version: '3.9' services: backend: container_name: "${APP_NAME}-backend" build: context: . dockerfile: deployment/Dockerfile args: - APP_NAME=${APP_NAME} - APP_HOST=${APP_HOST} - APP_PORT=${APP_PORT} volumes: - ./src:/usr/src/app/ - ./deployment/scripts:/app/deployment/scripts/ - static_files:/usr/src/app/static - media_files:/usr/src/app/media labels: - "traefik.enable=true" - "traefik.http.routers.${APP_NAME}-backend.rule=Host(`${APP_DOMAIN}`)" - "traefik.http.routers.${APP_NAME}-backend.entrypoints=web" - "traefik.http.services.${APP_NAME}-backend.loadbalancer.server.port=${APP_PORT:-8000}" env_file: .env expose: - "${APP_PORT:-8000}" depends_on: db: condition: service_healthy command: [ "/bin/sh", "/app/deployment/scripts/backend/start.sh" ] db: image: postgres:15.2-alpine container_name: "${APP_NAME}-db" hostname: "${POSTGRES_HOST:-db}" volumes: - postgres_data_dir:/var/lib/postgresql/data/ env_file: .env expose: - "${POSTGRES_PORT:-5432}" shm_size: 1g healthcheck: test: ["CMD", "pg_isready", "-U", "${POSTGRES_USER}", "-d", "${POSTGRES_DB}"] interval: 10s timeout: 5s retries: 5 redis: container_name: "${APP_NAME}-redis" image: redis:latest volumes: - redis_data:/data celery-worker: &celery-worker container_name: "${APP_NAME}-celery-worker" build: context: . dockerfile: deployment/Dockerfile volumes: - ./src:/usr/src/app/ - ./deployment/scripts:/app/deployment/scripts/ env_file: .env depends_on: - db - redis - backend command: [ "/bin/sh", "/app/deployment/scripts/celery/start-worker.sh" ] celery-beat: <<: *celery-worker container_name: "${APP_NAME}-celery-beat" command: [ "/bin/sh", "/app/deployment/scripts/celery/start-beat.sh" ] nginx: image: nginx:latest container_name: "${APP_NAME}-nginx" volumes: - ./deployment/scripts/nginx/nginx.conf:/etc/nginx/nginx.conf:ro - static_files:/usr/src/app/static - media_files:/usr/src/app/media labels: - "traefik.enable=true" - "traefik.http.routers.${APP_NAME}-nginx.rule=Host(`${APP_DOMAIN}`)" - "traefik.http.routers.${APP_NAME}-nginx.entrypoints=websecure" - "traefik.http.services.${APP_NAME}-nginx.loadbalancer.server.port=80" - "traefik.http.routers.${APP_NAME}-nginx.tls=true" - "traefik.http.routers.${APP_NAME}-nginx.tls.certresolver=myresolver" expose: - "80" - "443" depends_on: - backend - traefik traefik: image: traefik:v2.5 container_name: "${APP_NAME}-traefik" command: - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--providers.docker.watch=true" - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--entrypoints.web.http.redirections.entryPoint.to=websecure" - "--entrypoints.web.http.redirections.entryPoint.scheme=https" - "--entrypoints.web.http.redirections.entrypoint.permanent=true" - "--api.dashboard=true" - "--certificatesresolvers.myresolver.acme.httpchallenge=true" - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web" - "--certificatesresolvers.myresolver.acme.email=${LETSENCRYPT_EMAIL}" - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" - "--log.level=DEBUG" - "--accesslog=true" - "--tracing=true" labels: - "traefik.enable=true" - "traefik.http.routers.dashboard.rule=Host(`${TRAEFIK_DOMAIN}`) && (PathPrefix(`/`))" - "traefik.http.routers.dashboard.tls=true" - "traefik.http.routers.dashboard.tls.certresolver=myresolver" - "traefik.http.routers.dashboard.entrypoints=websecure" - "traefik.http.routers.dashboard.service=api@internal" - "traefik.http.routers.dashboard.middlewares=auth" - "traefik.http.middlewares.auth.basicauth.users=user:$$2y$$05$$22TlNvU.X30m4rVd3aIA3.jF/XXkh6eayHg5UYwDNgF8MVFwJgPrS" ports: - "80:80" - "443:443" volumes: - "/var/run/docker.sock:/var/run/docker.sock" - "./letsencrypt:/letsencrypt" volumes: static_files: media_files: postgres_data_dir: redis_data: