Docker Compose Anywhere
Effortlessly deploy Docker Compose apps in production with zero downtime using an opinionated template 🛠️.
Directory Structure
- .env
- docker-compose.yml
docker-compose.yml
version: "3.9"
services:
traefik:
image: traefik:v3.1.2
command:
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
- "--certificatesresolvers.myresolver.acme.email=${ACME_EMAIL:-your@email.com}"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./letsencrypt:/letsencrypt"
networks:
- net
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`${TRAEFIK_DASHBOARD_DOMAIN:-traefik.localhost}`)"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.middlewares=auth"
- "traefik.http.middlewares.auth.basicauth.users=${TRAEFIK_DASHBOARD_AUTH:-admin:$$apr1$$salt$$hashedpassword}"
- "traefik.http.routers.dashboard.tls=${USE_SSL:-false}"
- "traefik.http.routers.dashboard.tls.certresolver=myresolver"
redis:
image: redis
container_name: redis
ports:
- "6379:6379"
volumes:
- redis_data:/data
networks:
- net
restart: always
healthcheck:
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
interval: 10s
timeout: 5s
retries: 5
logging:
driver: json-file
options:
max-size: "50m"
max-file: "6"
db:
image: ankane/pgvector
container_name: postgres_db
ports:
- "5433:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=${POSTGRES_USER:-postgres}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgres}
- POSTGRES_DB=${POSTGRES_DB:-postgres}
- POSTGRES_HOST_AUTH_METHOD=trust
networks:
- net
restart: always
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-postgres}"]
interval: 10s
timeout: 5s
retries: 5
logging:
driver: json-file
options:
max-size: "50m"
max-file: "6"
api:
image: ghcr.io/hadijaveed/docker-compose-anywhere/app:latest
depends_on:
- traefik
- db
- redis
- dozzle
env_file:
- .env
environment:
- DATABASE_URL=postgresql+psycopg2://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@db:5432/${POSTGRES_DB:-postgres}
- REDIS_HOST=redis
- REDIS_PORT=6379
networks:
- net
deploy:
replicas: ${APP_REPLICAS:-2}
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`${API_DOMAIN:-api.localhost}`)"
- "traefik.http.routers.app.tls=${USE_SSL:-false}"
- "traefik.http.routers.app.tls.certresolver=myresolver"
- "traefik.http.services.app.loadbalancer.server.port=8000"
logging:
driver: json-file
options:
max-size: "50m"
max-file: "6"
background:
image: ghcr.io/hadijaveed/docker-compose-anywhere/background:latest
depends_on:
- db
- redis
environment:
- DATABASE_URL=postgresql+psycopg2://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@db:5432/${POSTGRES_DB:-postgres}
- REDIS_HOST=redis
- REDIS_PORT=6379
networks:
- net
deploy:
replicas: ${BACKGROUND_REPLICAS:-2}
restart: always
env_file:
- .env
logging:
driver: json-file
options:
max-size: "50m"
max-file: "6"
web:
image: ghcr.io/hadijaveed/docker-compose-anywhere/web:latest
depends_on:
- api
networks:
- net
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.web.rule=Host(`${WEB_DOMAIN:-app.localhost}`)"
- "traefik.http.routers.web.tls=${USE_SSL:-false}"
- "traefik.http.routers.web.tls.certresolver=myresolver"
- "traefik.http.services.web.loadbalancer.server.port=3001"
logging:
driver: json-file
options:
max-size: "50m"
max-file: "6"
dozzle:
image: amir20/dozzle:latest
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./dozzle/data:/data
networks:
- net
environment:
DOZZLE_NO_ANALYTICS: true
DOZZLE_AUTH_PROVIDER: simple
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.dozzle.rule=Host(`${DOZZLE_DOMAIN:-dozzle.localhost}`)"
- "traefik.http.routers.dozzle.tls=${USE_SSL:-false}"
- "traefik.http.routers.dozzle.tls.certresolver=myresolver"
- "traefik.http.services.dozzle.loadbalancer.server.port=8080"
healthcheck:
test: ["CMD", "/dozzle", "healthcheck"]
interval: 3s
timeout: 30s
retries: 5
start_period: 30s
volumes:
postgres_data:
redis_data:
networks:
net:
driver: bridgeResources
GitHub: https://github.com/hadijaveed/docker-compose-anywhere
GitHub Container Registry: ghcr.io/hadijaveed/docker-compose-anywhere/web
Configuration: https://github.com/hadijaveed/docker-compose-anywhere/blob/main/docker-compose-deploy.yml