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

475 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Инструкция по настройке автоматического деплоя на 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 <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 выше.
### Проблема: Образ не обновляется
**Решение:**
```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**