Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Kubernetes YAML Generator

Fill in a form or paste a Compose file, and get manifests the API server accepts.

Developer No upload Works offline Free preview, no sign-upIncluded in your pass Pro tool Pro pass: ₹179 for 30 days

Free preview.

  • Free preview: the first lines of the YAML (up to 20) with every check result, and for pasted manifests every count with the first problems (up to 10).
  • Locked until you unlock it: download and copy.
  • Unlock: Pro pass, ₹179 for 30 days, a one-time payment that never renews.

Ways to unlock shows how to get the full result.

See passes (opens in a new tab)

Printing this result is locked in the free preview.

App

Names the workload, its Service and its container.

Runs as
Container

8080, http 8080 or dns 53/UDP. The first one gets the Service’s traffic.

Health checks
Schedule

Job
Storage
Configuration and secrets

Either way the values are only encoded, not encrypted: keep real ones out of git.

Network
Autoscaling

Next steps

About the Kubernetes YAML Generator

Describe your app once — image, ports, environment, CPU and memory, health checks — and get the Kubernetes objects around it: a Deployment, Job or CronJob, a Service, an Ingress with TLS, a ConfigMap and a Secret, a PersistentVolumeClaim, a HorizontalPodAutoscaler and the Namespace. Or paste a docker-compose.yml and get a Deployment and a Service for each service, claims for its named volumes, and a note for every setting Kubernetes has no equivalent for (depends_on, bind mounts, env_file, networks…).

Every result is checked the way the API server would check it: against JSON Schemas built from the Kubernetes 1.37 OpenAPI document (so a typo such as protocl or replicas: "3" is caught), and against Kubernetes’ own rules — names and labels, selectors that match their pods, ports, quantities such as 512m written for 512Mi, probes, CronJob schedules and time zones, removed API versions. Paste existing manifests to check them line by line. Nothing is uploaded: the schemas are part of the page.

How to use it

  1. Choose Form, From Compose or Check YAML. Load example fills in a realistic one.
  2. In the form, give the app a name and an image, list its ports (http 8080) and environment (KEY=value), set CPU and memory, and tick the objects you need. A schedule is checked as you type, with its next runs in the time zone you pick.
  3. Read the problems next to the YAML: each one names the field to change. Notes (blue) are advice; errors (red) are what the API server would refuse.
  4. With a pass, or once this YAML is unlocked, Copy it or Download manifests.yaml; the free preview shows its first lines and locks both. Then run kubectl apply --dry-run=server -f manifests.yaml to let your cluster check it, and kubectl apply -f manifests.yaml to create it.

Examples

The default form: a web server with a readiness probe
Input
Name: web · Deployment · 2 replicas · image nginx:1.27 · port http 80 · requests 100m CPU, 128Mi · memory limit 256Mi · Service on port 80
Result
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  labels:
    app.kubernetes.io/name: web
spec:
  replicas: 2
  selector:
    matchLabels:
      app.kubernetes.io/name: web
  template:
    …
      containers:
      - name: web
        image: nginx:1.27
        ports:
        - name: http
          containerPort: 80
        readinessProbe:
          httpGet:
            path: /
            port: http
---
apiVersion: v1
kind: Service
…
  ports:
  - name: http
    port: 80
    targetPort: http

The Service selects the pods by app.kubernetes.io/name and sends traffic to the port by name, so changing the container port later needs no change to the Service.

A Compose service with a healthcheck
Input
web:
  image: ghcr.io/acme/shop-web:2.4.1
  ports: ["8080:3000"]
  deploy:
    resources:
      limits: { cpus: "0.5", memory: 512M }
  healthcheck:
    test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
    interval: 15s
