services: db: image: postgres:16 environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} restart: unless-stopped networks: - dokploy-network expose: - 5432 volumes: - dbdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] interval: 1s timeout: 5s retries: 10 migrate: image: migrate/migrate:latest depends_on: db: condition: service_healthy environment: - RECREATION_TOKEN=${RANDOM:-1} volumes: - ./apps/db/migrations:/migrations:ro networks: - dokploy-network command: [ "-verbose", "-path", "/migrations", "-database", "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?sslmode=disable", "up" ] restart: "no" storage: image: "ghcr.io/marcopedone/go_fs:latest" expose: - 8080 restart: unless-stopped pull_policy: "always" environment: PORT: 8080 AUTH_TOKEN: ${STORAGE_TOKEN} volumes: - storage_data:/app/storage networks: - dokploy-network healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 10s timeout: 5s retries: 5 start_period: 10s tiles: image: eqalpha/keydb:latest volumes: - tiles-data:/data networks: - dokploy-network expose: - 6379 command: keydb-server /etc/keydb/keydb.conf --maxmemory 100mb --maxmemory-policy volatile-lru --maxmemory-samples 5 healthcheck: test: ["CMD", "keydb-cli", "-h", "localhost", "ping"] interval: 5s timeout: 3s retries: 5 restart: unless-stopped deploy: resources: limits: cpus: "0.5" keydb: image: eqalpha/keydb:latest volumes: - keydb-data:/data networks: - dokploy-network expose: - 6379 healthcheck: test: ["CMD", "keydb-cli", "-h", "localhost", "ping"] interval: 5s timeout: 3s retries: 5 restart: unless-stopped deploy: resources: limits: cpus: "0.5" browserless: image: browserless/chrome:latest networks: - dokploy-network expose: - 3000 environment: - MAX_CONCURRENT_SESSIONS=5 - CONNECTION_TIMEOUT=30000 restart: always backend: image: "${IMAGE_REGISTRY:-ghcr.io}/${OWNER:-marcopedone}/${PREFIX:-infoalloggi}-backend:${TAG:-latest}" networks: - dokploy-network expose: - 1323 restart: unless-stopped pull_policy: "always" environment: STORAGE_URL: http://storage:8080 STORAGE_TOKEN: ${STORAGE_TOKEN} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} PGHOST: db PGPORT: "5432" IMAGEOPTION: "true" CONCURRENT_IMAGES: ${CONCURRENT_IMAGES} healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1323/"] interval: 10s timeout: 5s retries: 5 depends_on: storage: condition: service_healthy db: condition: service_healthy keydb: condition: service_healthy tiles: condition: service_healthy web: image: "${IMAGE_REGISTRY:-ghcr.io}/${OWNER:-marcopedone}/${PREFIX:-infoalloggi}-web:${TAG:-latest}" working_dir: /app restart: unless-stopped pull_policy: "always" environment: INTERNAL_BASE_URL: http://web:3000 POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} PGHOST: db PGPORT: "5432" BACKENDSERVER_URL: http://backend:1323 KEYDB_URL: keydb:6379 TILES_URL: tiles:6379 BASE_URL: ${BASE_URL} NEXT_PUBLIC_BASE_URL: ${BASE_URL} STRIPE_SECRET_KEY: ${STRIPE_SECRET_KEY} NEXT_PUBLIC_STRIPE_PUBLIC_KEY: ${NEXT_PUBLIC_STRIPE_PUBLIC_KEY} STRIPE_WEBHOOK_SECRET: ${STRIPE_WEBHOOK_SECRET} FIC_CLIENT_ID: ${FIC_CLIENT_ID} FIC_ACCESS_TOKEN: ${FIC_ACCESS_TOKEN} FIC_COMPANY_ID: ${FIC_COMPANY_ID} ARUBA_USER: ${ARUBA_USER} ARUBA_PASS: ${ARUBA_PASS} EXP_API_USER: ${EXP_API_USER} EXP_API_PASS: ${EXP_API_PASS} JWT_SECRET: ${JWT_SECRET} SKEBBY_USER: ${SKEBBY_USER} SKEBBY_PASS: ${SKEBBY_PASS} STORAGE_URL: http://storage:8080 STORAGE_TOKEN: ${STORAGE_TOKEN} BROWSER_WS_URL: "ws://browserless:3000" networks: - dokploy-network expose: - 3000 labels: - "traefik.enable=true" # HTTP ROUTER - "traefik.http.routers.app-http.rule=Host(`${DOMAIN}`) || Host(`www.${DOMAIN}`)" - "traefik.http.routers.app-http.entrypoints=web" - "traefik.http.routers.app-http.service=app-http" - "traefik.http.routers.app-http.middlewares=redirect-to-https@file" - "traefik.http.services.app-http.loadbalancer.server.port=3000" # HTTPS FOR WWW - "traefik.http.routers.app-www.rule=Host(`www.${DOMAIN}`)" - "traefik.http.routers.app-www.entrypoints=websecure" - "traefik.http.routers.app-www.service=app" - "traefik.http.routers.app-www.tls.certresolver=letsencrypt" - "traefik.http.routers.app-www.middlewares=redirect-apex" # APEX REDIRECT - "traefik.http.middlewares.redirect-apex.redirectregex.regex=^https?://www\\.${DOMAIN//./\\.}/(.*)" - "traefik.http.middlewares.redirect-apex.redirectregex.replacement=https://${DOMAIN}/$${1}" - "traefik.http.middlewares.redirect-apex.redirectregex.permanent=true" # CANONICAL DOMAIN - "traefik.http.routers.app.rule=Host(`${DOMAIN}`)" - "traefik.http.routers.app.entrypoints=websecure" - "traefik.http.routers.app.service=app" - "traefik.http.routers.app.tls.certresolver=letsencrypt" - "traefik.http.services.app.loadbalancer.server.port=3000" depends_on: backend: condition: service_healthy db: condition: service_healthy keydb: condition: service_healthy tiles: condition: service_healthy networks: dokploy-network: external: true volumes: storage_data: tiles-data: keydb-data: dbdata: