Initial docs
This commit is contained in:
157
docs/deployment.md
Normal file
157
docs/deployment.md
Normal file
@@ -0,0 +1,157 @@
|
||||
# Дополнение к ТЗ: Инфраструктура, 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 деплоем.
|
||||
Reference in New Issue
Block a user