services: postgres: image: postgres:16-alpine container_name: basil-postgres restart: unless-stopped environment: POSTGRES_USER: basil POSTGRES_PASSWORD: basil POSTGRES_DB: basil ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data networks: - internal healthcheck: test: ["CMD-SHELL", "pg_isready -U basil"] interval: 10s timeout: 5s retries: 5 api: image: ${DOCKER_REGISTRY:-harbor.pkartchner.com}/${DOCKER_USERNAME:-basil}/basil-api:${IMAGE_TAG:-latest} build: context: . dockerfile: packages/api/Dockerfile container_name: basil-api restart: unless-stopped depends_on: postgres: condition: service_healthy environment: NODE_ENV: production PORT: 3001 # Use DATABASE_URL from .env if set, otherwise default to local postgres DATABASE_URL: ${DATABASE_URL:-postgresql://basil:basil@postgres:5432/basil?schema=public} STORAGE_TYPE: local LOCAL_STORAGE_PATH: /app/uploads BACKUP_PATH: /app/backups CORS_ORIGIN: https://basil.pkartchner.com # JWT Configuration JWT_SECRET: ${JWT_SECRET:-change-this-to-a-random-secret-min-32-characters-long} JWT_REFRESH_SECRET: ${JWT_REFRESH_SECRET:-change-this-to-another-random-secret-min-32-characters} JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-15m} JWT_REFRESH_EXPIRES_IN: ${JWT_REFRESH_EXPIRES_IN:-7d} # Google OAuth GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID} GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET} GOOGLE_CALLBACK_URL: ${GOOGLE_CALLBACK_URL:-https://basil.pkartchner.com/api/auth/google/callback} # Application URLs APP_URL: ${APP_URL:-https://basil.pkartchner.com} API_URL: ${API_URL:-https://basil.pkartchner.com} volumes: - uploads_data:/app/uploads - backups_data:/app/backups networks: - internal - traefik web: image: ${DOCKER_REGISTRY:-harbor.pkartchner.com}/${DOCKER_USERNAME:-basil}/basil-web:${IMAGE_TAG:-latest} build: context: . dockerfile: packages/web/Dockerfile container_name: basil-web restart: unless-stopped depends_on: - api networks: - traefik - internal labels: - "traefik.enable=true" # HTTP router (will redirect to HTTPS) - "traefik.http.routers.basil-http.rule=Host(`basil.pkartchner.com`)" - "traefik.http.routers.basil-http.entrypoints=http" - "traefik.http.routers.basil-http.middlewares=redirect-to-https" # HTTPS router - "traefik.http.routers.basil.rule=Host(`basil.pkartchner.com`)" - "traefik.http.routers.basil.entrypoints=https" - "traefik.http.routers.basil.tls.certresolver=letsencrypt" - "traefik.http.routers.basil.middlewares=geoblock@file,secure-headers@file,crowdsec-bouncer@file" # Service - "traefik.http.services.basil.loadbalancer.server.port=80" - "traefik.docker.network=traefik" volumes: postgres_data: uploads_data: backups_data: networks: traefik: external: true internal: driver: bridge