Как настроить CI/CD пайплайн с GitHub Actions и Docker: пошаговое руководство 2026

Как настроить CI/CD пайплайн с GitHub Actions и Docker: пошаговое руководство 2026

Представь: ты коммитишь код, а через 5 минут он уже работает на production-сервере. Без ручного копирования файлов, без «магии» на сервере и без ночных деплоев в 3 часа ночи. Звучит как мечта? В 2026 году это стандарт для любой уважающей себя команды DevOps.

CI/CD пайплайн — это не просто модный термин, а фундамент современной разработки. GitHub Actions и Docker стали идеальной парой для автоматизации: первый управляет процессом, второй гарантирует, что окружение одинаково на всех этапах. В этом гайде я покажу, как собрать production-ready пайплайн с нуля, используя реальные конфиги и лучшие практики 2026 года.

Почему GitHub Actions и Docker — лучшая связка в 2026?

Давайте сразу к делу. GitHub Actions — это встроенный CI/CD-инструмент в GitHub, который не требует отдельной инфраструктуры. Docker — стандарт контейнеризации. Вместе они решают главную проблему DevOps: «На моей машине работает».

Вот что вы получаете:
- Единый раннер — GitHub предоставляет бесплатные раннеры (Linux, Windows, macOS) с предустановленным Docker.
- Масштабирование — можно запускать параллельные джобы для тестов на разных версиях.
- Кэширование — образы Docker кэшируются, ускоряя сборку на 40-60%.
- Безопасность — секреты хранятся в GitHub Secrets, а не в коде.

Архитектура пайплайна: что будет в статье

Мы построим пайплайн для типового веб-приложения (например, Node.js или Python Flask), который:
1. Автоматически запускается при пуше в ветку main.
2. Собирает Docker-образ.
3. Прогоняет тесты внутри контейнера.
4. Пушит образ в Docker Hub (или GitHub Container Registry).
5. Деплоит на сервер через SSH.

Весь код — YAML. Никакого лишнего софта.

Шаг 1. Подготовка репозитория и секретов

Первое, что нужно сделать — настроить безопасность. Никогда не храните пароли и токены в коде. Используйте GitHub Secrets.

Что понадобится:
- DOCKER_USERNAME и DOCKER_PASSWORD — для пуша образа в Docker Hub.
- SSH_PRIVATE_KEY — для деплоя на сервер.
- SERVER_HOST и SERVER_USER — адрес и пользователь сервера.

Как добавить: Settings → Secrets and variables → Actions → New repository secret.

Шаг 2. Базовый workflow-файл

Создайте в корне репозитория файл .github/workflows/deploy.yml. Это сердце пайплайна.

name: CI/CD Pipeline

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run tests
        run: |
          docker build -t myapp:test .
          docker run myapp:test npm test

  build-and-push:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Log in to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          push: true
          tags: ${{ secrets.DOCKER_USERNAME }}/myapp:latest

  deploy:
    needs: build-and-push
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to server
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            docker pull ${{ secrets.DOCKER_USERNAME }}/myapp:latest
            docker stop myapp || true
            docker rm myapp || true
            docker run -d --name myapp -p 80:3000 ${{ secrets.DOCKER_USERNAME }}/myapp:latest

Комментарий эксперта:
- needs — гарантирует последовательность: сначала тесты, потом сборка, потом деплой.
- appleboy/ssh-action — популярный action для SSH-команд. Альтернатива — self-hosted runner.
- || true — игнорирует ошибку, если контейнер не существует.

Шаг 3. Dockerfile для production

Ваш Dockerfile должен быть лёгким и безопасным. Вот пример для Node.js приложения:

FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app .
EXPOSE 3000
CMD ["node", "server.js"]

Почему multi-stage?
- Уменьшает размер образа в 3-4 раза.
- Не включает инструменты сборки (npm, git) в финальный образ.
- Меньше поверхность для атак.

Шаг 4. Оптимизация кэширования Docker

Каждый запуск пайплайна — это деньги и время. Кэширование слоёв Docker ускоряет сборку на 50-70%.

Добавьте в build-and-push:

- name: Set up Docker Buildx
  uses: docker/setup-buildx-action@v3
- name: Build and push with cache
  uses: docker/build-push-action@v5
  with:
    push: true
    tags: ${{ secrets.DOCKER_USERNAME }}/myapp:latest
    cache-from: type=gha
    cache-to: type=gha,mode=max

