Port already published by another service
Two services map to the same `host:container` port — only one will bind, the rest fail at runtime.
Fix: Move one of the services to a different host port (e.g. `8081:3000`) or stop publishing it externally.
Search tools and pages.
Validate docker-compose.yml against the Compose Spec schema with hand-written lints (port collisions, undefined networks, depends_on cycles)
sidebar • 160x600
Written by Giorgos Kostas. Last reviewed:
Docker Compose Validator parses your `docker-compose.yml` (or `compose.yaml`) with `js-yaml`, validates it against a focused Compose Spec JSON Schema using AJV, and then runs a second pass of hand-written lints that the schema can't express.
Each finding is tagged with severity (error / warning / hint), the YAML scope it points at (e.g. `services.api.ports`), and — when relevant — a one-line fix.
services:
api:
image: ghcr.io/devfox/api:1.4.0
ports: ["8080:3000"]
depends_on: [db, cache]
worker:
ports: ["8080:9000"]
depends_on: [db]
db:
image: postgres:16-alpine
volumes: [dbdata:/var/lib/postgresql/data]error services.worker Service has neither image nor build. error services.worker.ports Host port 8080/tcp is already published by service 'api'. warn services.api.volumes Named volume 'dbdata' is referenced but not declared at the top level. warn services.cache depends_on references 'cache' which is not defined in services.
Two services map to the same `host:container` port — only one will bind, the rest fail at runtime.
Fix: Move one of the services to a different host port (e.g. `8081:3000`) or stop publishing it externally.
Compose can't run a service without one of the two — usually happens after extracting a service into its own file.
Fix: Add `image: registry/name:tag` or `build: ./path/to/context`.
Compose creates a default driver network with that name silently; declaring it explicitly avoids surprises with `external:` networks.
Fix: Add the network under the top-level `networks:` block (e.g. `networks: { backend: { driver: bridge } }`).
Two or more services depend on each other — startup deadlocks.
Fix: Break the cycle: pick one service to start independently and use a healthcheck instead of `depends_on` for ordering.
Compose treats them as mutually exclusive on the same service.
Fix: Pick one. `network_mode: host` for a single-host shortcut, or `networks:` for the standard model.
No — everything happens in your browser. We bundle a focused subset of the Compose Spec JSON Schema and validate with AJV, then run hand-written lints for the high-value checks. No file leaves your machine.
The schema mirrors the modern Compose Spec (the same one Docker Compose v2 reads), so the legacy top-level `version:` key is allowed but optional. Service-level keys cover the most-used 95% of the spec.
No — environment-dependent issues (like an unreachable image registry, missing volume permissions, or a port being held by another process) can only be detected at runtime. The validator covers structural and reference issues.
A layered view of your `depends_on` chain: services with no dependencies on the left, the things that depend on them on the right. Cycles are flagged in their own layer with an error finding.
Right now it validates one file at a time. To check a `docker-compose.yml` + `docker-compose.override.yml` combo, run `docker compose config` locally and paste the merged output here.
The validator currently treats all services as active — it doesn't simulate `--profile` selection. If two services share a host port but never run together, treat the warning as informational.
Compose-adjacent tools you'll use in the same workflow. You can also browse the full DevOps & Infra category for more options.
Edit .env files in a key/value table with type detection, masked secrets, duplicate-key warnings, and export to JSON, YAML, shell, or docker-compose
Explore multi-document Kubernetes manifests grouped by kind with a cross-reference graph (Service to Deployment, ConfigMap mounts, Ingress backends)
Validate YAML syntax online and catch indentation and structure errors instantly. Paste YAML config files and get detailed error messages with line numbers.
Format and beautify YAML content online with proper indentation and flow styles. Paste YAML and get clean, readable output instantly.
Format, validate, and beautify JSON online with readable indentation, syntax checking, and copy-ready output for APIs, logs, and config files.
Generate a production-ready nginx.conf for reverse proxying with proxy_pass, headers, timeouts, and gzip from a focused form
Generate an nginx upstream + load balancer config with round-robin, least_conn, ip_hash, weights, health checks, and keepalive
Generate an HTTPS-ready nginx.conf with SSL certificate paths, modern protocols, ciphers, HSTS, and HTTP-to-HTTPS redirect
Generate an nginx.conf for serving a static site with try_files, SPA fallback, gzip, brotli, and aggressive cache headers
Generate an nginx config for proxying WebSocket connections with Upgrade and Connection headers and long read timeouts
content bottom • up to 300x250