Files
play-life/DEPLOY_SETUP.md
poignatov f7d340fc70
Some checks are pending
Build and Push Docker Image / build-and-push (push) Has started running
4.8.3: Автодеплой на Synology
2026-02-02 20:42:26 +03:00

18 KiB
Raw Blame History

Инструкция по настройке автоматического деплоя на 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

Проверка:

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 (определить путь):

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 (рекомендуется):

  1. Откройте File Station в DSM
  2. Перейдите в папку dockerplay-life (путь: /volume1/docker/play-life/)
  3. Если папки нет, создайте её: CreateCreate Folderplay-life
  4. Нажмите UploadUpload Files
  5. Выберите файл docker-compose.prod.yml с вашего компьютера
  6. Дождитесь завершения загрузки

Проверка: Файл должен быть по пути /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 (веб-интерфейс)

  1. Откройте Container Manager (или Docker в старых версиях DSM)
  2. Найдите контейнер dungeonsiege.synology.me-poignatov-play-life1
  3. Остановите его (Stop)
  4. Опционально: удалите контейнер (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: Проверка автоматического деплоя

  1. Поднимите версию в файле VERSION (например, с 4.8.2 на 4.8.3)
  2. Закоммитьте и запушьте изменения в main ветку
  3. Workflow автоматически:
    • Соберет образ
    • Запушит в registry
    • Выполнит деплой на сервер
  4. Проверьте уведомление в Telegram (если настроено)
  5. Проверьте, что контейнер обновился:
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 команды не выполняются

Решение:

# Добавить пользователя в группу 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

Решение: Это происходит если контейнеры не в одной сети. Проверьте:

# 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 ключи вместо пароля (можно настроить позже)

Что дальше?

После настройки автоматический деплой будет работать при каждом изменении версии. Просто:

  1. Поднимите версию в VERSION
  2. Закоммитьте и запушьте изменения
  3. Деплой выполнится автоматически! 🚀

Вопросы? Проверьте логи workflow в Gitea: Actions → Build and Push Docker Image