# Docker Compose — один файл описывает весь стек. # Запуск из этой папки: docker compose up -d --build # Версия схемы compose больше не обязательна в поле `version:` (Compose V2). name: multi-service-demo services: # --- Сервис 1: PostgreSQL (готовый образ из Docker Hub) --- db: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER:-app} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-app} POSTGRES_DB: ${POSTGRES_DB:-appdb} volumes: # Именованный том: данные БД на диске хоста, переживают пересоздание контейнера - pgdata:/var/lib/postgresql/data networks: - backend healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-app} -d ${POSTGRES_DB:-appdb}"] interval: 5s timeout: 5s retries: 10 start_period: 10s # --- Сервис 2: API (собирается из ./api/Dockerfile) --- api: build: context: ./api dockerfile: Dockerfile restart: unless-stopped environment: DATABASE_URL: postgresql://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD:-app}@db:5432/${POSTGRES_DB:-appdb} FLASK_ENV: production UPLOAD_DIR: /data/uploads volumes: # Том для загрузок: файлы копируются в API в папку тома (пример «данные вне образа») - api_uploads:/data/uploads depends_on: db: condition: service_healthy networks: - backend expose: - "5000" healthcheck: test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:5000/health || exit 1"] interval: 15s timeout: 5s retries: 5 start_period: 20s # --- Сервис 3: статический фронт (nginx + COPY html в образе web) --- web: build: context: ./web dockerfile: Dockerfile restart: unless-stopped networks: - backend expose: - "80" # --- Сервис 4: reverse proxy — единая точка входа с хоста --- proxy: build: context: ./proxy dockerfile: Dockerfile restart: unless-stopped ports: # Порт хоста берём из .env (см. .env.example) - "${HTTP_PORT:-8080}:80" depends_on: web: condition: service_started api: condition: service_healthy networks: - backend networks: backend: driver: bridge volumes: pgdata: api_uploads: