Files
trip-planner/docs/deployment.md
2026-08-13 18:26:15 +03:00

158 lines
8.1 KiB
Markdown
Raw Permalink 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.
# Дополнение к ТЗ: Инфраструктура, CI/CD и развертывание
---
## 1. Архитектура развертывания
Развертывание системы осуществляется в контейнеризованной среде с использованием **Docker Compose**. Это обеспечивает простоту управления зависимостями (БД, кэш) и изоляцию компонентов приложения.
### 1.1 Компоненты Docker Compose
Среда развертывания включает следующие сервисы:
1. **API Service (Go)** — основной HTTP-сервер.
2. **Cron Service (Go)** — фоновые задачи (обновление справочников, проверка статуса). *Может быть объединен с API в один бинарник/контейнер, если используется встроенный планировщик, но рекомендуется запускать отдельным процессом.*
3. **PostgreSQL** — база данных со справочниками и маршрутами (используется официальный образ, данные хранятся в Docker Volumes).
4. **Redis** — кэш-слой для API Яндекс.Расписаний.
5. **Watchtower** — сервис для автоматического обновления контейнеров.
### 1.2 Использование Watchtower
Для реализации автоматического деплоя (CD) на сервере разворачивается образ `nickfedor/watchtower`.
Он регулярно опрашивает Docker Registry (или ожидает webhook) и, при появлении нового образа приложения с тегом `latest` (или другим заданным), автоматически скачивает его, корректно останавливает старый контейнер и запускает новый с теми же параметрами окружения.
---
## 2. Процесс CI/CD (Gitea Actions)
Весь процесс непрерывной интеграции и доставки управляется встроенным механизмом **Gitea Actions** и запускается автоматически при любом `push` в ветку `master`.
### 2.1 Этапы пайплайна (Pipeline Steps)
Пайплайн описывается в файле `.gitea/workflows/deploy.yml` и включает следующие шаги:
1. **Checkout**: Клонирование актуального кода из ветки `master`.
2. **Setup Go**: Установка необходимой версии Go и настройка кэширования модулей (`go mod download`).
3. **Lint & Test**:
- Запуск линтеров (например, `golangci-lint`) для проверки качества кода.
- Запуск unit-тестов (`go test -v ./...`), включая тесты графа маршрутизации с моками вместо реального API.
4. **Build Binaries**: Компиляция исполняемых файлов для Linux/amd64 (API и Cron).
5. **Docker Build & Push**:
- Сборка Docker-образа приложения на основе `Dockerfile` (рекомендуется multi-stage сборка для уменьшения веса финального образа).
- Авторизация в приватном или публичном Docker Registry.
- Пуш собранного образа с тегами `latest` и `{{.CommitID}}`.
### 2.2 Схема автоматического деплоя (CD)
1. Разработчик делает `git push origin master`.
2. Gitea Actions успешно прогоняет тесты и пушит образ `my-registry.com/travel-api:latest`.
3. На production-сервере `nickfedor/watchtower` замечает обновление образа.
4. Watchtower выполняет pull нового образа и перезапускает сервисы приложения без ручного вмешательства.
---
## 3. Примеры конфигурации
### 3.1 Пример `docker-compose.yml` (Production)
```yaml
version: '3.8'
services:
travel-api:
image: my-registry.com/travel-api:latest
restart: always
ports:
- "8080:8080"
environment:
- DB_DSN=postgres://user:pass@db:5432/travel?sslmode=disable
- REDIS_ADDR=redis:6379
- YANDEX_API_KEY=${YANDEX_API_KEY}
depends_on:
- db
- redis
db:
image: postgres:15-alpine
restart: always
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=travel
volumes:
- pg_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
restart: always
volumes:
- redis_data:/data
watchtower:
image: nickfedor/watchtower
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# Если используется приватный реестр, прокидываем авторизацию:
# - /root/.docker/config.json:/config.json:ro
command: --interval 60 --cleanup travel-api
# Обновляем только контейнер travel-api, проверяя изменения каждые 60 секунд (или по крону)
volumes:
pg_data:
redis_data:
```
### 3.2 Пример Gitea Actions (`.gitea/workflows/deploy.yml`)
```yaml
name: Build, Test and Publish
on:
push:
branches:
- master
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.22'
- name: Go Modules Cache
uses: actions/cache@v3
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Run Tests
run: go test -v -race ./...
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Docker Registry
uses: docker/login-action@v2
with:
registry: my-registry.com
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and Push Docker Image
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: my-registry.com/travel-api:latest,my-registry.com/travel-api:${{ gitea.sha }}
```
## 4. Рекомендации по безопасности и отказоустойчивости
1. **Секреты:** Ключи API Яндекс.Расписаний, пароли от БД и доступы к Registry не должны храниться в коде. В Gitea Actions они зашиваются через механизм *Secrets*, а в Docker Compose — через файл `.env` на сервере.
2. **Откаты (Rollback):** Если новая версия `latest` ломает production, откатить версию можно путем изменения тега в `docker-compose.yml` на предыдущий успешный коммит-хэш (например, `image: my-registry.com/travel-api:a1b2c3d`) и ручного перезапуска, либо через revert коммита в `master` (что триггернет Gitea Actions на сборку "исправленного" `latest`).
3. **Downtime:** При базовой настройке Watchtower будет небольшой даунтайм в несколько секунд во время перезапуска контейнера. Для MVP/версии 1.0 это приемлемо. Для zero-downtime в будущем потребуется переход на Docker Swarm / Kubernetes или поднятие прокси (nginx/traefik) с health-чеками и blue/green деплоем.