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

8.1 KiB
Raw Permalink Blame History

Дополнение к ТЗ: Инфраструктура, 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)

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. Рекомендации по безопасности и отказоустойчивости

  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 деплоем.