personal-lifecycle-tracker / docker-compose.yaml
docker-compose.yaml
Raw
name: personal-lifecycle-tracker

services:
  db:
    image: postgres:16-alpine
    container_name: personal-lifecycle-tracker-db
    restart: unless-stopped
    environment:
      POSTGRES_USER: ${POSTGRES_USER:-postgres}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres}
      POSTGRES_DB: ${POSTGRES_DB:-lifecycle}
    ports:
      - "${POSTGRES_PORT:-5434}:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-lifecycle}"]
      interval: 5s
      timeout: 5s
      retries: 5
      start_period: 5s

  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
      target: base
    container_name: personal-lifecycle-tracker-backend
    environment:
      PORT: 8000
      PYTHONUNBUFFERED: "1"
      CORS_ORIGINS: "http://localhost:3000,http://localhost:3003,http://localhost:5173,http://127.0.0.1:3000,http://127.0.0.1:3003"
      DATABASE_URL: "${DATABASE_URL:-postgresql://postgres:postgres@db:5432/lifecycle}"
      APP_ENV: "${APP_ENV:-development}"
      APP_VERSION: "${APP_VERSION:-dev-latest}"
      OTEL_SERVICE_NAME: "api-backend"
      OTEL_EXPORTER_OTLP_ENDPOINT: "${OTEL_EXPORTER_OTLP_ENDPOINT:-}"
      OTEL_RESOURCE_ATTRIBUTES: "service.name=api-backend,deployment.environment=${APP_ENV:-development},service.version=${APP_VERSION:-dev-latest}"
    ports:
      - "${BACKEND_PORT:-8003}:8000"
    volumes:
      - ./backend:/app
    networks:
      - default
      - observability-net
    depends_on:
      db:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://127.0.0.1:8000/health"]
      interval: 5s
      timeout: 10s
      retries: 8
      start_period: 10s
    restart: unless-stopped

  frontend:
    image: personal-lifecycle-tracker-frontend:dev
    build:
      context: ./frontend
      dockerfile: Dockerfile
      target: dev
    container_name: personal-lifecycle-tracker-frontend
    environment:
      PORT: 3000
      VITE_API_URL: "${VITE_API_URL:-}"
      VITE_BACKEND_URL: http://backend:8000
    ports:
      - "${FRONTEND_PORT:-3003}:3000"
    volumes:
      - ./frontend:/app
      - /app/node_modules
    depends_on:
      backend:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3000').then(r => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))"]
      interval: 5s
      timeout: 5s
      retries: 5
      start_period: 10s
    restart: unless-stopped

  e2e:
    build:
      context: ./e2e
      dockerfile: Dockerfile
    container_name: personal-lifecycle-tracker-e2e
    network_mode: host
    environment:
      BASE_URL: "${BASE_URL:-http://127.0.0.1:${FRONTEND_PORT:-3003}}"
      BACKEND_URL: "${BACKEND_URL:-http://127.0.0.1:${BACKEND_PORT:-8003}}"
      CI: "true"
    volumes:
      - ./e2e:/e2e
      - /e2e/node_modules
    depends_on:
      frontend:
        condition: service_healthy
      backend:
        condition: service_healthy
    profiles: ["test", "e2e"]

volumes:
  postgres_data:

networks:
  default:
  observability-net:
    name: ${OBSERVABILITY_NET:-personal-lifecycle-observability-net}
    external: true