🐳 Docker Compose Visualizer

Turn any docker-compose.yml into an interactive architecture diagram — with a dependency graph, startup order and a security & best-practice audit. Runs entirely in your browser.

Waiting for a compose file…
docker-compose.yml
Samples
🐳

No compose file yet

Paste a docker-compose.yml, drop a file, or load one of the samples to see the architecture.

About the Docker Compose Visualizer

A docker-compose.yml file describes an entire system — services, images, ports, volumes, networks and the order things must boot in — but it describes it as a flat list. Once a stack grows past three or four services, understanding how they actually fit together means scrolling up and down and holding the graph in your head. This tool renders that graph for you: paste the file and get an interactive architecture diagram, the real startup order, and a list of the mistakes that most often bite in production.

Everything runs client-side in JavaScript. Your compose file — which frequently contains database credentials, internal hostnames and API keys — is never uploaded, stored or logged.

What the analyzer checks

🔓 Exposed databases

Flags Postgres, MySQL, MongoDB, Redis and friends publishing ports to all interfaces instead of staying on the internal network.

🔑 Hardcoded credentials

Finds passwords, tokens and API keys written as literals — and calls out well-known weak values like postgres or admin.

🔁 Circular dependencies

Detects depends_on cycles that stop Compose resolving a startup order at all.

🩺 Missing healthchecks

Warns when a service others wait on has no healthcheck — the usual cause of "connection refused" on boot.

⚓ Port conflicts

Catches two services publishing the same host port, where only the first to start will bind.

💾 Ephemeral data

Highlights databases with no volume mounted, whose data disappears on docker compose down.

Frequently Asked Questions

Is my docker-compose.yml uploaded anywhere?

No. Parsing, analysis and diagram rendering all happen in your browser using JavaScript. The file is never sent to a server, stored or logged — you can confirm this by watching the network tab while you paste.

Which Docker Compose versions are supported?

The Compose Specification (v2/v3 style files with a top-level services key) as well as legacy v1 files that declare services at the top level. Both short and long syntax for ports, volumes and depends_on are handled, along with YAML anchors and aliases.

How are ${VARIABLE} placeholders handled?

Variables are resolved using their inline default when one is given, for example ${POSTGRES_PORT:-5432}. Without a default the placeholder is left visible so you can see exactly which values come from your .env file. Every variable found is listed in the summary.

What does the startup order show?

It is a topological sort of your depends_on graph, grouped into waves. Services in the same wave have no dependency between them and start in parallel. If a cycle exists, the tool reports it as an error because Compose cannot resolve an order.

Why does it warn about depends_on without a healthcheck?

depends_on only waits for a container to start, not for the process inside to be ready to accept connections. That is the single most common cause of 'connection refused' errors on boot. Adding a healthcheck and using condition: service_healthy makes the wait meaningful.

Can I share a diagram with my team?

Yes. Click Share link and the compose file is encoded into the URL itself — nothing is stored on a server. Anyone who opens the link sees the same diagram. You can also export the diagram as SVG or PNG.

Complete guide to reading and auditing a docker-compose file

A docker-compose.yml file describes an entire system — every service, the image it runs, the ports it publishes, the volumes it mounts, the networks it joins, and the order in which things must come up. But it describes all of that as a flat list of keys. Once a stack grows past three or four services, understanding how they actually fit together means scrolling up and down and holding the dependency graph in your head.

This visualizer parses the file and draws that graph for you. Each service becomes a node showing its image and published ports, and each depends_on relationship becomes an arrow. Services that share no dependency sit side by side, so the shape of the architecture — which components are entry points, which are shared infrastructure, which are isolated — becomes obvious at a glance.

Alongside the diagram, the tool runs a static audit of the file. It looks for the mistakes that are easy to make and expensive to discover in production: a database published to every network interface, a password committed as a literal, two services fighting over the same host port, or a dependency chain that can never resolve. Each finding explains what is wrong, why it matters, and the specific change that fixes it.

Everything runs in your browser. Compose files routinely contain database credentials, internal hostnames, and API keys, so nothing is uploaded, stored, or logged — you can confirm that by watching the network panel while you paste.

How it works

The file is parsed with js-yaml, which resolves anchors and aliases before any analysis happens. YAML merge keys (the <<: *anchor syntax used by x-common templates) are then applied manually, because js-yaml follows the YAML 1.2 core schema and does not merge them itself. Without that step, every field inherited from a shared template would be silently dropped and the audit would report problems that are not real.

Variable placeholders are resolved next. ${POSTGRES_VERSION:-16} becomes 16 using its inline default, while a variable with no default is left visible so you can see exactly which values come from your .env file rather than the compose file itself. Every variable encountered is collected and reported.

Both the short and long forms of ports, volumes, and depends_on are normalised into a single internal shape, so "8080:80", "127.0.0.1:8080:80/tcp", and the long { target, published } object all produce the same result. The graph is then laid out in layers: a service sits one layer to the right of its deepest dependency, and nodes within a layer are ordered to minimise crossing arrows.

Startup order is computed as a topological sort of the depends_on graph, grouped into waves. Services in the same wave have no dependency between them and start in parallel. If a cycle exists, no valid order can be produced, and the tool reports the cycle explicitly rather than showing a misleading partial order.

Common uses

  • Understand an unfamiliar stack quickly when joining a project or reviewing a pull request that changes infrastructure.
  • Explain a system's architecture in a design document, onboarding guide, or incident review by exporting the diagram as SVG or PNG.
  • Audit a compose file for exposed databases and hardcoded credentials before it is committed or shared.
  • Diagnose why containers start in the wrong order by reading the computed startup waves instead of guessing from the file.
  • Find the cause of a port binding failure when two services publish the same host port.
  • Check that every stateful service has a volume mounted, so data is not lost the next time the stack is torn down.
  • Confirm that a refactor did not leave behind orphaned networks, unused volumes, or a depends_on pointing at a service that no longer exists.

Before you rely on the result

  • depends_on only waits for a container to start, not for the process inside it to be ready. This is the single most common cause of connection refused errors on boot. Add a healthcheck and use depends_on with condition: service_healthy when a service genuinely needs to wait.
  • Publishing a database port with "5432:5432" binds it to every interface on the host. On a public server that exposes the database to the internet. Other services in the same compose project can reach it over the internal network without any ports mapping at all.
  • A password written directly into the environment section ends up in version control. Use a variable and supply the value from an .env file that is listed in .gitignore, or use Docker secrets.
  • An image with no tag, or one pinned to :latest, means the same compose file can produce different containers on different days. Pin an explicit version so builds are reproducible.
  • Without a volume, a database stores its data inside the container layer and loses everything on docker compose down. Mount a named volume at the data directory for the engine you are running.
  • Without resource limits, a single runaway container can consume all host CPU and memory and take every other service down with it. Set deploy.resources.limits on anything that processes untrusted or variable workloads.
  • The root user check is a hint rather than a finding. Whether a container actually runs as root depends on the USER instruction in the image's Dockerfile, which a compose file cannot tell you. Treat it as a prompt to verify, not a confirmed problem.