name: neon-bar # Три контейнера: сайт (nginx + статика), CRM (Python API), PostgreSQL. # Сеть внутренняя: наружу смотрит только сайт; CRM отдаёт ему /api/. services: db: # NF-20: дайджест-пин базового образа — пересборка в другой день даёт # те же слои (обновление пина — осознанное действие: новый digest + тест) image: postgres:17-alpine@sha256:b0f9560a2de083e2cc7382e75f808c7381a32852a7ec49117deedb300e552b24 container_name: neon-db restart: unless-stopped stop_grace_period: 10s mem_limit: 512m logging: &logging driver: json-file options: { max-size: "10m", max-file: "3" } environment: # Пароли БЕЗ дефолтов (F-1/F-2): compose упадёт с понятной ошибкой, # если .env не задан — дефолтные креды в контейнер не попадут никогда. POSTGRES_DB: ${PG_DB:?Задайте PG_DB в .env} POSTGRES_USER: ${PG_USER:?Задайте PG_USER в .env} POSTGRES_PASSWORD: ${PG_PASSWORD:?Задайте PG_PASSWORD в .env} volumes: - pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${PG_USER} -d ${PG_DB}"] interval: 5s timeout: 3s retries: 20 crm: build: ./crm container_name: neon-crm restart: unless-stopped stop_grace_period: 10s mem_limit: 256m logging: *logging depends_on: db: condition: service_healthy environment: DATABASE_URL: postgresql://${PG_USER}:${PG_PASSWORD}@db:5432/${PG_DB} CRM_PORT: "47613" # расписание смен, границы суток в отчётах и «новинках» считаются # по барному времени (фиксированный UTC+5) — TZ важен для SQL-окон TZ: ${CRM_TZ:-Asia/Yekaterinburg} CRM_OWNER_LOGIN: ${CRM_OWNER_LOGIN:-owner} # Пароли только из .env (F-2): дефолтных neon2026 больше не существует. # Первый старт создаёт учётки с этими паролями; смена .env на живой базе # не действует — каждому сотруднику меняет пароль в панели (кнопка 🔑). CRM_OWNER_PASSWORD: ${CRM_OWNER_PASSWORD:?Задайте CRM_OWNER_PASSWORD в .env} CRM_OWNER_NAME: ${CRM_OWNER_NAME:-Нурлан} CRM_ADMIN_LOGIN: ${CRM_ADMIN_LOGIN:-admin} CRM_ADMIN_PASSWORD: ${CRM_ADMIN_PASSWORD:?Задайте CRM_ADMIN_PASSWORD в .env} CRM_ADMIN_NAME: ${CRM_ADMIN_NAME:-Ирина} CRM_WAITER_LOGIN: ${CRM_WAITER_LOGIN:-waiter.mark} CRM_WAITER_PASSWORD: ${CRM_WAITER_PASSWORD:?Задайте CRM_WAITER_PASSWORD в .env} CRM_WAITER_NAME: ${CRM_WAITER_NAME:-Марк} CRM_SEED_DEMO_ORDERS: ${CRM_SEED_DEMO_ORDERS:-0} # 1 — разрешить старт с дефолтными паролями (только dev-стенд!) CRM_ALLOW_DEFAULT_PASSWORDS: ${CRM_ALLOW_DEFAULT_PASSWORDS:-0} # Публикуем только на localhost: посетителям CRM не нужна, # а админ может зайти с сервера через SSH-туннель при желании. ports: - "127.0.0.1:47613:47613" volumes: # фото позиций, загружаемые владельцем, переживают пересборку - ./crm/media:/app/media site: build: ./site container_name: neon-site restart: unless-stopped stop_grace_period: 10s mem_limit: 64m logging: *logging depends_on: - crm ports: - "${SITE_BIND:-127.0.0.1}:${SITE_PORT:-8080}:80" volumes: pgdata: # NF-10: фиксированная подсеть сети compose — site/nginx.conf доверяет # X-Forwarded-For только ей и 127.0.0.1 (set_real_ip_from). Меняете здесь — # меняйте и там. networks: default: ipam: config: - subnet: 172.18.0.0/16