18 KiB
Инструкция по настройке автоматического деплоя на Synology
Что было сделано
✅ Создан docker-compose.prod.yml - production конфигурация для Synology
✅ Обновлен .gitea/workflows/build-and-push.yml - добавлен автоматический деплой
✅ Настроена автоматическая раскатка после успешного пуша образа в registry
Как это работает
- При пуше в
mainветку запускается workflow - Если версия в
VERSIONизменилась:- Собирается Docker образ
- Образ пушится в registry
dungeonsiege.synology.me/poignatov/play-life:latest - Автоматически выполняется деплой на Synology сервер
- Деплой включает:
- Подключение к серверу по 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
- Откройте DSM (веб-интерфейс Synology)
- Перейдите в Control Panel → Terminal & SNMP
- Включите Enable SSH service
- Порт по умолчанию:
22(можно оставить как есть) - Нажмите Apply
Проверка:
ssh poignatov@192.168.50.55
# Должно запросить пароль и подключиться
Шаг 3: Подготовка сервера
3.1. Определить правильный путь и создать директорию
Способ 1: Через File Station (определить путь):
- Откройте File Station в DSM
- Создайте папку
play-lifeв удобном месте (например, вdockerили в корнеhomes) - Правый клик на папке → Properties → вкладка Location
- Скопируйте полный путь (например:
/volume1/docker/play-lifeили/volume1/homes/poignatov/docker/play-life)
Способ 2: Через SSH (определить путь):
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, можно проверить путь через него:
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 (рекомендуется):
- Откройте File Station в DSM
- Перейдите в папку
docker→play-life(путь:/volume1/docker/play-life/) - Если папки нет, создайте её: Create → Create Folder →
play-life - Нажмите Upload → Upload Files
- Выберите файл
docker-compose.prod.ymlс вашего компьютера - Дождитесь завершения загрузки
Проверка: Файл должен быть по пути /volume1/docker/play-life/docker-compose.prod.yml
Вариант 2: Через SSH с cat (если SCP не работает):
# На сервере через SSH - создать файл
ssh poignatov@192.168.50.55
cd /volume1/docker/play-life
cat > docker-compose.prod.yml << 'EOF'
# Вставьте сюда содержимое файла, затем нажмите Enter и введите EOF
EOF
Вариант 3: Вручную через SSH с nano:
# На сервере
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 (если настроен):
# Если SCP не работает, используйте один из вариантов выше
scp docker-compose.prod.yml poignatov@192.168.50.55:/volume1/docker/play-life/
Содержимое файла docker-compose.prod.yml:
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 для связи контейнеров. Это нужно сделать один раз:
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 с переменными окружения:
cd /volume1/docker/play-life
nano .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 команды:
docker ps
docker-compose --version
Если команды не работают, добавьте пользователя в группу docker:
sudo synogroup --add docker poignatov
# Или через DSM: Control Panel → User & Group → Edit → Groups → docker
Шаг 4: Остановка старого контейнера
Вариант 1: Через DSM (веб-интерфейс)
- Откройте Container Manager (или Docker в старых версиях DSM)
- Найдите контейнер
dungeonsiege.synology.me-poignatov-play-life1 - Остановите его (Stop)
- Опционально: удалите контейнер (Remove)
Вариант 2: Через SSH
# Остановить контейнер
docker stop dungeonsiege.synology.me-poignatov-play-life1
# Удалить контейнер (опционально)
docker rm dungeonsiege.synology.me-poignatov-play-life1
Шаг 5: Первый запуск через docker-compose
На сервере выполните:
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: Проверка автоматического деплоя
- Поднимите версию в файле
VERSION(например, с4.8.2на4.8.3) - Закоммитьте и запушьте изменения в
mainветку - Workflow автоматически:
- Соберет образ
- Запушит в registry
- Выполнит деплой на сервер
- Проверьте уведомление в Telegram (если настроено)
- Проверьте, что контейнер обновился:
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
Решение: Используйте альтернативные способы копирования файлов:
- Через File Station (веб-интерфейс) - самый простой способ
- Через SSH с cat/heredoc - создать файл напрямую на сервере
- Через nano - вручную скопировать содержимое
Подробности в разделе "Шаг 3.2" выше.
Проблема: SSH подключение не работает
Решение:
- Проверьте, что SSH включен в DSM
- Проверьте правильность IP адреса и пользователя
- Проверьте пароль в secrets Gitea
Проблема: Docker команды не выполняются
Решение:
# Добавить пользователя в группу docker
sudo synogroup --add docker poignatov
# Или через DSM: Control Panel → User & Group → Edit → Groups → docker
Проблема: Ошибка при логине в registry
Решение:
- Проверьте, что
GIT_TOKENиGIT_USERNAMEsecrets настроены в 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
Решение: Это происходит если контейнеры не в одной сети. Проверьте:
# 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
Проблема: Контейнер не запускается
Решение:
# Проверить логи
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 <IP_адрес_postgres>
Проблема: Ошибка "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 выше.
Проблема: Образ не обновляется
Решение:
# Вручную обновить образ
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
Полезные команды
Просмотр логов
cd /volume1/docker/play-life
docker-compose -f docker-compose.prod.yml logs -f
Перезапуск контейнера
cd /volume1/docker/play-life
docker-compose -f docker-compose.prod.yml restart
Остановка контейнера
cd /volume1/docker/play-life
docker-compose -f docker-compose.prod.yml down
Обновление образа вручную
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 ключи вместо пароля (можно настроить позже)
Что дальше?
После настройки автоматический деплой будет работать при каждом изменении версии. Просто:
- Поднимите версию в
VERSION - Закоммитьте и запушьте изменения
- Деплой выполнится автоматически! 🚀
Вопросы? Проверьте логи workflow в Gitea: Actions → Build and Push Docker Image