Result
containers:
- name: web
  image: ghcr.io/acme/shop-web:2.4.1
  ports:
  - containerPort: 3000
  resources:
    limits:
      cpu: 500m
      memory: 512Mi
  readinessProbe:
    exec:
      command: [wget, -qO-, http://localhost:3000/health]
    periodSeconds: 15
…
kind: Service
  ports:
  - port: 8080
    targetPort: 3000

Compose’s 512M means 512 × 1,024 × 1,024 bytes, so it becomes 512Mi. The healthcheck becomes a readiness probe, because Docker does not restart an unhealthy container either.

Checking a manifest
Input
In the container “web” of a Deployment:
resources:
  requests:
    memory: 512m
    cpu: "2"
  limits:
    cpu: "1"
env:
- name: DEBUG
  value: no
Result
Error: Container “web”: the cpu request (2) is above its limit (1); a request must be less than or equal to the limit.
Error: Expected a string, got boolean false.
Warning: Container “web”: memory request “512m” means 512 thousandths of a byte (“m” is milli). Did you mean 512Mi?
Warning: "no" is the boolean false in YAML 1.1 (used here), but the string "no" in YAML 1.2. Quote it ("no") if you mean the text.

Each problem comes with its line and column; Show selects it in your text.

What the check covers

  • Structure against the bundled schemas (Kubernetes 1.37): unknown fields with a “did you mean”, wrong types, missing required fields, and API versions Kubernetes no longer serves (extensions/v1beta1, batch/v1beta1 CronJob, autoscaling/v2beta2 and others from the deprecation guide).
  • Names and labels as in Kubernetes’ own code: RFC 1123 names, Service names, label keys and values, port names of up to 15 characters, environment variable names (object names, labels).
  • Values: quantities and requests above limits, probes, ports and NodePorts, Ingress paths and path types, Secret data that is not base64, the 1 MiB limit of ConfigMaps and Secrets.
  • CronJobs with the same parser Kubernetes uses: five fields, Sunday is 0 (not 7), no seconds, no TZ= in the schedule, names of at most 52 characters (CronJob).
  • Links between objects in one file: a Service whose selector matches no pod template, a targetPort no container has, an Ingress pointing to a port the Service lacks, an autoscaler whose pods set no CPU request.

How Compose settings are converted

  • image, command → args, entrypoint → command, environment, working_dir, user (numeric IDs), cap_add / cap_drop, read_only, privileged, extra_hosts, stop_grace_period, platform (node selector) and deploy.replicas carry over.
  • ports and expose → container ports and a Service (published ports keep their published number as the Service port). A service with neither still gets a Service when another one connects to it by name:port, as in DATABASE_URL: postgres://app@db:5432/shop: in Compose that works without ports, in Kubernetes only through a Service.
  • deploy.resources and mem_limit / cpus → limits and requests.
  • Named volumes → PersistentVolumeClaims; tmpfs → an in-memory emptyDir; bind mounts → an empty folder, with the command to put the files in a ConfigMap instead.
  • secrets and configs → Secret and ConfigMap volumes mounted where Compose mounts them, with the kubectl create command for each; env_file → an envFrom ConfigMap with its command.
  • ${VAR:-default} takes its default; other variables are listed, because Kubernetes does not fill them in. depends_on, networks, links, logging, ulimits and the like are listed with what to do instead.

Before you apply

  • kubectl apply --dry-run=server -f manifests.yaml asks your own cluster, with its version, admission policies (Pod Security, quotas) and custom resources, to check everything without changing anything; kubectl diff -f manifests.yaml shows what would change.
  • Secrets in YAML are only base64-encoded. Create real ones with kubectl create secret generic …, or use Sealed Secrets or External Secrets, and keep the values out of git.
  • Pin image versions (nginx:1.27, or a digest) so every node runs the same image and rollbacks work.

Limitations

  • The form writes one container per pod and Deployments, Jobs and CronJobs; for StatefulSets, DaemonSets, sidecars or init containers, edit the YAML and check it under Check YAML.
  • Custom resources (cert-manager, Argo, Istio…) are read but not checked against a schema; they appear as unknown kinds.
  • The schemas are those of Kubernetes 1.37: a field added recently may not exist on an older cluster. Cluster-side checks — admission policies, quotas, existing objects — need kubectl apply --dry-run=server.
  • Compose features with no Kubernetes equivalent are listed, not converted, and env_file, secrets and configs files cannot be read here: run the kubectl create commands shown.

Privacy

Everything happens in your browser. What you enter or open here is not uploaded or stored by MySmartCoPilot.

Frequently asked questions

What do I get without a pass?

Without a pass, Kubernetes YAML Generator shows the first lines of the YAML (up to 20) with every check result, and for pasted manifests every count with the first problems (up to 10). Until you unlock it, the result can’t be downloaded or copied. A Pro, Premium or Ultimate pass, a one-time payment that never renews, unlocks the full result. The pricing page lists the passes and their prices.

Is this like kompose?

For Compose files, yes: services become Deployments and Services and named volumes become PersistentVolumeClaims. The difference is that every unconverted setting is explained with what to use instead, values are translated (Compose 512M → 512Mi, 0.5 CPUs → 500m), and the result is checked against the Kubernetes schemas and rules before you see it — all in the browser.

Why is "no" (or "8080") quoted in the YAML?

Kubernetes reads YAML 1.1, where unquoted yes, no, on and off are booleans and 8080 is a number. Environment variable values, labels and annotations must be strings, so the generator quotes such values; the checker flags unquoted ones in pasted YAML.

What is the difference between requests and limits?

Requests are what the scheduler reserves on a node for the container; limits are the most it may use. A container above its memory limit is stopped, and above its CPU limit it is slowed down. A request may not be larger than its limit. CPU is counted in cores (0.5 or 500m), memory in bytes with suffixes (128Mi, 1Gi).

Which time zone does a CronJob use?

Without spec.timeZone, the local time zone of the kube-controller-manager, which is often UTC. Set an IANA name such as Europe/Berlin or Asia/Kolkata to run in local time; TZ= inside the schedule is not accepted.

Is my Compose file or YAML sent anywhere?

No. The page converts and checks everything in your browser with the schemas built into it; nothing is uploaded and no cluster is contacted.

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.