type=gha использует GitHub Actions cache. Бесплатно и эффективно.

Шаг 5. Тестирование в контейнере

Тесты должны запускаться в изолированном окружении, идентичном production. Используйте docker-compose для интеграционных тестов с БД.

Пример .github/workflows/test.yml:

name: Integration Tests
on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_PASSWORD: testpass
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
    steps:
      - uses: actions/checkout@v4
      - name: Run tests
        run: |
          docker build -t myapp .
          docker run --network host -e DATABASE_URL=postgres://postgres:testpass@localhost:5432/test myapp npm test

Важно: Сервисы (PostgreSQL, Redis) запускаются как отдельные контейнеры, доступные по localhost. Это быстрее, чем docker-compose.

Шаг 6. Деплой на AWS EC2 (альтернатива SSH)

Если ваш сервер — AWS EC2, можно использовать aws-actions/amazon-ecs-deploy-task-definition для деплоя в ECS. Но для простоты оставим SSH.

Для production-деплоя рекомендую добавить Health Check:

script: |
  docker pull ...
  docker run -d --name myapp_new ...
  sleep 10
  curl -f http://localhost:3000/health || exit 1
  docker stop myapp && docker rm myapp
  docker rename myapp_new myapp

Это стратегия blue-green deployment на минималках: новый контейнер запускается параллельно, проверяется, и только потом старый удаляется.

Шаг 7. Мониторинг пайплайна

GitHub Actions показывает статус в интерфейсе, но для серьёзных проектов нужно больше:
- Slack-уведомления — action slackapi/slack-github-action.
- Метрики — экспортируйте время сборки и частоту деплоев в Prometheus.
- Логи — все шаги логируются, но для аудита можно добавить actions/upload-artifact для сохранения логов тестов.

Пример: полный пайплайн для Python (Flask)

Для разнообразия — пример для Python с pytest и flake8:

name: Python CI/CD

on: [push]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Lint
        run: |
          docker build --target lint -t myapp:lint .
          docker run myapp:lint flake8

  test:
    needs: lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Test
        run: |
          docker build --target test -t myapp:test .
          docker run myapp:test pytest

  build:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      - run: |
          docker build -t myapp:prod --target prod .
          docker tag myapp:prod ${{ secrets.DOCKER_USERNAME }}/flask-app:latest
          docker push ${{ secrets.DOCKER_USERNAME }}/flask-app:latest

Dockerfile с таргетами:

FROM python:3.12-slim AS base
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt

FROM base AS lint
RUN pip install flake8
COPY . .

FROM base AS test
RUN pip install pytest
COPY . .

FROM base AS prod
COPY . .
CMD ["gunicorn", "app:app"]

Типичные ошибки и как их избежать

Ошибка Решение
Секреты в коде Всегда используйте GitHub Secrets. Никогда не хардкодьте.
Большие образы Docker Multi-stage сборка + Alpine.
Отсутствие кэша Используйте cache-from и cache-to.
Деплой без проверки Добавьте Health Check и rollback.
Раннеры зависают Установите таймаут: timeout-minutes: 10.

Что дальше? Продвинутые техники

Когда базовый пайплайн работает, можно добавить:
- Matrix builds — тестирование на нескольких версиях Node/Python.
- Self-hosted runners — для деплоя в приватную сеть.
- Terraform — автоматическое разворачивание инфраструктуры перед деплоем.
- Kaniko — сборка Docker без Docker daemon (безопаснее для CI).

Заключение

CI/CD пайплайн с GitHub Actions и Docker — это не роскошь, а необходимость для любой команды, которая хочет доставлять код быстро и без ошибок. В 2026 году инструменты стали настолько зрелыми, что настроить production-ready пайплайн можно за вечер.

Начните с малого: добавьте автотесты на каждый коммит. Потом — сборку образа. Потом — деплой. Через неделю вы не вспомните, как жили без автоматизации.

Хотите освоить полный стек DevOps? В курсе «DevOps и облачные технологии» мы разбираем реальные сценарии: от Docker и Kubernetes до CI/CD с GitHub Actions, Terraform и мониторингом Prometheus. Вы будете писать YAML-конфиги для production, а не игрушечные примеры. Присоединяйтесь на asibiont.com — и ваш следующий деплой пройдёт без сучка и задоринки.

← Все статьи

Комментарии