# Production-стек LMS: PostgreSQL 18 + 5 сервисов. # Java на сервере не нужна — всё собирается и запускается в контейнерах. # # Запуск: # cp .env.prod.example .env.prod # и заполнить секреты # docker compose --env-file .env.prod -f docker-compose.prod.yml up -d --build # # Наружу публикуется только web на 127.0.0.1:8090; его проксирует nginx (deploy/nginx). name: lms x-db-env: &db-env LMS_DB_USER: ${LMS_DB_USER:-lms} LMS_DB_PASSWORD: ${LMS_DB_PASSWORD:?Задайте LMS_DB_PASSWORD в .env.prod} # Все backend-сервисы проверяют JWT по JWKS identity. В контейнерах это # http://identity:8081, а не localhost (иначе 401 на авторизованных запросах). x-jwt-env: &jwt-env LMS_JWT_JWK_SET_URI: http://identity:8081/api/v1/auth/jwks.json x-internal-env: &internal-env LMS_INTERNAL_TOKEN: ${LMS_INTERNAL_TOKEN:?Задайте LMS_INTERNAL_TOKEN в .env.prod} services: postgres: image: postgres:18 restart: unless-stopped environment: POSTGRES_DB: ${LMS_DB_NAME:-lms} POSTGRES_USER: ${LMS_DB_USER:-lms} POSTGRES_PASSWORD: ${LMS_DB_PASSWORD:?Задайте LMS_DB_PASSWORD в .env.prod} volumes: - lms_pgdata:/var/lib/postgresql healthcheck: test: ["CMD-SHELL", "pg_isready -U ${LMS_DB_USER:-lms} -d ${LMS_DB_NAME:-lms}"] interval: 5s timeout: 3s retries: 20 networks: [lms] identity: build: { context: ., target: identity } image: lms-identity:latest restart: unless-stopped environment: <<: [*db-env, *internal-env] LMS_DB_URL: jdbc:postgresql://postgres:5432/${LMS_DB_NAME:-lms}?currentSchema=identity depends_on: postgres: { condition: service_healthy } networks: [lms] academic: build: { context: ., target: academic } image: lms-academic:latest restart: unless-stopped environment: <<: [*db-env, *jwt-env, *internal-env] LMS_DB_URL: jdbc:postgresql://postgres:5432/${LMS_DB_NAME:-lms}?currentSchema=academic LMS_IDENTITY_URI: http://identity:8081 LMS_CONTENT_ASSETS_DIR: /data/content-assets volumes: - lms_assets:/data/content-assets depends_on: postgres: { condition: service_healthy } identity: { condition: service_started } networks: [lms] progress: build: { context: ., target: progress } image: lms-progress:latest restart: unless-stopped environment: <<: [*db-env, *jwt-env, *internal-env] LMS_DB_URL: jdbc:postgresql://postgres:5432/${LMS_DB_NAME:-lms}?currentSchema=progress LMS_SUBMISSIONS_DIR: /data/submissions LMS_IDENTITY_URI: http://identity:8081 LMS_ACADEMIC_URI: http://academic:8082 volumes: - lms_submissions:/data/submissions depends_on: postgres: { condition: service_healthy } identity: { condition: service_started } academic: { condition: service_started } networks: [lms] gateway: build: { context: ., target: gateway } image: lms-gateway:latest restart: unless-stopped environment: LMS_IDENTITY_URI: http://identity:8081 LMS_ACADEMIC_URI: http://academic:8082 LMS_PROGRESS_URI: http://progress:8083 LMS_JWT_JWK_SET_URI: http://identity:8081/api/v1/auth/jwks.json depends_on: identity: { condition: service_started } academic: { condition: service_started } progress: { condition: service_started } networks: [lms] web: build: { context: ., target: web } image: lms-web:latest restart: unless-stopped environment: LMS_GATEWAY_URL: http://gateway:8080 SERVER_PORT: 8090 ports: - "127.0.0.1:${LMS_WEB_PORT:-8090}:8090" depends_on: gateway: { condition: service_started } networks: [lms] networks: lms: volumes: lms_pgdata: lms_submissions: lms_assets: