version: '3.8' services: # PostgreSQL Database postgres: image: postgres:15-alpine container_name: picpeak-postgres environment: POSTGRES_DB: ${DB_NAME:-picpeak} POSTGRES_USER: ${DB_USER:-picpeak} POSTGRES_PASSWORD: ${DB_PASSWORD:-picpeak} volumes: - postgres_data:/var/lib/postgresql/data restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-picpeak}"] interval: 10s timeout: 5s retries: 5 # Backend API backend: build: ./backend container_name: picpeak-backend depends_on: postgres: condition: service_healthy environment: NODE_ENV: production DATABASE_CLIENT: pg DB_HOST: postgres DB_PORT: 5432 DB_NAME: ${DB_NAME:-picpeak} DB_USER: ${DB_USER:-picpeak} DB_PASSWORD: ${DB_PASSWORD:-picpeak} env_file: - .env volumes: - ./storage:/app/storage - ./data:/app/data restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/health"] interval: 30s timeout: 10s retries: 3 # Frontend frontend: build: context: ./frontend args: VITE_API_URL: ${VITE_API_URL:-/api} VITE_UMAMI_URL: ${VITE_UMAMI_URL} VITE_UMAMI_WEBSITE_ID: ${VITE_UMAMI_WEBSITE_ID} container_name: picpeak-frontend depends_on: - backend restart: unless-stopped # Nginx Reverse Proxy nginx: image: nginx:alpine container_name: picpeak-nginx ports: - "80:80" - "443:443" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./certbot/conf:/etc/letsencrypt - ./certbot/www:/var/www/certbot depends_on: - frontend - backend restart: unless-stopped command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'" # Certbot for SSL certbot: image: certbot/certbot container_name: picpeak-certbot volumes: - ./certbot/conf:/etc/letsencrypt - ./certbot/www:/var/www/certbot entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'" volumes: postgres_data: networks: default: name: picpeak-network