# Развёртывание: docker compose up -d --build (или Coolify, build pack «Docker Compose») # Переменные — в .env рядом с этим файлом (образец — .env.example): DB_PASSWORD, SECRET_KEY, ADMIN_PASSWORD и др. # # Дополнительные сервисы включаются профилями — по одному или вместе: # docs — Nextcloud для документации оборудования (+ своя база), # office — ONLYOFFICE Document Server: просмотр Word/Excel/PowerPoint в портале, # ai — Ollama: локальная модель для AI-помощника (данные не уходят наружу). # Пример: в .env COMPOSE_PROFILES=docs,office,ai и затем docker compose up -d # Портал сам находит запущенные сервисы во внутренней сети Docker и подставляет их адреса в настройки # (Nextcloud, ONLYOFFICE, адрес модели). Значения из .env и из интерфейса важнее автоматических. services: db: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_DB: checklists POSTGRES_USER: checklists POSTGRES_PASSWORD: ${DB_PASSWORD} volumes: - pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U checklists -d checklists"] interval: 5s timeout: 5s retries: 20 app: build: . restart: unless-stopped depends_on: db: condition: service_healthy environment: DATABASE_URL: postgresql+psycopg://checklists:${DB_PASSWORD}@db:5432/checklists SECRET_KEY: ${SECRET_KEY} ADMIN_PASSWORD: ${ADMIN_PASSWORD} APP_TZ: ${APP_TZ:-Europe/Moscow} APP_ENV: production # слабый SECRET_KEY/ADMIN_PASSWORD -> отказ запуска FORWARDED_ALLOW_IPS: ${FORWARDED_ALLOW_IPS:-127.0.0.1} # адрес NPM (доверенный прокси) PHOTO_DIR: /data/photos # каталог фото можно сменить в админке (он должен лежать на томе) # --- документация (Nextcloud): пустой адрес — найдётся сам, если запущен профиль docs --- NC_URL: ${NC_URL:-} NC_USER: ${NC_USER:-${NEXTCLOUD_ADMIN_USER:-ncadmin}} NC_PASSWORD: ${NC_PASSWORD:-${NEXTCLOUD_ADMIN_PASSWORD:-}} NC_ROOT: ${NC_ROOT:-} # --- ONLYOFFICE: секрет общий с сервисом onlyoffice ниже; пустой адрес — найдётся сам (профиль office) --- ONLYOFFICE_URL: ${ONLYOFFICE_URL:-} ONLYOFFICE_JWT: ${ONLYOFFICE_JWT:-change-me-onlyoffice-jwt} PORTAL_INTERNAL_URL: ${PORTAL_INTERNAL_URL:-} # --- AI-помощник: пустой адрес — при профиле ai подставится Ollama и модель OLLAMA_MODEL --- ASSISTANT_PROVIDER: ${ASSISTANT_PROVIDER:-} ASSISTANT_BASE_URL: ${ASSISTANT_BASE_URL:-} ASSISTANT_MODEL: ${ASSISTANT_MODEL:-} OLLAMA_MODEL: ${OLLAMA_MODEL:-qwen2.5:7b} # модель, если найден сервис ollama ASSISTANT_API_KEY: ${ASSISTANT_API_KEY:-} volumes: - photos:/data/photos # фотографии нарядов - appdata:/srv/data # демо-режим, кэш документов и файл APK (appdata/apk/*.apk раздаётся по /app.apk) ports: - "${APP_PORT:-8080}:8000" # на этот порт хоста смотрит прокси (NPM) healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/api/v1/health', timeout=3)"] interval: 15s timeout: 5s retries: 5 start_period: 25s # ---------- профиль docs: Nextcloud ---------- nextcloud-db: image: postgres:16-alpine profiles: ["docs"] restart: unless-stopped environment: POSTGRES_DB: nextcloud POSTGRES_USER: nextcloud POSTGRES_PASSWORD: ${NEXTCLOUD_DB_PASSWORD:-${DB_PASSWORD}} volumes: - nc_pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U nextcloud -d nextcloud"] interval: 5s timeout: 5s retries: 20 nextcloud: image: nextcloud:30-apache profiles: ["docs"] restart: unless-stopped depends_on: nextcloud-db: condition: service_healthy environment: POSTGRES_HOST: nextcloud-db POSTGRES_DB: nextcloud POSTGRES_USER: nextcloud POSTGRES_PASSWORD: ${NEXTCLOUD_DB_PASSWORD:-${DB_PASSWORD}} NEXTCLOUD_ADMIN_USER: ${NEXTCLOUD_ADMIN_USER:-ncadmin} NEXTCLOUD_ADMIN_PASSWORD: ${NEXTCLOUD_ADMIN_PASSWORD:-} # «nextcloud» — имя, по которому к нему обращается портал внутри сети Docker NEXTCLOUD_TRUSTED_DOMAINS: nextcloud localhost ${NEXTCLOUD_DOMAIN:-} OVERWRITEPROTOCOL: ${NEXTCLOUD_PROTOCOL:-} # https — если Nextcloud открывают через прокси с HTTPS volumes: - nextcloud:/var/www/html ports: - "${NEXTCLOUD_PORT:-8081}:80" # веб-интерфейс Nextcloud: сюда загружают документацию healthcheck: test: ["CMD", "php", "-r", "exit(strpos((string)@file_get_contents('http://localhost/status.php'), '\"installed\":true') === false ? 1 : 0);"] interval: 30s timeout: 10s retries: 10 start_period: 120s # ---------- профиль office: ONLYOFFICE Document Server (только внутренняя сеть) ---------- onlyoffice: image: onlyoffice/documentserver:8.2 profiles: ["office"] restart: unless-stopped environment: JWT_ENABLED: "true" JWT_SECRET: ${ONLYOFFICE_JWT:-change-me-onlyoffice-jwt} ALLOW_PRIVATE_IP_ADDRESS: "true" # иначе не скачает документ с портала по внутреннему адресу Docker volumes: - onlyoffice_data:/var/www/onlyoffice/Data healthcheck: test: ["CMD-SHELL", "curl -fs http://localhost/healthcheck | grep -q true"] interval: 30s timeout: 10s retries: 10 start_period: 90s # ---------- профиль ai: локальная модель Ollama ---------- ollama: image: ollama/ollama:0.5.7 profiles: ["ai"] restart: unless-stopped volumes: - ollama:/root/.ollama # Видеокарта NVIDIA (необязательно, нужен nvidia-container-toolkit) — раскомментируйте: # deploy: # resources: # reservations: # devices: [{driver: nvidia, count: all, capabilities: [gpu]}] ollama-pull: # один раз скачивает модель в том ollama и завершается image: ollama/ollama:0.5.7 profiles: ["ai"] depends_on: [ollama] restart: "no" environment: OLLAMA_HOST: http://ollama:11434 MODEL: ${OLLAMA_MODEL:-qwen2.5:7b} entrypoint: ["/bin/sh", "-c", "sleep 5 && ollama pull \"$$MODEL\""] volumes: pgdata: photos: appdata: nc_pgdata: nextcloud: onlyoffice_data: ollama: