Docker Compose Generator
Generate docker-compose.yml for Node, Postgres, MySQL, MongoDB, Redis, NGINX, MailHog, Adminer with healthchecks and Compose-spec. Free, offline, client-side.
- Runs in your browser
- Nothing uploaded
- Free, no sign-up
Generate a docker-compose.yml for common dev stacks with healthchecks, Compose-spec format (no obsolete version: field), and idiomatic defaults. Includes the anonymous-volume trick for node_modules, so the host folder never clobbers the container's native dependencies.
Custom host ports (leave blank for defaults: 3000/5432/3306/27017/6379/80/8025/8080)
How to Use Docker Compose Generator
- Tick the services you need. Defaults: Node 20, PostgreSQL 16, Redis 7. Eight services in total now (was 5) - added MongoDB, MailHog (dev mail catcher), and Adminer (web DB UI).
- Set a project prefix (used in DB names like
app_db). Or pick a preset - MEAN, LAMP-ish, JAMstack, WP-like, full stack, or minimal Node-only. - Choose toggles: Healthchecks (recommended on - wires
depends_on: condition: service_healthy), container names (off - keeping off lets you run multiple stacks on the same host), legacyversion:field (off - Compose v2 omits this). - Customize ports if defaults collide on your host. Port collision detection runs on every change and shows a warning.
- Press Ctrl+Enter or click Generate. Live debounced re-render (200 ms) on any change too.
- Copy or download the YAML. The file uses 2-space indentation, no obsolete
version:field, and has the anonymous-volume trick fornode_modules(prevents host'snode_modulesfrom clobbering the container's - a real recurring bug). - Save the file in your project root as
docker-compose.yml, change the demo passwords, and rundocker compose up(ordocker-compose upfor older Compose).
Frequently Asked Questions
Why no version: field by default?
Docker Compose v2 (the current standard, written in Go) treats the top-level version: field as obsolete. It’s silently ignored AND emits a warning on every docker compose up. The Compose Specification (which both Compose v2 and Docker Swarm use) removed it. We omit it by default. Toggle it on only if you’re stuck on Compose v1 (Python-based, end-of-lifed June 2023).
What’s the anonymous-volume trick for node_modules?
When you mount your project as - .:/usr/src/app (so code changes hot-reload), Docker overlays your host’s directory ON TOP OF the container’s image content. If your host has a node_modules folder (because you ran npm install locally too), it overwrites the one built INSIDE the container during image build. Problem: those host modules were compiled for your host’s OS/arch. Native modules like bcrypt or sharp will SIGSEGV or fail to load. Fix: add a second volume entry - /usr/src/app/node_modules AFTER the bind mount. This is an anonymous volume Docker maintains separately, which takes precedence over the bind mount for that subpath – preserving the container’s compiled modules.
Why are the passwords “CHANGE_ME_demo_only”?
To make it VERY hard to accidentally deploy. The original used rootpassword which, while obviously a placeholder, is short and forgettable – easy to leave in. The string CHANGE_ME_demo_only will fail loudly any time you actually try to authenticate with it. For production: use env_file: directive pointing to a .env file (gitignored) with real secrets, or Docker secrets / Swarm secrets / Kubernetes secrets / Doppler / Vault, depending on your platform.
Why is container_name: off by default?
When you set container_name: app_postgres, Docker enforces global uniqueness – you can only have ONE container with that exact name across the whole Docker daemon. Try to start a second stack (say, two branches of the same project side-by-side) and you get Conflict. The container name "app_postgres" is already in use. Without container_name:, Docker generates unique names per project automatically (myproject-postgres-1, otherproject-postgres-1). Toggle it on only if you have scripts that reference a specific container name.
What’s depends_on: condition: service_healthy?
The short form depends_on: - postgres only waits for the Postgres CONTAINER to START – not for Postgres itself to be ready to accept connections. So your Node app may try to connect to Postgres while Postgres is still initializing its data directory, get a connection refused, and crash. The long form depends_on: postgres: condition: service_healthy waits for the healthcheck to pass before starting Node. This is THE most common docker-compose bug fix in production.
What does MailHog do?
MailHog is a dev mail catcher. It runs a fake SMTP server on port 1025 – point your app’s mail config there and ALL outgoing emails get captured instead of sent. You view them in a web UI on port 8025. Critical for testing password resets, welcome emails, etc. without spamming real inboxes or needing a real SMTP service. Modern alternative is MailDev with similar capabilities. We use MailHog (the most popular).
What’s Adminer?
Adminer is a single-PHP-file DB admin UI – like phpMyAdmin but multi-DB (MySQL, Postgres, SQLite, MS SQL, Oracle, SimpleDB, MongoDB, Elasticsearch). Lighter and faster than phpMyAdmin. Useful for poking at dev databases. Never expose Adminer publicly in production – it has had auth bypass CVEs.
Can I run multiple stacks side-by-side?
Yes, IF you (a) leave container_name: off (default) AND (b) override host ports for collision. Docker Compose isolates each project’s network, volumes, and container names by project name (the directory name, or -p flag). So two checkouts in ~/projA and ~/projB can both run a full stack as long as the host ports don’t collide. Use the custom-ports panel to remap them – e.g. 5433 for projB’s Postgres.
Is this production-ready?
No. This is a dev/learning starter. Production needs: secrets via env files or secret manager (NOT in the YAML), resource limits (deploy: resources: limits:), restart policies tuned to your reliability needs, logging configuration (json-file rotation or external log driver), reverse proxy with TLS (NGINX/Caddy/Traefik), backups for DB volumes, monitoring (Prometheus/Loki/Grafana or a hosted service), and review of every default. Use this output as a starting point, not a destination.
Related Tools
Android AssetLinks JSON Generator - App Links →
Android AssetLinks JSON Generator files for Android App Links. Configure package names and SHA-256…
Convert ASCII to Binary →
Convert ASCII to Binary tool. Convert text to binary and binary to text. 100%…
Base32 Encoder/Decoder →
Free Base32 encoder and decoder tool. Encode or decode Base32 strings online. 100% client-side,…
Base58 Encoder/Decoder →
Free Base58 encoder and decoder tool. Encode or decode Base58 strings like Bitcoin addresses.…
Base64 Encoder and Decoder →
Base64 Encoder and Decoder - Convert text strings into Base64 format or decode Base64…
BBCode to HTML Converter →
Generate standard semantic HTML arrays translating classic forum BBCode syntax cleanly explicitly mappings independently…
Convert Binary to Hex →
Convert Binary to Hex tool. Convert binary numbers to hex instantly. 100% client-side, instant,…
Convert BSON to JSON →
Convert MongoDB BSON hex dumps to readable JSON in your browser. Free, offline, client-side…
Chmod Calculator →
Chmod Calculator - Build Linux chmod permissions visually - read/write/execute for owner, group, public,…
Coin Flip →
Free Coin Flip Online streaks, batch 10 000 flips, and optional crypto-grade RNG. Full…
Convert Base64 String Encoder and Decoder →
Encode text to Base64 or decode Base64 back to readable text, with full UTF-8…
Countdown Timer →
Countdown timer with presets, pause, audio alert, shareable URL. Free, client-side, instant, secure.