services: web: image: younes60/web:${DOCKER_TAGS:-latest} build: context: . dockerfile: ./apps/web/prod.Dockerfile x-bake: platforms: - linux/amd64 - linux/arm64 args: - AUTH_SECRET=${AUTH_SECRET} - JOBS_BEARER_TOKEN=${JOBS_BEARER_TOKEN} - JOBS_API_BASEURL=${JOBS_API_BASEURL} - WEB_BASE_URL=${WEB_BASE_URL} deploy: replicas: 2 labels: - "traefik.enable=true" - "traefik.http.routers.web.entrypoints=web-secure" - "traefik.http.routers.web.rule=Host(`${PUBLIC_IP}.sslip.io`)" - "traefik.http.routers.web.tls=true" - "traefik.http.routers.web.tls.certresolver=deliveryresolver" - "traefik.http.services.web.loadbalancer.server.port=3000" - "resource=delivery-web-instance" - "traefik.swarm.network=proxy" environment: - AUTH_SECRET=${AUTH_SECRET} - JOBS_BEARER_TOKEN=${JOBS_BEARER_TOKEN} - JOBS_API_BASEURL=${JOBS_API_BASEURL} - WEB_BASE_URL=${WEB_BASE_URL} ports: - 3000:3000 networks: - proxy jobs: image: younes60/jobs:${DOCKER_TAGS:-latest} build: context: . dockerfile: ./apps/jobs/prod.Dockerfile x-bake: platforms: - linux/amd64 - linux/arm64 deploy: replicas: 2 environment: - PUBLIC_IP=${PUBLIC_IP} - PORT=${PORT} - DATABASE_URL=${DATABASE_URL} - LOG_LEVEL=${LOG_LEVEL} - NODE_ENV=${NODE_ENV} - SSH_HOST=${SSH_HOST} - BEARER_TOKEN=${BEARER_TOKEN} - REDIS_PASSWORD=${REDIS_PASSWORD} - TEST_USERS_PASSWORD=${TEST_USERS_PASSWORD} - DOCKER_GID=${DOCKER_GID} - AUTH_SECRET=${AUTH_SECRET} volumes: - /data/delivery/ssh/keys:/var/ssh/keys - /var/run/docker.sock:/var/run/docker.sock ports: - 3090:3090 networks: - proxy database: image: postgres:17.5 ports: - 5432:5432 environment: - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - POSTGRES_USER=productiondb - POSTGRES_DB=productiondb networks: - proxy volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready"] interval: 5s timeout: 5s retries: 5 bull_queue: image: redis:8.0.1 command: redis-server --requirepass ${REDIS_PASSWORD} --save 60 1 --loglevel warning --maxmemory-policy noeviction --maxmemory 2gb ports: - 6379:6379 networks: - proxy volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 traefik: image: "traefik:v3.3.6" deploy: placement: constraints: - node.role == manager labels: - "traefik.enable=true" - "resource=reverse-proxy:delivery" - "traefik.swarm.network=proxy" # define traefik dashboard router and service - "traefik.http.routers.traefik.rule=Host(`traefik.${PUBLIC_IP}.sslip.io`)" - "traefik.http.routers.traefik.service=api@internal" - "traefik.http.routers.traefik.tls.certresolver=deliveryresolver" - "traefik.http.routers.traefik.entrypoints=web-secure" - "traefik.http.routers.traefik.middlewares=autodetectContenttype@file" - "traefik.http.services.traefik.loadbalancer.server.port=8080" ports: - "80:80" - "443:443" volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro" - ./infrastructure/traefik-config/traefik.yaml:/etc/traefik/traefik.yaml:ro # static traefik configuration - ./infrastructure/traefik-config/dynamic.yaml:/etc/traefik/dynamic.yaml:ro # dynamic traefik configuration - ./infrastructure/traefik-config/acme.json:/etc/traefik/acme.json # TLS certificate storage networks: - proxy networks: proxy: external: true volumes: postgres_data: name: postgres_data redis_data: name: redis_data letsencrypt: name: letsencrypt