services: traefik: image: traefik:v3.1 restart: unless-stopped environment: DOCKER_API_VERSION: "1.40" command: - --providers.docker=true - --providers.docker.exposedbydefault=false - --entrypoints.web.address=:80 - --entrypoints.websecure.address=:443 - --entrypoints.web.http.redirections.entrypoint.to=websecure - --entrypoints.web.http.redirections.entrypoint.scheme=https - --certificatesresolvers.le.acme.email=${TRAEFIK_ACME_EMAIL} - --certificatesresolvers.le.acme.storage=/letsencrypt/acme.json - --certificatesresolvers.le.acme.httpchallenge=true - --certificatesresolvers.le.acme.httpchallenge.entrypoint=web ports: - "80:80" - "443:443" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - letsencrypt:/letsencrypt postgres: image: postgres:15 restart: unless-stopped environment: POSTGRES_DB: eventsphere POSTGRES_USER: eventsphere POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U eventsphere -d eventsphere"] interval: 5s timeout: 5s retries: 20 redis: image: redis:7-alpine restart: unless-stopped volumes: - redisdata:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 5s retries: 20 api: build: context: . dockerfile: apps/api/Dockerfile restart: unless-stopped environment: NODE_ENV: production PORT: 4000 DATABASE_URL: ${DATABASE_URL} JWT_SECRET: ${JWT_SECRET} JWT_ACCESS_TTL: ${JWT_ACCESS_TTL:-15m} JWT_REFRESH_TTL: ${JWT_REFRESH_TTL:-30d} REDIS_URL: ${REDIS_URL:-redis://redis:6379} PUBLIC_API_URL: ${PUBLIC_API_URL} PUBLIC_WEB_URL: https://${TRAEFIK_DOMAIN_APP} CORS_ORIGINS: https://${TRAEFIK_DOMAIN_APP} AUTO_BOOTSTRAP: ${AUTO_BOOTSTRAP:-1} ALLOW_PUBLIC_SIGNUP: ${ALLOW_PUBLIC_SIGNUP:-0} DEFAULT_TENANT_NAME: ${DEFAULT_TENANT_NAME} DEFAULT_TENANT_SLUG: ${DEFAULT_TENANT_SLUG} DEFAULT_SUPERADMIN_FULL_NAME: ${DEFAULT_SUPERADMIN_FULL_NAME} DEFAULT_SUPERADMIN_EMAIL: ${DEFAULT_SUPERADMIN_EMAIL} DEFAULT_SUPERADMIN_PASSWORD: ${DEFAULT_SUPERADMIN_PASSWORD} SMTP_HOST: ${SMTP_HOST} SMTP_PORT: ${SMTP_PORT} SMTP_USER: ${SMTP_USER} SMTP_PASS: ${SMTP_PASS} SMTP_FROM: ${SMTP_FROM} AFRICASTALKING_USERNAME: ${AFRICASTALKING_USERNAME} AFRICASTALKING_API_KEY: ${AFRICASTALKING_API_KEY} AFRICASTALKING_SENDER_ID: ${AFRICASTALKING_SENDER_ID} AFRICASTALKING_WHATSAPP_URL: ${AFRICASTALKING_WHATSAPP_URL} PAYSTACK_SECRET_KEY: ${PAYSTACK_SECRET_KEY} UPLOADS_DIR: /app/uploads volumes: - uploads:/app/uploads depends_on: postgres: condition: service_healthy redis: condition: service_healthy labels: - traefik.enable=true - traefik.http.routers.api.rule=Host(`${TRAEFIK_DOMAIN_API}`) - traefik.http.routers.api.entrypoints=websecure - traefik.http.routers.api.tls=true - traefik.http.routers.api.tls.certresolver=le - traefik.http.services.api.loadbalancer.server.port=4000 healthcheck: test: ["CMD", "node", "-e", "require('http').get('http://localhost:4000/api/v1/health',r=>process.exit(r.statusCode===200?0:1)).on('error',()=>process.exit(1))"] interval: 10s timeout: 5s retries: 20 worker: build: context: . dockerfile: apps/worker/Dockerfile restart: unless-stopped environment: NODE_ENV: production DATABASE_URL: ${DATABASE_URL} JWT_SECRET: ${JWT_SECRET} JWT_ACCESS_TTL: ${JWT_ACCESS_TTL:-15m} JWT_REFRESH_TTL: ${JWT_REFRESH_TTL:-30d} REDIS_URL: ${REDIS_URL:-redis://redis:6379} PUBLIC_API_URL: ${PUBLIC_API_URL} PUBLIC_WEB_URL: https://${TRAEFIK_DOMAIN_APP} PROCESS_QUEUES: "1" SMTP_HOST: ${SMTP_HOST} SMTP_PORT: ${SMTP_PORT} SMTP_USER: ${SMTP_USER} SMTP_PASS: ${SMTP_PASS} SMTP_FROM: ${SMTP_FROM} AFRICASTALKING_USERNAME: ${AFRICASTALKING_USERNAME} AFRICASTALKING_API_KEY: ${AFRICASTALKING_API_KEY} AFRICASTALKING_SENDER_ID: ${AFRICASTALKING_SENDER_ID} AFRICASTALKING_WHATSAPP_URL: ${AFRICASTALKING_WHATSAPP_URL} PAYSTACK_SECRET_KEY: ${PAYSTACK_SECRET_KEY} depends_on: api: condition: service_healthy web: build: context: . dockerfile: apps/web/Dockerfile args: NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL} restart: unless-stopped depends_on: api: condition: service_healthy labels: - traefik.enable=true - traefik.http.routers.web.rule=Host(`${TRAEFIK_DOMAIN_APP}`) - traefik.http.routers.web.entrypoints=websecure - traefik.http.routers.web.tls=true - traefik.http.routers.web.tls.certresolver=le - traefik.http.services.web.loadbalancer.server.port=3000 volumes: pgdata: redisdata: letsencrypt: uploads: