All Snippets

Docker Compose Stack — Postgres + Redis + App

Production-ready Docker Compose template with PostgreSQL, Redis, health checks, persistent volumes, and environment management.

A common stack for web apps: your application, a PostgreSQL database, and Redis for caching/sessions. This template includes health checks, persistent volumes, restart policies, and environment variable management.

The Full Compose File

docker-compose.ymlyaml
1
services:
2
  app:
3
    build: .
4
    ports:
5
      - "3000:3000"
6
    environment:
7
      - DATABASE_URL=postgres://appuser:${DB_PASSWORD}@db:5432/myapp
8
      - REDIS_URL=redis://cache:6379
9
      - NODE_ENV=production
10
    depends_on:
11
      db:
12
        condition: service_healthy
13
      cache:
14
        condition: service_healthy
15
    restart: unless-stopped
16
 
17
  db:
18
    image: postgres:17-alpine
19
    volumes:
20
      - pgdata:/var/lib/postgresql/data
21
    environment:
22
      POSTGRES_DB: myapp
23
      POSTGRES_USER: appuser
24
      POSTGRES_PASSWORD: ${DB_PASSWORD}
25
    ports:
26
      - "5432:5432"
27
    healthcheck:
28
      test: ["CMD-SHELL", "pg_isready -U appuser -d myapp"]
29
      interval: 5s
30
      timeout: 5s
31
      retries: 5
32
    restart: unless-stopped
33
 
34
  cache:
35
    image: redis:7-alpine
36
    volumes:
37
      - redisdata:/data
38
    command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
39
    ports:
40
      - "6379:6379"
41
    healthcheck:
42
      test: ["CMD", "redis-cli", "ping"]
43
      interval: 5s
44
      timeout: 3s
45
      retries: 5
46
    restart: unless-stopped
47
 
48
volumes:
49
  pgdata:
50
  redisdata:

Environment File

Store secrets in a .env file next to your docker-compose.yml:

.envbash
1
DB_PASSWORD=change-me-to-something-strong

Never commit `.env` files to version control. Add .env to your .gitignore immediately. Use .env.example with placeholder values for documentation.

Key Patterns Used

Health Checks

ServiceHealth CheckWhy It Matters
PostgreSQLpg_isreadyApp won't start until the DB is accepting connections
Redisredis-cli pingEnsures Redis is responsive, not just running
App(add your own)Compose waits for dependencies via depends_on: condition

Volume Persistence

  • pgdata — PostgreSQL data survives container restarts and rebuilds
  • redisdata — Redis AOF persistence so cached data survives restarts

Restart Policies

PolicyBehavior
noNever restart (default)
alwaysAlways restart, even if manually stopped
unless-stoppedRestart unless you explicitly docker compose stopbest for most cases
on-failureOnly restart if the container exits with a non-zero code

Common Commands

Day-to-day operationsbash
1
# Start everything (detached)
2
docker compose up -d
3
 
4
# Rebuild after code changes
5
docker compose up -d --build
6
 
7
# View logs (follow mode)
8
docker compose logs -f app
9
 
10
# Stop everything (keeps volumes)
11
docker compose down
12
 
13
# Stop and DELETE all data (nuclear option)
14
docker compose down -v

docker compose down -v deletes your named volumes — that means all your database data is gone. Only use this for a full reset.

Accessing the Database

Connect to Postgres from your hostbash
1
# Via psql (if installed locally)
2
psql -h localhost -U appuser -d myapp
3
 
4
# Via docker exec (no local psql needed)
5
docker compose exec db psql -U appuser -d myapp

For database GUIs, connect to localhost:5432 with the credentials from your .env. Works with pgAdmin, DBeaver, TablePlus, and DataGrip.

If you're converting between docker run commands and Compose files, try the Docker Run to Compose converter on this site.