Шаг 1.8 плана production-готовности: дамп 2026-09-07 03:00 восстановлен в scratch-БД без ошибок (125 таблиц), процедура задокументирована в DOCKER.md
13 KiB
Запуск через Docker
Приложение поддерживает несколько режимов развёртывания через Docker Compose.
Каждый режим активируется профилями --profile.
Режимы базы данных
| Режим | База данных | Команда |
|---|---|---|
| Внешняя (Neon, любой Postgres) | Ваш хост | docker compose up --build |
| Встроенная PostgreSQL | Docker-контейнер | docker compose --profile with-postgres up --build |
Режимы хранилища файлов
| Режим | Хранилище | Команда |
|---|---|---|
| Локальный диск (по умолчанию) | Папка uploads/ |
(без флагов) |
| MinIO S3 + WebDAV | MinIO-контейнер | --profile with-minio |
Профили можно комбинировать. Самый полный вариант («устройство в коробке»):
docker compose --profile with-postgres --profile with-minio up --build
Режим 1: Внешняя база, локальный диск
Файлы хранятся в папке uploads/ (сбрасываются при пересборке).
DATABASE_URL=postgresql://user:password@host/dbname?sslmode=require
JWT_SECRET=...
SESSION_SECRET=...
API_KEY_HMAC_SECRET=...
VAPID_PUBLIC_KEY=...
VAPID_PRIVATE_KEY=...
docker compose up --build
Режим 2: Встроенная PostgreSQL, локальный диск
# PostgreSQL
POSTGRES_DB=appdb
POSTGRES_USER=appuser
POSTGRES_PASSWORD=your-strong-db-password
DATABASE_URL=postgresql://appuser:your-strong-db-password@db:5432/appdb
# App
JWT_SECRET=...
SESSION_SECRET=...
API_KEY_HMAC_SECRET=...
VAPID_PUBLIC_KEY=...
VAPID_PRIVATE_KEY=...
docker compose --profile with-postgres up --build
Режим 3: MinIO S3 + WebDAV (рекомендуется для устройств)
Файлы хранятся в MinIO — не теряются при перезапуске. WebDAV позволяет просматривать и добавлять файлы через Windows Explorer, Finder, Cyberduck.
Переменные окружения
# PostgreSQL (если используете встроенную)
POSTGRES_DB=appdb
POSTGRES_USER=appuser
POSTGRES_PASSWORD=your-strong-db-password
DATABASE_URL=postgresql://appuser:your-strong-db-password@db:5432/appdb
# MinIO S3 — приложение видит MinIO как "minio" внутри Docker-сети
MINIO_ENDPOINT=http://minio:9000
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=your-strong-minio-password
MINIO_BUCKET=files
# WebDAV — доступ через браузер/файловый менеджер на порту 8080
WEBDAV_USER=admin
WEBDAV_PASSWORD=your-webdav-password
# App
JWT_SECRET=...
SESSION_SECRET=...
API_KEY_HMAC_SECRET=...
VAPID_PUBLIC_KEY=...
VAPID_PRIVATE_KEY=...
Запуск (всё сразу: PostgreSQL + App + MinIO + WebDAV)
docker compose --profile with-postgres --profile with-minio up --build
Доступные интерфейсы
| Сервис | Адрес | Описание |
|---|---|---|
| iistwin приложение | http://device-ip:5000 |
Основной интерфейс |
| MinIO Console | http://device-ip:9001 |
Веб-интерфейс MinIO (логин: MINIO_ACCESS_KEY) |
| WebDAV | http://device-ip:8080 |
Файловый менеджер (логин: WEBDAV_USER) |
Подключение WebDAV
Windows Explorer: Нажмите «Подключить сетевой диск» → введите \\device-ip@8080\DavWWWRoot
macOS Finder: Нажмите ⌘K → введите http://device-ip:8080
Cyberduck / WinSCP: Протокол WebDAV, хост device-ip, порт 8080
Локальные LLM через Ollama
Профиль with-ollama запускает Ollama — локальный LLM-сервер — как отдельный контейнер. Модели не скачиваются автоматически: вы выбираете и загружаете их через интерфейс iistwin в разделе Настройки → LLM Провайдеры.
Запуск с Ollama
# Только приложение + Ollama (внешняя БД)
docker compose --profile with-ollama up --build
# Всё сразу: PostgreSQL + App + Ollama
docker compose --profile with-postgres --profile with-ollama up --build
# Максимальная конфигурация: PostgreSQL + MinIO + WebDAV + Ollama
docker compose --profile with-postgres --profile with-minio --profile with-ollama up --build
При активном профиле with-ollama переменная OLLAMA_BASE_URL=http://ollama:11434 передаётся в контейнер приложения автоматически через docker-compose.yml. Переопределить адрес можно через .env.
Управление моделями через UI
После запуска откройте Настройки → LLM Провайдеры, добавьте провайдер типа Ollama с URL http://ollama:11434 (или http://localhost:11434 для локального запуска вне Docker) и воспользуйтесь разделом «Модели Ollama»:
- Скачать модель — введите имя (например
qwen2.5:7b) и нажмите «Скачать». Сервер запуститollama pull, скачивание занимает несколько минут. - Удалить модель — нажмите кнопку удаления рядом с установленной моделью.
- Список установленных моделей — отображается с размером на диске.
Рекомендуемые модели
| Тип | Модели |
|---|---|
| Эмбеддинги (RAG) | bge-m3, mxbai-embed-large, qwen3-embedding:8b |
| Чат / AI-боты | qwen2.5:3b, qwen2.5:7b |
NVIDIA GPU
Для использования GPU раскомментируйте секцию deploy в сервисе ollama в файле docker-compose.yml и убедитесь, что на хосте установлен NVIDIA Container Toolkit.
Порты
| Сервис | Порт | Описание |
|---|---|---|
| Ollama API | 11434 |
REST API для управления моделями и инференса |
Volumes
| Volume | Данные |
|---|---|
ollama_data |
Скачанные модели Ollama |
Для сброса данных (удаление всех скачанных моделей):
docker compose --profile with-ollama down -v
Генерация VAPID-ключей для веб-пушей
VAPID-ключи используются для web push уведомлений. Без постоянных ключей при каждом перезапуске сервера все push-подписки браузеров становятся невалидными.
Генерация ключей (выполнить один раз):
npx web-push generate-vapid-keys
Команда выведет пару ключей:
Public Key:
BAxxx...
Private Key:
xxx...
Скопируйте значения в переменные окружения VAPID_PUBLIC_KEY и VAPID_PRIVATE_KEY. Если ключи не заданы, сервер выведет предупреждение в лог и сгенерирует временные ключи (только для текущей сессии).
Sequence при старте
Независимо от режима, контейнер приложения всегда:
- Проверяет доступность базы данных (
scripts/check-db.js) - Применяет SQL-миграции из папки
migrations/(npm run db:migrate) - Создаёт MinIO bucket если настроен S3 (автоматически)
- Запускает сервер приложения (
npm run start)
Изменение схемы базы данных
При добавлении новых таблиц или колонок в shared/schema.ts необходимо
создать SQL-файл миграции, который будет применён на всех серверах автоматически.
Шаги
-
Внесите изменения в
shared/schema.ts. -
Сгенерируйте миграцию (создаёт SQL-файл в папке
migrations/):npm run db:generateКоманда создаст файл вида
migrations/0004_<name>.sql. -
Закоммитьте оба файла — изменённый
shared/schema.tsи новый SQL-файл миграции:git add shared/schema.ts migrations/ git commit -m "feat: add <description>" -
При деплое новой версии (
docker compose pull && docker compose up -d)db:migrateавтоматически применит новую миграцию, не затрагивая уже существующие данные.
Важно: SQL-файлы миграций нельзя редактировать после коммита — только добавлять новые. Применённые миграции отслеживаются в таблице
__drizzle_migrationsв самой БД.
Проверка миграций после деплоя
Чтобы убедиться, что все миграции применились корректно, выполните в PostgreSQL:
SELECT * FROM "__drizzle_migrations" ORDER BY created_at;
Ожидаемый результат: строки 0000_baseline, 0001_sync_missing_columns, …, 0007_sync_missing_columns_v2 (плюс все последующие).
Если строки отсутствуют или возникла ошибка — смотрите логи контейнера: docker compose logs app.
Хранение данных (volumes)
| Volume | Данные |
|---|---|
postgres_data |
База данных PostgreSQL |
minio_data |
Файлы (загруженные через iistwin) |
ollama_data |
Скачанные LLM-модели |
Для полного сброса данных:
docker compose --profile with-postgres --profile with-minio --profile with-ollama down -v
Быстрый справочник
| Цель | Команда |
|---|---|
| Только приложение (внешняя БД + диск) | docker compose up --build |
| + встроенная PostgreSQL | docker compose --profile with-postgres up --build |
| + MinIO + WebDAV (без PostgreSQL) | docker compose --profile with-minio up --build |
| + локальные LLM (Ollama) | docker compose --profile with-ollama up --build |
| Всё сразу | docker compose --profile with-postgres --profile with-minio --profile with-ollama up --build |
Бэкапы PostgreSQL (production)
Автоматические (на сервере, cron):
- 3:00 —
pg_dump -Fc | gzip→/opt/crm/backups/crm-YYYYMMDD-HHMMSS.dump.gz(скрипт/opt/crm/scripts/backup-db.sh), ротация 14 дней; - 3:30 — CSV-экспорт основных таблиц →
/opt/crm/backups/csv/YYYYMMDD-HHMMSS/(скрипт/opt/crm/scripts/backup-csv.sh), 7 копий; - логи:
/var/log/crm-backup.log.
RPO/RTO:
- RPO (точка потери данных): до 24 часов (дамп раз в сутки). Для уменьшения — чаще расписание или WAL-архивация (не настроено).
- RTO (время восстановления): ~15–30 минут (остановка app, pg_restore ~11 МБ дампа за минуты, запуск).
Восстановление из дампа:
docker compose stop app document-worker
docker exec crm-db-1 psql -U appuser -d postgres -c 'DROP DATABASE appdb'
docker exec crm-db-1 psql -U appuser -d postgres -c 'CREATE DATABASE appdb'
zcat /opt/crm/backups/crm-<дата>.dump.gz | docker exec -i crm-db-1 pg_restore -U appuser -d appdb --no-owner --no-privileges
docker compose up -d
Проверка восстановления: выполнена 2026-09-07 — дамп за 03:00 восстановлен в scratch-БД без ошибок (125 таблиц, данные консистентны). Повторять такую проверку после изменений схемы бэкапа.
Не входит в pg_dump (бэкапить отдельно):
- файлы MinIO (
minio_data) — tar volume вручную; - модели Ollama (
ollama_data) — tar volume вручную; /app/data(crm_data— JSON-конфиги финансов, google-токены).
Известный риск: бэкапы лежат на том же VPS — при отказе диска/сервера потеряются вместе с продом. Требуется выгрузка наружу (S3/другой хост) — в бэклоге.