Docker Compose Generator
Pick your services and get a production-ready docker-compose.yml with healthchecks.
● Runs 100% in your browser — nothing you type leaves this page.
# Generated by OhSudo — https://ohsudo.com/tools/docker-compose-generator/# Passwords come from the .env file next to this one. Keep it out of git.name: "myapp"services:app:# Built from the Dockerfile in this folderbuild: .restart: "unless-stopped"environment:DATABASE_URL: "postgres://app:${POSTGRES_PASSWORD}@postgres:5432/app"REDIS_URL: "redis://redis:6379"# "host:container" — reachable from your machineports:- "3000:3000"# Start after these services (and wait until they are healthy)depends_on:postgres:condition: service_healthyredis:condition: service_healthynetworks:- backendpostgres:image: postgres:18-alpinerestart: "unless-stopped"environment:POSTGRES_USER: "app"POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"POSTGRES_DB: "app"# Not published: other services reach it at postgres:5432# Named volume: the data survives when the container is re-createdvolumes:- "postgres-data:/var/lib/postgresql"# Lets other services wait until this one is readyhealthcheck:test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]interval: 10stimeout: 5sretries: 5start_period: 30snetworks:- backendredis:image: redis:8-alpinerestart: "unless-stopped"command: ["redis-server", "--appendonly", "yes"]# Not published: other services reach it at redis:6379# Named volume: the data survives when the container is re-createdvolumes:- "redis-data:/data"# Lets other services wait until this one is readyhealthcheck:test: ["CMD", "redis-cli", "ping"]interval: 10stimeout: 5sretries: 5start_period: 30snetworks:- backendvolumes:postgres-data:redis-data:# Services on this network reach each other by service namenetworks:backend:
🔒 Passwords are generated in your browser and never put in the URL. Keep .env out of git.
Run it
$ docker compose up -dThe address bar updates as you go, so you can bookmark or share the result.
How to use it
- Name your project and pick the services you need — your own app, a database, a cache, a reverse proxy.
- Fine-tune each one: version, published ports, a persistent volume, a healthcheck.
- Copy or download
docker-compose.yml(and.env), put them in your project folder and rundocker compose up -d.
The generator connects the services for you: your app gets DATABASE_URL, REDIS_URL and friends, WordPress is pointed at MySQL or MariaDB, and every service waits for its dependencies to be healthy, not just started.
What you get
- Healthchecks for the databases and caches, so
depends_onwithcondition: service_healthyactually waits until PostgreSQL accepts connections. - Named volumes for anything that stores data, so a
docker compose downdoesn’t wipe your database. - A dedicated network: services reach each other by name (
postgres:5432), and databases aren’t published on your host unless you ask for it. - A
.envfile for passwords. They are generated in your browser, are never part of the shareable link, and you should keep.envout of git.
Shell, we have a problem!
Publishing a database port (5432:5432) on a server with a public IP makes it reachable from the internet — Docker’s port publishing goes around many host firewalls like UFW. Keep databases internal, or use “Publish ports on 127.0.0.1 only”.
Common commands
docker compose up -d # start everything in the backgrounddocker compose ps # status and health of each servicedocker compose logs -f app # follow the logs of one servicedocker compose pull # fetch newer imagesdocker compose down # stop and remove containers (volumes stay)docker compose down -v # ...and delete the volumes tooFAQ
Why is there no version: at the top?
The version key is obsolete. Docker Compose v2 ignores it and warns about it, so modern files leave it out.
What’s the difference between depends_on and a healthcheck?
depends_on alone only waits for the container to start. With a healthcheck and condition: service_healthy, Compose waits until the service reports it is ready — the difference between your app crashing on boot and connecting on the first try.
Can I use this in production?
It’s a solid starting point: pinned major versions, healthchecks, volumes and secrets out of the file. For production, also pin exact image versions, put a reverse proxy with TLS in front, back up your volumes, and don’t publish database ports.
Articles
Learn more
Docker "exited with code 137": OOM kill or a stop that took too long
Exit code 137 means the container was killed with SIGKILL. Find out if it ran out of memory or ignored docker stop, and fix each case.
Intermediate · 5 min read
Nginx "502 Bad Gateway": find the cause in the error log
Fix nginx 502 Bad Gateway: read error.log, then fix the backend that is down, the wrong address or socket, the crashing app, or SELinux on RHEL.
Intermediate · 5 min read