# Coolify: перенос сервисов (backend Docker, web статик, внешняя БД) Цель: перенести существующие сервисы в Coolify (через Traefik/Let’s 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`.