Skip to content
From the studio / Free tool

A better starting point for your next deployment.

Good websites need a solid foundation. ComposeKit helps you put yours together: choose your stack, then generate a Docker Compose file with health checks, restart policies and sensible defaults. Free, with no signup.

Your app
Add-ons

docker-compose.yml

# Generated by ComposeKit · solyxlabs.com
# Start:  cp .env.example .env  (set strong passwords: openssl rand -base64 24)
#         docker compose up -d
name: app

services:
  app:
    build: .            # or: image: ghcr.io/you/yourapp:main
    restart: unless-stopped
    # no ports: Caddy is the public door and reaches app:3000 internally
    environment:
      DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
    depends_on:
      postgres:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:3000/api/health"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 20s
    deploy:
      resources:
        limits:
          memory: 768M

  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 5
    deploy: { resources: { limits: { memory: 512M } } }

  pg-backup:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      PGPASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - ./backups:/backups
    entrypoint: |
      sh -c 'while true; do
        pg_dump -h postgres -U ${POSTGRES_USER} ${POSTGRES_DB} | gzip > /backups/backup-$$(date +%F).sql.gz
        find /backups -name "backup-*.sql.gz" -mtime +7 -delete
        sleep 86400
      done'
    depends_on:
      postgres:
        condition: service_healthy

  caddy:
    image: caddy:2-alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data     # certificates live here, keep this volume
      - caddy_config:/config
    deploy: { resources: { limits: { memory: 256M } } }
    # Caddyfile (2 lines, automatic HTTPS):
    #   yourdomain.com {
    #       reverse_proxy app:3000
    #   }

volumes:
  pgdata:
  caddy_data:
  caddy_config:

Put these in .env beside the file: POSTGRES_USER=app POSTGRES_PASSWORD= POSTGRES_DB=app

Want a hand getting it live?

We design and build websites, and handle the work behind launch. Tell us about your website or app. We will agree the deployment scope, price and timeline before work begins.

Talk on WhatsApp