services: db: image: postgres:17-alpine environment: POSTGRES_DB: ${POSTGRES_DB:-pnvpanel} POSTGRES_USER: ${POSTGRES_USER:-pnvpanel} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-pnvpanel} volumes: - pgdata:/var/lib/postgresql/data healthcheck: test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER:-pnvpanel} -d ${POSTGRES_DB:-pnvpanel}'] interval: 5s timeout: 5s retries: 10 restart: unless-stopped app: build: context: . dockerfile: Dockerfile depends_on: db: condition: service_healthy # Секреты (Jwt__SigningKey, AdminSeed__Password, Telegram__BotToken, ...) — из .env, # см. .env.example. ConnectionStrings__Default ниже переопределяет .env: адрес БД внутри # сети compose всегда 'db', не значение из .env (которое рассчитано на локальный запуск). env_file: - .env environment: ASPNETCORE_ENVIRONMENT: Production ASPNETCORE_HTTP_PORTS: '8080' ConnectionStrings__Default: 'Host=db;Port=5432;Database=${POSTGRES_DB:-pnvpanel};Username=${POSTGRES_USER:-pnvpanel};Password=${POSTGRES_PASSWORD:-pnvpanel}' volumes: # Data Protection key-ring (шифрование секретов нод at-rest) должен пережить пересоздание # контейнера — иначе расшифровка паролей нод после рестарта станет невозможна. - dp_keys:/app/keys healthcheck: test: ['CMD', 'curl', '-f', 'http://localhost:8080/health'] interval: 15s timeout: 5s start_period: 20s retries: 5 ports: - '8080:8080' restart: unless-stopped volumes: pgdata: dp_keys: