8.1 KiB
Дополнение к ТЗ: Инфраструктура, CI/CD и развертывание
1. Архитектура развертывания
Развертывание системы осуществляется в контейнеризованной среде с использованием Docker Compose. Это обеспечивает простоту управления зависимостями (БД, кэш) и изоляцию компонентов приложения.
1.1 Компоненты Docker Compose
Среда развертывания включает следующие сервисы:
- API Service (Go) — основной HTTP-сервер.
- Cron Service (Go) — фоновые задачи (обновление справочников, проверка статуса). Может быть объединен с API в один бинарник/контейнер, если используется встроенный планировщик, но рекомендуется запускать отдельным процессом.
- PostgreSQL — база данных со справочниками и маршрутами (используется официальный образ, данные хранятся в Docker Volumes).
- Redis — кэш-слой для API Яндекс.Расписаний.
- 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 и включает следующие шаги:
- Checkout: Клонирование актуального кода из ветки
master. - Setup Go: Установка необходимой версии Go и настройка кэширования модулей (
go mod download). - Lint & Test:
- Запуск линтеров (например,
golangci-lint) для проверки качества кода. - Запуск unit-тестов (
go test -v ./...), включая тесты графа маршрутизации с моками вместо реального API.
- Запуск линтеров (например,
- Build Binaries: Компиляция исполняемых файлов для Linux/amd64 (API и Cron).
- Docker Build & Push:
- Сборка Docker-образа приложения на основе
Dockerfile(рекомендуется multi-stage сборка для уменьшения веса финального образа). - Авторизация в приватном или публичном Docker Registry.
- Пуш собранного образа с тегами
latestи{{.CommitID}}.
- Сборка Docker-образа приложения на основе
2.2 Схема автоматического деплоя (CD)
- Разработчик делает
git push origin master. - Gitea Actions успешно прогоняет тесты и пушит образ
my-registry.com/travel-api:latest. - На production-сервере
nickfedor/watchtowerзамечает обновление образа. - Watchtower выполняет pull нового образа и перезапускает сервисы приложения без ручного вмешательства.
3. Примеры конфигурации
3.1 Пример docker-compose.yml (Production)
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)
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. Рекомендации по безопасности и отказоустойчивости
- Секреты: Ключи API Яндекс.Расписаний, пароли от БД и доступы к Registry не должны храниться в коде. В Gitea Actions они зашиваются через механизм Secrets, а в Docker Compose — через файл
.envна сервере. - Откаты (Rollback): Если новая версия
latestломает production, откатить версию можно путем изменения тега вdocker-compose.ymlна предыдущий успешный коммит-хэш (например,image: my-registry.com/travel-api:a1b2c3d) и ручного перезапуска, либо через revert коммита вmaster(что триггернет Gitea Actions на сборку "исправленного"latest). - Downtime: При базовой настройке Watchtower будет небольшой даунтайм в несколько секунд во время перезапуска контейнера. Для MVP/версии 1.0 это приемлемо. Для zero-downtime в будущем потребуется переход на Docker Swarm / Kubernetes или поднятие прокси (nginx/traefik) с health-чеками и blue/green деплоем.