DevOps Tools

Docker Compose Validator

Check a docker-compose.yml or compose.yaml file before you run it: YAML syntax, unknown or misspelled keys, port syntax and host port conflicts, undeclared volumes, networks and secrets, depends_on targets and conditions, restart policies and plain-text secrets.

Private by design: anything you enter is processed in your browser only. It is never uploaded to or logged on our servers. Validation runs entirely in your browser, so passwords in your environment section never leave this page unless you create a share link, which stores the file in the link itself.

Validates as you type. Indent with spaces; YAML does not allow tabs.

Validation result
Paste a Compose file to start.

    Services

    Service Image / build Ports Volumes Depends on

    About this Docker Compose validator

    Docker Compose describes a multi-container application in a single YAML file. Compose v2 (the docker compose plugin) follows the open Compose Specification, which replaced the old numbered file formats. This validator parses your file with a YAML 1.2 parser, reports syntax errors with their line number, and then checks the structure against the specification, all without Docker installed.

    Beyond syntax it catches the mistakes that usually surface only when you run docker compose up: misspelled keys such as enviroment (with a "did you mean" suggestion), named volumes, networks or secrets that are used but never declared at the top level, depends_on entries that point to a service that does not exist or form a cycle, invalid restart policies, two services publishing the same host port, and duplicate container_name values. It also warns about unpinned :latest images and passwords written in plain text in environment.

    The services table gives you a quick overview of what the file starts: which image or build context each service uses, what it publishes, what it mounts and what it waits for. Values that use variable interpolation such as ${PORT:-8080} are resolved by Compose from your shell or .env file, so this tool skips checks it cannot evaluate rather than guessing.

    For a definitive answer, run docker compose config in the project folder; it resolves variables, merges override files and prints the final model or the first error. Lint the images your services build with the Dockerfile linter, move to Kubernetes with the Kubernetes YAML linter, or convert the file to JSON with the data format converter.

    Reference Guide

    Top-level keys in the Compose Specification:

    KeyPurpose
    servicesThe containers to run (required in practice)
    networks, volumesNamed networks and volumes that services can reference
    secrets, configsFiles or values mounted into services at /run/secrets/<name> or a target path
    nameProject name (otherwise the folder name)
    includeOther Compose files to load as part of this application
    versionObsolete. Compose v2 ignores it and prints a warning; remove it
    x-*Extension fields, often used with YAML anchors for shared settings

    Most-used service keys:

    KeyExample
    image / buildimage: nginx:1.27, build: ./api or build: { context: ., dockerfile: Dockerfile.prod }. One of them is required
    ports / expose- "8080:80" publishes on the host; expose only documents ports for other services
    environment / env_fileMap (KEY: value) or list (- KEY=value); env_file: .env.api
    volumes- db-data:/var/lib/postgresql/data (named), - ./src:/app/src:ro (bind)
    depends_onStart order, optionally waiting on a condition (see below)
    restart"no" (default), always, on-failure, on-failure:5, unless-stopped
    healthchecktest: ["CMD", "curl", "-f", "http://localhost/health"], interval, timeout, retries, start_period
    command / entrypointOverride the image's CMD / ENTRYPOINT
    networks, secrets, configsReferences to top-level definitions
    deploy, profiles, user, working_dir, labels, loggingResources and replicas, optional service groups, runtime user, cwd, metadata, log driver

    Port syntax:

    EntryMeaning
    "3000"Container port 3000 on a random host port
    "8080:80"Host 8080 → container 80, on all interfaces
    "127.0.0.1:8080:80"Only reachable from the host itself
    "127.0.0.1::80"Random host port on localhost
    "9090-9091:8080-8081"Port range (both sides must be the same length)
    "6060:6060/udp"UDP (or /sctp); TCP is the default
    - target: 80
      published: "8080"
      host_ip: 127.0.0.1
      protocol: tcp
    Long syntax; also supports mode: host | ingress, name and app_protocol

    Always quote short-syntax ports. Older YAML 1.1 parsers read unquoted values like 22:22 as a base-60 number.

    depends_on conditions (long syntax):

    ConditionWaits until
    service_startedThe dependency's container has started (same as the short list form)
    service_healthyThe dependency's healthcheck reports healthy. It needs a healthcheck in Compose or a HEALTHCHECK in its image
    service_completed_successfullyThe dependency ran to completion with exit code 0 (migrations, seeders)

    Each entry can also set restart: true (restart this service when the dependency is updated) and required: false (only warn if the dependency is missing).

    Check with Docker itself: docker compose config validates and prints the fully resolved file, docker compose config --quiet only reports errors (handy in CI), and docker compose -f compose.yaml -f compose.prod.yaml config shows the merged result of several files.

    Example input

    version: "3.8"
    
    services:
      web:
        build: .
        ports:
          - "8080:80"
        environment:
          DATABASE_URL: postgres://app:${DB_PASSWORD}@db:5432/app
        depends_on:
          db:
            condition: service_healthy
        volumes:
          - uploads:/app/uploads
    
      worker:
        image: myorg/worker:latest
        depends_on:
          - db
          - queue
        enviroment:
          - LOG_LEVEL=info
    
      db:
        image: postgres:16-alpine
        environment:
          POSTGRES_PASSWORD: supersecret
        ...

    This sample loads automatically when you open the tool. Use Load Sample to bring it back.

    Frequently Asked Questions

    No. The Compose Specification used by Docker Compose v2 ignores the top-level version key and warns that it is obsolete. You can safely remove it.

    Give the dependency a healthcheck and use the long depends_on syntax with condition: service_healthy. A plain depends_on list only waits for the container to start.

    It catches syntax errors and common mistakes instantly without Docker installed. Running docker compose config locally is still the final check, because it also resolves variables and extends.