name: rentaldrivego-prod services: postgres: image: postgres:16-alpine restart: unless-stopped networks: - internal environment: POSTGRES_DB: rentaldrivego POSTGRES_USER: postgres POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-change-me} healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -d rentaldrivego"] interval: 5s timeout: 5s retries: 10 volumes: - postgres_prod_data:/var/lib/postgresql/data redis: image: redis:7-alpine restart: unless-stopped networks: - internal volumes: - redis_prod_data:/data api: image: ${APP_IMAGE:-rentaldrivego-prod-app}:${APP_VERSION:-latest} build: context: . dockerfile: Dockerfile.production command: - bash - -c - | npm run db:deploy && npm run start --workspace @rentaldrivego/api networks: - internal - traefik-proxy depends_on: postgres: condition: service_healthy redis: condition: service_started env_file: - .env.docker.production environment: DATABASE_URL_FROM_POSTGRES: ${DATABASE_URL_FROM_POSTGRES:-true} FILE_STORAGE_ROOT: /var/lib/rentaldrivego/storage POSTGRES_HOST: ${POSTGRES_HOST:-postgres} POSTGRES_PORT: ${POSTGRES_PORT:-5432} POSTGRES_DB: ${POSTGRES_DB:-rentaldrivego} POSTGRES_USER: ${POSTGRES_USER:-postgres} volumes: - api_uploads:/var/lib/rentaldrivego/storage restart: unless-stopped labels: - traefik.enable=true - traefik.http.routers.api.rule=Host(`${API_DOMAIN}`) - traefik.http.routers.api.entrypoints=websecure - traefik.http.routers.api.tls=true - traefik.http.routers.api.tls.certresolver=letsencrypt - traefik.http.services.api.loadbalancer.server.port=4000 marketplace: image: ${APP_IMAGE:-rentaldrivego-prod-app}:${APP_VERSION:-latest} build: context: . dockerfile: Dockerfile.production args: NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL} NEXT_PUBLIC_MARKETPLACE_URL: ${NEXT_PUBLIC_MARKETPLACE_URL} NEXT_PUBLIC_DASHBOARD_URL: ${NEXT_PUBLIC_DASHBOARD_URL} NEXT_PUBLIC_ADMIN_URL: ${NEXT_PUBLIC_ADMIN_URL} command: ["npm", "run", "start", "--workspace", "@rentaldrivego/marketplace"] networks: - internal - traefik-proxy depends_on: - api env_file: - .env.docker.production restart: unless-stopped labels: - traefik.enable=true - traefik.http.routers.marketplace.rule=Host(`${PUBLIC_SITE_DOMAIN}`) || Host(`www.${PUBLIC_SITE_DOMAIN}`) - traefik.http.routers.marketplace.entrypoints=websecure - traefik.http.routers.marketplace.tls=true - traefik.http.routers.marketplace.tls.certresolver=letsencrypt - traefik.http.routers.marketplace.service=marketplace-svc - traefik.http.routers.marketplace.priority=10 - traefik.http.services.marketplace-svc.loadbalancer.server.port=3000 dashboard: image: ${APP_IMAGE:-rentaldrivego-prod-app}:${APP_VERSION:-latest} build: context: . dockerfile: Dockerfile.production args: NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL} NEXT_PUBLIC_MARKETPLACE_URL: ${NEXT_PUBLIC_MARKETPLACE_URL} NEXT_PUBLIC_DASHBOARD_URL: ${NEXT_PUBLIC_DASHBOARD_URL} NEXT_PUBLIC_ADMIN_URL: ${NEXT_PUBLIC_ADMIN_URL} command: ["npm", "run", "start", "--workspace", "@rentaldrivego/dashboard"] networks: - internal - traefik-proxy depends_on: - api env_file: - .env.docker.production restart: unless-stopped labels: - traefik.enable=true - traefik.http.routers.dashboard.rule=(Host(`${PUBLIC_SITE_DOMAIN}`) || Host(`www.${PUBLIC_SITE_DOMAIN}`)) && PathPrefix(`/dashboard`) - traefik.http.routers.dashboard.entrypoints=websecure - traefik.http.routers.dashboard.tls=true - traefik.http.routers.dashboard.tls.certresolver=letsencrypt - traefik.http.routers.dashboard.service=dashboard-svc - traefik.http.routers.dashboard.priority=20 - traefik.http.services.dashboard-svc.loadbalancer.server.port=3001 admin: image: ${APP_IMAGE:-rentaldrivego-prod-app}:${APP_VERSION:-latest} build: context: . dockerfile: Dockerfile.production args: NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL} NEXT_PUBLIC_MARKETPLACE_URL: ${NEXT_PUBLIC_MARKETPLACE_URL} NEXT_PUBLIC_DASHBOARD_URL: ${NEXT_PUBLIC_DASHBOARD_URL} NEXT_PUBLIC_ADMIN_URL: ${NEXT_PUBLIC_ADMIN_URL} command: ["npm", "run", "start", "--workspace", "@rentaldrivego/admin"] networks: - internal - traefik-proxy depends_on: - api env_file: - .env.docker.production restart: unless-stopped labels: - traefik.enable=true - traefik.http.routers.admin.rule=(Host(`${PUBLIC_SITE_DOMAIN}`) || Host(`www.${PUBLIC_SITE_DOMAIN}`)) && PathPrefix(`/admin`) - traefik.http.routers.admin.entrypoints=websecure - traefik.http.routers.admin.tls=true - traefik.http.routers.admin.tls.certresolver=letsencrypt - traefik.http.routers.admin.service=admin-svc - traefik.http.routers.admin.priority=20 - traefik.http.services.admin-svc.loadbalancer.server.port=3002 pgmanage: image: cmdpromptinc/pgmanage-enterprise:latest restart: unless-stopped user: "0:0" networks: - internal - traefik-proxy depends_on: postgres: condition: service_healthy environment: PGMANAGE_LISTEN_PORT: "8000" PGMANAGE_DEFAULT_USERNAME: ${PGMANAGE_DEFAULT_USERNAME:-admin} PGMANAGE_DEFAULT_PASSWORD: ${PGMANAGE_DEFAULT_PASSWORD:-admin} PGMANAGE_SECURE_COOKIES: "True" volumes: - pgmanage_prod_data:/appdata - ./docker/pgmanage/override.py:/appdata/override.py:ro labels: - traefik.enable=true - traefik.http.routers.pgmanage.rule=Host(`${PGMANAGE_DOMAIN}`) - traefik.http.routers.pgmanage.entrypoints=websecure - traefik.http.routers.pgmanage.tls.certresolver=letsencrypt - traefik.http.services.pgmanage.loadbalancer.server.port=8000 networks: internal: driver: bridge traefik-proxy: external: true volumes: postgres_prod_data: redis_prod_data: pgmanage_prod_data: api_uploads: