mnemo_cards/docs/coolify-migration.md

137 lines
5.6 KiB
Markdown
Raw Permalink Normal View History

# Coolify: перенос сервисов (backend Docker, web статик, внешняя БД)
Цель: перенести существующие сервисы в Coolify (через Traefik/Lets Encrypt), сохранив БД на хосте. Ниже — пошаговая инструкция, Dockerfile-примеры, настройки Coolify и порядок переключения трафика.
## 1. Backend (Dart) в Docker
### Структура образа
- Base (builder): `dart:stable-sdk`
- Runtime: `debian:bookworm-slim` (или distroless)
- Порт: `8081`
- Health: `GET /health` (замените, если другой endpoint)
### Пример Dockerfile
```
# stage: build
FROM dart:stable-sdk AS builder
WORKDIR /app
COPY pubspec.* ./
RUN dart pub get
COPY . .
RUN dart compile exe lib/main.dart -o /app/server
# stage: runtime
FROM debian:bookworm-slim
WORKDIR /app
COPY --from=builder /app/server /app/server
EXPOSE 8081
CMD ["/app/server", "-a", "0.0.0.0", "-p", "8081"]
```
### Env для внешней БД (БД остаётся на хосте)
- `DB_HOST` — IP хоста (обычно `172.17.0.1` или реальный публичный/приватный IP)
- `DB_PORT` — порт вашей БД
- `DB_NAME`, `DB_USER`, `DB_PASSWORD`
- Если нужен TLS к БД: добавить флаги клиента/сертификаты
### Настройка сети/Traefik
- В сервисе (compose) добавить:
```
networks:
- coolify
extra_hosts:
- "host.docker.internal:host-gateway"
```
- Traefik (через Coolify UI → Domains):
- Domain: `api.mnemo-cards.online`
- EntryPoints: `websecure`
- Cert resolver: `le`
- HTTP→HTTPS редирект уже есть через middleware redirectscheme
### Шаги в Coolify (UI)
1. Project → Environment → New Service → Dockerfile.
2. Указать репозиторий/ветку и путь к Dockerfile.
3. Env: `DB_HOST`, `DB_PORT`, `DB_NAME`, `DB_USER`, `DB_PASSWORD` (+ ваши APP_*).
4. Network: подключить `coolify`.
5. Domains: `api.mnemo-cards.online`, entrypoint `websecure`, resolver `le`.
6. Healthcheck: HTTP 200 на `/health` (или ваш путь).
## 2. Web и Admin (Flutter Web) как статика в контейнере
### Сборка
```
flutter build web --release \
--dart-define=API_BASE_URL=https://api.mnemo-cards.online
```
Артефакт: `build/web/`.
### Пример Dockerfile (nginx)
```
FROM nginx:1.27-alpine
COPY build/web/ /usr/share/nginx/html/
RUN rm /etc/nginx/conf.d/default.conf
COPY default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
```
`default.conf`:
```
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /assets/ {
try_files $uri =404;
add_header Cache-Control "public, max-age=31536000, immutable";
}
}
```
### Разделение сервисов
- Web: домен `mnemo-cards.online`
- Admin: домен `admin.mnemo-cards.online`
Рекомендуется два сервиса в Coolify (два образа или один образ + разные домены).
### Шаги в Coolify
1. New Service → Dockerfile/Image (web).
2. Network: `coolify`.
3. Domains:
- web: `mnemo-cards.online` → entrypoint `websecure`, resolver `le`.
- admin: `admin.mnemo-cards.online` (отдельный сервис либо второй домен).
4. Healthcheck: HEAD `/` (200/301/302).
## 3. Traefik/LE (уже поднят)
- Порты 80/443 заняты Traefik.
- Все сервисы должны быть в сети `coolify`.
- Для каждого домена в Coolify задать entrypoint `websecure` и resolver `le`; HTTP→HTTPS редирект активен.
## 4. Порядок миграции/катовера
1) Собрать и запушить образы:
- backend (Dart) → registry.
- web/admin статика → отдельные образы.
2) Создать сервисы в Coolify (backend, web, admin) c env и доменами.
3) Протестировать:
- Временно через hosts или временный домен (Coolify supports additional domain).
- Проверить доступ к БД из контейнера (psql/curl).
4) Подключить боевые домены:
- `api.mnemo-cards.online`, `mnemo-cards.online`, `admin.mnemo-cards.online`.
5) Переключить трафик:
- Остановить legacy systemd backend и nginx, когда новые сервисы отвечают.
6) Мониторинг/откат:
- При проблемах: стартануть старый systemd/nginx (бэкап конфигов: `/root/pre-coolify-backup-2025-12-07.tar.gz`).
## 5. Проверки после миграции
- HTTPS: `curl -I https://api.mnemo-cards.online`, `https://mnemo-cards.online`, `https://admin.mnemo-cards.online` → 200/301/302, валидный LE.
- Health: все сервисы green в Coolify; backend `/health` 200.
- БД: приложение читает/пишет (прогнать базовый сценарий).
- Логи: нет ошибок подключения к БД/Redis.
- Сеть: наружу открыты только 80/443 (Traefik); внутренние порты не публиковать.
## 6. Что остаётся на хосте
- База данных остаётся на сервере; контейнеры подключаются как к внешнему ресурсу (`DB_HOST` = IP хоста).
- Traefik/LE уже работают в Docker, используется resolver `le`.