Paste a Compose file to see a service inventory and the findings of a local structural linter. The YAML is parsed in your browser: nothing is uploaded, no Docker daemon is contacted and docker compose is never executed.
Runs locally in your browserPaste compose.yaml or docker-compose.yml. Parsing and checks run locally in the browser.
This is a local structural linter. It does not pull images, inspect your Docker daemon, resolve environment variables, or execute Compose.
| Service | Image / build | Ports | Depends on |
|---|---|---|---|
| No Compose file validated yet. | |||
Paste a compose.yaml or docker-compose.yml and press Validate compose file. The page parses the document in the browser and prints two things: a findings list grouped by severity, each row showing the path of the offending key such as services.db.ports[0], and a service inventory with the image or build source, the published ports and the depends_on targets of every service.
The built-in example (api and db, each with a named volume) comes back as ready for review, because nothing in it blocks a docker compose up. A host port reused by two services, a depends_on entry that points at a service that does not exist, or a dependency cycle such as a → b → a are reported as errors instead.
Structure: services must be a mapping with at least one service, each service must be an object, and names may only use letters, numbers, dots, underscores and hyphens — Compose rejects anything else. image must be a non-empty string and build a path or an object; a service with neither is flagged, because it cannot run.
Ports: container targets must be 1–65535, and a published host port may be a single number or a range such as 8000-8005. The linter flags out-of-range or non-numeric host ports, protocols other than tcp, udp or sctp, and every duplicate or overlapping host port — whether it appears twice in one service or in two different ones. network_mode: host with published ports adds a warning, because those mappings are ignored at runtime.
depends_on may be a list or a mapping; every target must exist and the graph must be acyclic, so a → b → a or a service depending on itself is reported with the full cycle. container_name and privileged: true are flagged as warnings because they limit scaling or widen host access beyond what most services need.
Named volumes that a service mounts must be declared in the top-level volumes mapping. Anchors and aliases are resolved by the local parser, and <<: *common is merged into the service when it points at a mapping, so an image that only arrives through the merge key still appears in the inventory; when the merge cannot be resolved, the row says so instead of silently reporting a missing image.
Nothing is executed: the page never runs docker compose, never contacts a Docker daemon and never pulls an image. Variables such as ${POSTGRES_PASSWORD} are not resolved, .env files are not read, and profiles or extends behaviour is only checked as structure. Compose version differences are not simulated, so confirm the final file against the Compose release you deploy with.
The document is parsed in your browser: the pasted text is not uploaded and validation keeps working offline. Very large files are limited by the memory of your own device, and a single document is read at a time — a file with a second --- document is rejected with its line number.