100 lines
4.7 KiB
Markdown
100 lines
4.7 KiB
Markdown
# Развёртывание через Docker (на хосте)
|
||
|
||
Альтернативный способ запуска для локального стека и портируемого деплоя.
|
||
На боевой VM Flatlogic **Docker не используется** — там PM2 + локальный PostgreSQL
|
||
+ Cloudflare tunnel (см. [`deployment-vm.md`](./deployment-vm.md)).
|
||
|
||
Проект состоит из двух приложений:
|
||
|
||
- `frontend/` — Vite + React + TypeScript (SPA). Сборка → `frontend/dist/`.
|
||
- `backend/` — Express + Sequelize на TypeScript/ESM. Сборка → `backend/dist/`.
|
||
|
||
## Файлы
|
||
|
||
В корне репозитория:
|
||
|
||
| Файл | Назначение | Порт |
|
||
|---|---|---|
|
||
| `Dockerfile` | прод single-image: компилированный бэк отдаёт API **и** SPA (из `public`) | 8080 |
|
||
| `Dockerfile.dev` | staging-реплика VM: nginx + фронт `vite preview` (3001) + бэк (3000), `dev_stage` | 8080 |
|
||
| `docker/docker-compose.yml` | локальный стек: PostgreSQL + app (из `Dockerfile`), `NODE_ENV=development` | 8080 |
|
||
|
||
Все стейджи на `node:24-alpine`, `npm ci`. Нативный `bcrypt` собирается тулчейном
|
||
(`python3 make g++`) в builder-стейдже, в рантайм копируется готовый `node_modules`
|
||
(без перекомпиляции). `rolldown` (бандлер Vite) имеет musl-биндинги, поэтому alpine
|
||
подходит.
|
||
|
||
## 1. Быстрый старт — docker compose (рекомендуется)
|
||
|
||
Поднимает PostgreSQL + приложение одной командой. Бэкенд в `development` отдаёт API
|
||
и SPA на одном порту (логин работает по http).
|
||
|
||
```bash
|
||
cd docker
|
||
docker compose up --build
|
||
# открыть http://localhost:8080
|
||
```
|
||
|
||
Параметры (env заданы в `docker-compose.yml`, меняйте под себя):
|
||
|
||
- `SECRET_KEY=local_dev_secret_change_me`
|
||
- `DB_*` указывают на сервис `db` (Postgres 16, БД/пользователь `app_local`)
|
||
- `SEED_ADMIN_EMAIL`, `SEED_ADMIN_PASSWORD`, `SEED_USER_PASSWORD`
|
||
|
||
Остановить и удалить (вместе с данными БД):
|
||
|
||
```bash
|
||
docker compose down -v
|
||
```
|
||
|
||
## 2. Прод single-image (`Dockerfile`)
|
||
|
||
Один контейнер: компилированный бэкенд на `NODE_ENV=production` слушает 8080 и
|
||
отдаёт и `/api`, и собранный SPA (фронт кладётся в `public`).
|
||
|
||
```bash
|
||
docker build -t schoolchain:prod .
|
||
|
||
docker run --rm -p 8080:8080 \
|
||
-e NODE_ENV=production \
|
||
-e PORT=8080 \
|
||
-e SECRET_KEY=<секрет> \
|
||
-e ALLOWED_ORIGINS=https://<ваш-домен> \
|
||
-e DB_HOST=<host> -e DB_PORT=5432 -e DB_NAME=<db> -e DB_USER=<user> -e DB_PASS=<pass> \
|
||
-e SEED_ADMIN_EMAIL=<email> -e SEED_ADMIN_PASSWORD=<pass> -e SEED_USER_PASSWORD=<pass> \
|
||
schoolchain:prod
|
||
```
|
||
|
||
> В `NODE_ENV=production` обязательны `SECRET_KEY` и `ALLOWED_ORIGINS`, а cookie
|
||
> идут с флагом `Secure` (нужен HTTPS-фронт перед контейнером). Команда запуска
|
||
> (`npm run start:production`) сама прогоняет миграции и сидеры перед стартом —
|
||
> БД должна быть доступна.
|
||
|
||
## 3. Staging-реплика VM (`Dockerfile.dev`)
|
||
|
||
Повторяет схему VM в одном образе: nginx (8080) → фронт `vite preview` (3001) + бэк
|
||
(3000), `NODE_ENV=dev_stage`, source maps. Запускать за HTTPS (в `dev_stage`
|
||
cookie — `Secure`).
|
||
|
||
```bash
|
||
docker build -t schoolchain:staging -f Dockerfile.dev .
|
||
docker run --rm -p 8080:8080 \
|
||
-e SECRET_KEY=<секрет> \
|
||
-e DB_HOST=<host> -e DB_PORT=5432 -e DB_NAME=<db> -e DB_USER=<user> -e DB_PASS=<pass> \
|
||
-e SEED_ADMIN_EMAIL=<email> -e SEED_ADMIN_PASSWORD=<pass> -e SEED_USER_PASSWORD=<pass> \
|
||
schoolchain:staging
|
||
```
|
||
|
||
## 4. `.dockerignore`
|
||
|
||
Исключает `node_modules`, `dist`, `public`, `**/.env` (чтобы не запекать dev-секреты
|
||
в образ — окружение задаётся при запуске), `.git`, логи.
|
||
|
||
## 5. NODE_ENV — что выбрать
|
||
|
||
| `NODE_ENV` | Где | Особенности |
|
||
|---|---|---|
|
||
| `development` | локальный `docker compose` | http-логин работает; нет требований к `ALLOWED_ORIGINS`; cookie без `Secure` |
|
||
| `dev_stage` | `Dockerfile.dev` (staging) | прод-подобный, но мягкий; нужен HTTPS (`Secure` cookie); рефлектит origin |
|
||
| `production` | `Dockerfile` (прод) | обязательны `SECRET_KEY` + `ALLOWED_ORIGINS`; `Secure` cookie; строгий CORS |
|