version: '3.8' services: backend: image: 'registry.local.nothaft.cloud/picpeak-backend:latest' restart: unless-stopped environment: - NODE_ENV=production - DATABASE_CLIENT=pg - DB_HOST=db - DB_PORT=5432 - DB_USER=${DB_USER:-picpeak} - DB_PASSWORD=${DB_PASSWORD} - DB_NAME=${DB_NAME:-picpeak} - PORT=3000 - JWT_SECRET=${JWT_SECRET} - ADMIN_URL=https://picpeak.local.nothaft.cloud - FRONTEND_URL=https://picpeak.local.nothaft.cloud - SMTP_HOST=${SMTP_HOST} - SMTP_PORT=${SMTP_PORT} - SMTP_SECURE=${SMTP_SECURE} - SMTP_USER=${SMTP_USER} - SMTP_PASS=${SMTP_PASS} - EMAIL_FROM=${EMAIL_FROM} - UMAMI_URL=${UMAMI_URL} - UMAMI_WEBSITE_ID=${UMAMI_WEBSITE_ID} - STORAGE_PATH=/app/storage - EVENTS_PATH=/app/storage/events - ARCHIVE_PATH=/app/storage/events/archived volumes: - '/mnt/DockerMount/picpeak/storage:/app/storage' - '/mnt/DockerMount/picpeak/data:/app/data' - '/mnt/DockerMount/picpeak/logs:/app/logs' networks: - picpeak - proxy deploy: labels: - traefik.enable=true - traefik.docker.network=proxy # Backend API routing WITHOUT path stripping - 'traefik.http.routers.picpeak-backend.rule=(Host(`picpeak.nothaft.cloud`) || Host(`picpeak.local.nothaft.cloud`)) && PathPrefix(`/api`)' - traefik.http.routers.picpeak-backend.entrypoints=https - traefik.http.routers.picpeak-backend.tls.certresolver=dns - traefik.http.services.picpeak-backend.loadbalancer.server.port=3000 # Remove the stripprefix middleware - backend expects /api prefix # - traefik.http.middlewares.picpeak-stripprefix.stripprefix.prefixes=/api # - traefik.http.routers.picpeak-backend.middlewares=picpeak-stripprefix - traefik.http.routers.picpeak-backend.priority=100 - homepage.group=Public Services - homepage.name=PicPeak Backend - homepage.icon=mdi-api - 'homepage.href=https://picpeak.local.nothaft.cloud/api/health' - homepage.description=PicPeak API Backend healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000/health"] interval: 30s timeout: 10s retries: 3 start_period: 60s depends_on: - db frontend: image: 'registry.local.nothaft.cloud/picpeak-frontend:latest' restart: unless-stopped depends_on: - backend networks: - picpeak - proxy deploy: labels: - traefik.enable=true - traefik.docker.network=proxy - traefik.http.routers.picpeak.rule=Host(`picpeak.nothaft.cloud`) || Host(`picpeak.local.nothaft.cloud`) - traefik.http.routers.picpeak.entrypoints=https - traefik.http.routers.picpeak.tls.certresolver=dns - traefik.http.services.picpeak.loadbalancer.server.port=80 - traefik.http.routers.picpeak.priority=10 - homepage.group=Public Services - homepage.name=PicPeak - homepage.icon=mdi-photo - 'homepage.href=https://picpeak.local.nothaft.cloud/' - homepage.description=Photo Sharing System db: image: 'postgres:14-alpine' restart: unless-stopped environment: - POSTGRES_USER=${DB_USER:-picpeak} - POSTGRES_PASSWORD=${DB_PASSWORD} - POSTGRES_DB=${DB_NAME:-picpeak} - POSTGRES_HOST_AUTH_METHOD=${PG_AUTH_METHOD:-scram-sha-256} - POSTGRES_INITDB_ARGS=${PG_INIT_ARGS:---auth-host=scram-sha-256 --auth-local=trust} volumes: - '/mnt/DockerMount/picpeak/db:/var/lib/postgresql/data' networks: - picpeak command: ${PG_COMMANDS:-postgres -c ssl=off} healthcheck: test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-picpeak}"] interval: 10s timeout: 5s retries: 5 networks: proxy: external: true picpeak: driver: bridge