# Инструкция по настройке автоматического деплоя на Synology ## Что было сделано ✅ Создан `docker-compose.prod.yml` - production конфигурация для Synology ✅ Обновлен `.gitea/workflows/build-and-push.yml` - добавлен автоматический деплой ✅ Настроена автоматическая раскатка после успешного пуша образа в registry ## Как это работает 1. При пуше в `main` ветку запускается workflow 2. Если версия в `VERSION` изменилась: - Собирается Docker образ - Образ пушится в registry `dungeonsiege.synology.me/poignatov/play-life:latest` - Автоматически выполняется деплой на Synology сервер 3. Деплой включает: - Подключение к серверу по SSH - Логин в registry - Обновление образа (`docker pull`) - Перезапуск контейнера через docker-compose --- ## Шаг 1: Настройка Secrets в Gitea Перейдите в настройки вашего репозитория в Gitea: **Settings → Secrets** Добавьте следующие 3 secrets: | Secret | Значение | Описание | |--------|----------|----------| | `DEPLOY_HOST` | `192.168.50.55` | IP адрес вашего Synology (или `dungeonsiege.synology.me`) | | `DEPLOY_USER` | `poignatov` | Ваш SSH пользователь на Synology (замените на свой) | | `DEPLOY_PASSWORD` | `ваш_пароль` | Пароль от этого пользователя | **Как узнать вашего пользователя:** - Подключитесь к Synology по SSH: `ssh poignatov@192.168.50.55` - Или посмотрите в DSM: **Control Panel → User & Group** **Важно:** Пользователь должен быть в группе `administrators` и иметь доступ к Docker. --- ## Шаг 2: Включение SSH на Synology 1. Откройте **DSM** (веб-интерфейс Synology) 2. Перейдите в **Control Panel → Terminal & SNMP** 3. Включите **Enable SSH service** 4. Порт по умолчанию: `22` (можно оставить как есть) 5. Нажмите **Apply** **Проверка:** ```bash ssh poignatov@192.168.50.55 # Должно запросить пароль и подключиться ``` --- ## Шаг 3: Подготовка сервера ### 3.1. Определить правильный путь и создать директорию **Способ 1: Через File Station (определить путь):** 1. Откройте **File Station** в DSM 2. Создайте папку `play-life` в удобном месте (например, в `docker` или в корне `homes`) 3. **Правый клик** на папке → **Properties** → вкладка **Location** 4. Скопируйте полный путь (например: `/volume1/docker/play-life` или `/volume1/homes/poignatov/docker/play-life`) **Способ 2: Через SSH (определить путь):** ```bash ssh poignatov@192.168.50.55 # Посмотреть доступные volumes ls -la /volume* # Или найти где находятся ваши Docker контейнеры docker inspect dungeonsiege.synology.me-poignatov-play-life1 | grep -i source # Это покажет путь к volume (например: /volume1/docker/play-life/uploads) # Создать директорию (замените путь на правильный!) mkdir -p /volume1/docker/play-life cd /volume1/docker/play-life # Или если путь другой, например: # mkdir -p /volume1/homes/poignatov/docker/play-life # cd /volume1/homes/poignatov/docker/play-life ``` **Проверка пути через существующий контейнер:** Если у вас уже запущен контейнер `dungeonsiege.synology.me-poignatov-play-life1`, можно проверить путь через него: ```bash ssh poignatov@192.168.50.55 docker inspect dungeonsiege.synology.me-poignatov-play-life1 | grep -A 5 "Mounts" ``` Это покажет путь к volume (например: `/volume1/docker/play-life/uploads`), значит базовый путь будет `/volume1/docker/play-life`. **Подтвержденный путь:** `/volume1/docker/play-life` ✅ ### 3.2. Скопировать docker-compose.prod.yml Скопируйте файл `docker-compose.prod.yml` из репозитория на сервер: **Вариант 1: Через веб-интерфейс File Station (рекомендуется):** 1. Откройте **File Station** в DSM 2. Перейдите в папку `docker` → `play-life` (путь: `/volume1/docker/play-life/`) 3. Если папки нет, создайте её: **Create** → **Create Folder** → `play-life` 4. Нажмите **Upload** → **Upload Files** 5. Выберите файл `docker-compose.prod.yml` с вашего компьютера 6. Дождитесь завершения загрузки **Проверка:** Файл должен быть по пути `/volume1/docker/play-life/docker-compose.prod.yml` **Вариант 2: Через SSH с cat (если SCP не работает):** ```bash # На сервере через SSH - создать файл ssh poignatov@192.168.50.55 cd /volume1/docker/play-life cat > docker-compose.prod.yml << 'EOF' # Вставьте сюда содержимое файла, затем нажмите Enter и введите EOF EOF ``` **Вариант 3: Вручную через SSH с nano:** ```bash # На сервере ssh poignatov@192.168.50.55 cd /volume1/docker/play-life nano docker-compose.prod.yml # Вставьте содержимое файла (Ctrl+Shift+V или правый клик) # Сохраните: Ctrl+O, Enter, Ctrl+X ``` **Вариант 4: Через SCP (если настроен):** ```bash # Если SCP не работает, используйте один из вариантов выше scp docker-compose.prod.yml poignatov@192.168.50.55:/volume1/docker/play-life/ ``` **Содержимое файла `docker-compose.prod.yml`:** ```yaml version: '3.8' # Production конфигурация для Synology # Использует образ из registry вместо локальной сборки # База данных postgres запущена отдельно (не в этом compose) services: play-life: image: dungeonsiege.synology.me/poignatov/play-life:latest container_name: play-life-prod ports: - "3080:80" volumes: - /volume1/docker/play-life/uploads:/app/uploads:rw restart: always env_file: - .env # Подключаемся к общей сети playlife-net # Перед первым запуском нужно создать сеть и подключить postgres: # docker network create playlife-net # docker network connect playlife-net postgres1 networks: - playlife-net networks: playlife-net: external: true ``` **Важно:** Оба контейнера (play-life и postgres1) подключены к сети `playlife-net`, что позволяет им находить друг друга по имени. В `.env` файле используйте `DB_HOST=postgres1` (имя контейнера). Это стабильно и не меняется при перезапуске. ### 3.3. Создать общую сеть и подключить postgres Создадим отдельную docker network для связи контейнеров. Это нужно сделать **один раз**: ```bash ssh poignatov@192.168.50.55 # 1. Создать сеть playlife-net docker network create playlife-net # 2. Подключить существующий postgres контейнер к этой сети docker network connect playlife-net postgres1 # 3. Проверить, что postgres подключен к сети docker network inspect playlife-net ``` **Важно:** Postgres остается также подключен к своей старой сети (bridge), так что другие контейнеры, которые его используют, продолжат работать. ### 3.4. Создать .env файл На сервере создайте файл `.env` с переменными окружения: ```bash cd /volume1/docker/play-life nano .env ``` Вставьте следующие переменные (замените значения на свои): ```env DB_NAME=n8n_db DB_HOST=postgres1 DB_PORT=5432 DB_USER=n8n_user DB_PASSWORD=y9CroXzrQdA^RP WEBHOOK_BASE_URL=https://pl-dungeonsiege.duckdns.org TIMEZONE=Europe/Moscow TELEGRAM_BOT_TOKEN=8473129470:AAFeB1CKmhbyH26g_sFz5CgpAit3QFM-wME TODOIST_CLIENT_ID=bf61a1770f004838935816bee3b10ec4 TODOIST_CLIENT_SECRET=25942ae6e4d64054b76aee3aecd259bb JWT_SECRET=BYa757tsSlG2CuGW5PUPpTRgF5iILniEXVXaBDlKfB4= ``` **Важно:** - `DB_HOST=postgres1` - имя контейнера postgres (стабильно, не меняется) - `DB_PORT=5432` - порт внутри контейнера postgres (не путать с внешним портом 5433) - Благодаря сети `playlife-net`, контейнеры могут находить друг друга по имени - Убедитесь, что все остальные значения соответствуют вашему текущему контейнеру Сохраните файл (Ctrl+O, Enter, Ctrl+X). ### 3.4. Проверить права доступа Убедитесь, что пользователь может выполнять docker команды: ```bash docker ps docker-compose --version ``` Если команды не работают, добавьте пользователя в группу `docker`: ```bash sudo synogroup --add docker poignatov # Или через DSM: Control Panel → User & Group → Edit → Groups → docker ``` --- ## Шаг 4: Остановка старого контейнера ### Вариант 1: Через DSM (веб-интерфейс) 1. Откройте **Container Manager** (или **Docker** в старых версиях DSM) 2. Найдите контейнер `dungeonsiege.synology.me-poignatov-play-life1` 3. Остановите его (Stop) 4. Опционально: удалите контейнер (Remove) ### Вариант 2: Через SSH ```bash # Остановить контейнер docker stop dungeonsiege.synology.me-poignatov-play-life1 # Удалить контейнер (опционально) docker rm dungeonsiege.synology.me-poignatov-play-life1 ``` --- ## Шаг 5: Первый запуск через docker-compose На сервере выполните: ```bash cd /volume1/docker/play-life # Проверить конфигурацию docker-compose -f docker-compose.prod.yml config # Запустить контейнер docker-compose -f docker-compose.prod.yml up -d # Проверить статус docker-compose -f docker-compose.prod.yml ps # Посмотреть логи docker-compose -f docker-compose.prod.yml logs -f ``` **Ожидаемый результат:** - Контейнер должен запуститься - Приложение должно быть доступно на `http://192.168.50.55:3080` --- ## Шаг 6: Проверка автоматического деплоя 1. Поднимите версию в файле `VERSION` (например, с `4.8.2` на `4.8.3`) 2. Закоммитьте и запушьте изменения в `main` ветку 3. Workflow автоматически: - Соберет образ - Запушит в registry - Выполнит деплой на сервер 4. Проверьте уведомление в Telegram (если настроено) 5. Проверьте, что контейнер обновился: ```bash ssh poignatov@192.168.50.55 cd /volume1/docker/play-life docker-compose -f docker-compose.prod.yml ps docker images | grep play-life ``` --- ## Устранение проблем ### Проблема: SCP не работает (subsystem request failed) **Ошибка:** ``` subsystem request failed on channel 0 scp: Connection closed ``` **Решение:** Используйте альтернативные способы копирования файлов: 1. **Через File Station** (веб-интерфейс) - самый простой способ 2. **Через SSH с cat/heredoc** - создать файл напрямую на сервере 3. **Через nano** - вручную скопировать содержимое Подробности в разделе "Шаг 3.2" выше. ### Проблема: SSH подключение не работает **Решение:** - Проверьте, что SSH включен в DSM - Проверьте правильность IP адреса и пользователя - Проверьте пароль в secrets Gitea ### Проблема: Docker команды не выполняются **Решение:** ```bash # Добавить пользователя в группу docker sudo synogroup --add docker poignatov # Или через DSM: Control Panel → User & Group → Edit → Groups → docker ``` ### Проблема: Ошибка при логине в registry **Решение:** - Проверьте, что `GIT_TOKEN` и `GIT_USERNAME` secrets настроены в Gitea - Проверьте, что registry доступен с сервера: `docker login dungeonsiege.synology.me` ### Проблема: "lookup postgres1 on ...: no such host" **Ошибка:** ``` Failed to connect to database:dial tcp: lookup postgres1 on 192.168.50.1:53: no such host ``` **Решение:** Это происходит если контейнеры не в одной сети. Проверьте: ```bash # 1. Проверить, что оба контейнера в сети bridge docker network inspect bridge | grep -A 5 "Containers" # 2. Убедиться, что в docker-compose.prod.yml используется networks, а не network_mode cat /volume1/docker/play-life/docker-compose.prod.yml # 3. Пересоздать контейнер с правильной сетью cd /volume1/docker/play-life docker-compose -f docker-compose.prod.yml down docker-compose -f docker-compose.prod.yml up -d # 4. Проверить, что контейнеры могут общаться docker exec play-life-prod ping -c 2 postgres1 ``` ### Проблема: Контейнер не запускается **Решение:** ```bash # Проверить логи docker-compose -f docker-compose.prod.yml logs # Проверить конфигурацию docker-compose -f docker-compose.prod.yml config # Проверить, что postgres контейнер запущен docker ps | grep postgres # Проверить IP адрес postgres docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' postgres1 # Проверить, что контейнер может достучаться до postgres по IP docker exec play-life-prod ping -c 2 ``` ### Проблема: Ошибка "network-scoped alias is supported only for containers in user defined networks" **Ошибка:** ``` ERROR: network-scoped alias is supported only for containers in user defined networks ``` **Решение:** Это происходит при использовании `external_links` с bridge network. Убедитесь, что в `docker-compose.prod.yml` используется `network_mode: bridge` без `external_links` и `networks`. Проверьте содержимое файла - он должен быть как в разделе 3.2 выше. ### Проблема: Образ не обновляется **Решение:** ```bash # Вручную обновить образ cd /volume1/docker/play-life docker pull dungeonsiege.synology.me/poignatov/play-life:latest docker-compose -f docker-compose.prod.yml up -d --force-recreate ``` --- ## Полезные команды ### Просмотр логов ```bash cd /volume1/docker/play-life docker-compose -f docker-compose.prod.yml logs -f ``` ### Перезапуск контейнера ```bash cd /volume1/docker/play-life docker-compose -f docker-compose.prod.yml restart ``` ### Остановка контейнера ```bash cd /volume1/docker/play-life docker-compose -f docker-compose.prod.yml down ``` ### Обновление образа вручную ```bash cd /volume1/docker/play-life docker pull dungeonsiege.synology.me/poignatov/play-life:latest docker-compose -f docker-compose.prod.yml up -d --force-recreate ``` --- ## Безопасность - ✅ Пароль хранится в secrets Gitea, не в коде - ✅ `.env` файл с секретами хранится только на сервере - ✅ Используется существующий `GIT_TOKEN` для логина в registry - ⚠️ Рекомендуется использовать SSH ключи вместо пароля (можно настроить позже) --- ## Что дальше? После настройки автоматический деплой будет работать при каждом изменении версии. Просто: 1. Поднимите версию в `VERSION` 2. Закоммитьте и запушьте изменения 3. Деплой выполнится автоматически! 🚀 --- **Вопросы?** Проверьте логи workflow в Gitea: **Actions → Build and Push Docker Image**