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.
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:
| Key | Purpose |
|---|---|
services | The containers to run (required in practice) |
networks, volumes | Named networks and volumes that services can reference |
secrets, configs | Files or values mounted into services at /run/secrets/<name> or a target path |
name | Project name (otherwise the folder name) |
include | Other Compose files to load as part of this application |
version | Obsolete. 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:
| Key | Example |
|---|---|
image / build | image: 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_file | Map (KEY: value) or list (- KEY=value); env_file: .env.api |
volumes | - db-data:/var/lib/postgresql/data (named), - ./src:/app/src:ro (bind) |
depends_on | Start order, optionally waiting on a condition (see below) |
restart | "no" (default), always, on-failure, on-failure:5, unless-stopped |
healthcheck | test: ["CMD", "curl", "-f", "http://localhost/health"], interval, timeout, retries, start_period |
command / entrypoint | Override the image's CMD / ENTRYPOINT |
networks, secrets, configs | References to top-level definitions |
deploy, profiles, user, working_dir, labels, logging | Resources and replicas, optional service groups, runtime user, cwd, metadata, log driver |
Port syntax:
| Entry | Meaning |
|---|---|
"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):
| Condition | Waits until |
|---|---|
service_started | The dependency's container has started (same as the short list form) |
service_healthy | The dependency's healthcheck reports healthy. It needs a healthcheck in Compose or a HEALTHCHECK in its image |
service_completed_successfully | The 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.
Related Tools
All DevOps Tools →Kubernetes YAML Linter
Lint Kubernetes manifests for errors and best practices: mis...
Helm Values Tool
Compare and merge Helm values.yaml files the way Helm does,...
Log Analyzer
Parse Nginx/Apache access logs, JSON logs and plain applicat...
PDF Form Filler
Upload and fill interactive PDF form fields directly in your...
Color Converter
Convert colors between HEX, RGB, HSL, HSV, and CMYK formats...
Number Base Converter
Convert numbers between binary, octal, decimal, hexadecimal...