CI/CD на базе Ubuntu 24.04 LTS: GitHub Actions, Docker, NGINX

CI/CD на базе Ubuntu 24.04 LTS: GitHub Actions, Docker, NGINX

Ручное развёртывание приложений замедляет циклы разработки, увеличивает риски ошибок и чревато простоями в работе сервисов. Современные проекты требуют автоматизированного подхода, где каждый код-коммит запускает чёткий процесс: сборку, тестирование и деплой без ручного вмешательства. Рассказываем, как реализовать полноценный CI/CD-пайплайн на базе Ubuntu 24.04 с тремя ключевыми технологиями — и запустить его на VPS для стабильной и управляемой среды развёртывания:

  • GitHub Actions для автоматизированного управления процессами,
  • Docker для создания переносимых контейнеризованных сред,
  • NGINX как reverse-proxy с TLS-шифрованием.

Такая система:

  • автоматически собирает и тестирует приложение при каждом обновлении кода,
  • развёртывает обновления на продакшн-сервере без простоя,
  • обеспечивает безопасное подключение через HTTPS,
  • сохраняет возможность мгновенного отката.

Аренда VPS/VDS от 219 руб/месяц

Преимущества VPS в AdminVPS:

✓ Бесплатное администрирование

✓ Только быстрые NVMe-диски

✓ Защита от DDoS-атак

✓ Быстрая техподдержка

Аренда VPS/VDS виртуального сервера от AdminVPS — это прозрачная и честная услуга с доступной ценой

Подготовка инфраструктуры

Начнём с настройки сервера на Ubuntu 24.04 LTS.

Установка базовых компонентов:

sudo apt update && sudo apt upgrade -y
sudo apt install docker.io docker-compose ufw -y

Настройка файрвола:

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp   # HTTP
sudo ufw allow 443/tcp  # HTTPS
sudo ufw enable

Добавление пользователя для CI/CD:

sudo useradd -m deployer
sudo usermod -aG docker deployer
sudo mkdir -p /home/deployer/.ssh

Генерация SSH-ключа для GitHub Actions:

ssh-keygen -t ed25519 -f github-actions-key
sudo mv github-actions-key.pub /home/deployer/.ssh/authorized_keys
sudo chown -R deployer:deployer /home/deployer/.ssh

Настройка GitHub Actions

GitHub Actions — это система автоматизации, встроенная в GitHub. Она позволяет создавать пайплайны (цепочки действий), которые автоматически выполняются при определённых событиях, например, при отправке кода в репозиторий (push). Это ключевой инструмент для Continuous Integration/Continuous Deployment (CI/CD).

Создайте в корне репозитория файл .github/workflows/cicd.yml с содержимым:

name: CI/CD Pipeline  # Название пайплайна
on: [push]   # Пайплайн запускается при любом push в репозиторий
jobs:
  build-test:  # Задача № 1 — сборка и тестирование
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2
      - name: Cache Docker layers
        uses: actions/cache@v3
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-docker-${{ hashFiles('**/Dockerfile') }}
      - name: Build and test
        run: |
          docker build -t your-app:latest .
          docker run your-app:latest npm test   # Пример для Node.js
  deploy:  # Задача № 2 — деплой на сервер
    needs: build-test
    runs-on: self-hosted
    steps:
      - name: Deploy to production
        env:
          SSH_KEY: ${{ secrets.SERVER_SSH_KEY }}
        run: |
          echo "$SSH_KEY" > key.pem
          chmod 600 key.pem
          scp -i key.pem .env deployer@ip_сервера:/app/.env
          ssh -i key.pem deployer@ip_сервера "cd /app && docker-compose pull && docker-compose up -d"

Во время выполнения первой задачи ваш репозиторий будет клонирован на виртуальную машину GitHub с последней версией Ubuntu, затем будет установлен Docker Buildx — расширенный инструмент для сборки образов, собран Docker-образ с тегом your-app:latest, включено кеширование слоёв Docker (ускоряет сборку на 40-70 % за счёт сохранения промежуточных образов), запущен контейнер и выполнены тесты (в примере — npm test для Node.js).

Вторая задача (деплой) выполняется на вашем собственном сервере с Ubuntu 24.04 и только в случае успешного выполнения первой задачи. Приложение будет развёрнуто на вашем сервере через SSH.

Настройка Self-Hosted Runner для GitHub Actions

GitHub Actions по умолчанию использует виртуальные машины GitHub (ubuntu-latest, windows-latest и другие). Но для деплоя на ваш сервер требуется специальный агент — Self-Hosted Runner. Это программа, которая:

  • устанавливается непосредственно на ваш сервер Ubuntu,
  • связывает сервер с вашим репозиторием GitHub,
  • выполняет задачи CI/CD непосредственно на вашей инфраструктуре.

Для подключения сервера в настройках GitHub репозитория перейдите в Secrets → New repository secret и добавьте в SERVER_SSH_KEY приватный ключ из файла github-actions-key.

На сервере установите GitHub Actions Runner:

mkdir actions-runner && cd actions-runner
curl -o runner.tar.gz -L https://github.com/actions/runner/releases/download/v2.316.1/actions-runner-linux-x64-2.316.1.tar.gz
tar xzf ./runner.tar.gz
./config.sh --url https://github.com/ваш/репозиторий --token YOUR_TOKEN
./run.sh

Докеризация приложения

Создайте оптимизированный Dockerfile в корне проекта:

# Стадия сборки
FROM ubuntu:24.04 as builder
RUN apt update && apt install -y build-essential python3.12 git
COPY . /app
WORKDIR /app
RUN make build  # Кастомная команда для вашего стека
# Финальный образ
FROM ubuntu:24.04
RUN apt update && apt install -y python3.12 && \
    useradd -m appuser && chown -R appuser:appuser /app
USER appuser
COPY --from=builder --chown=appuser /app/dist /app
EXPOSE 8000
CMD ["python3", "/app/main.py"]

Критичные оптимизации:

  • Мультистадийная сборка уменьшает итоговый образ на 60-80 % за счёт исключения инструментов компиляции.
  • Безавторизационный пользователь appuser снижает риск эксплуатации уязвимостей.
  • Временные файлы не попадают в образ.

Проверка безопасности:

docker scan your-app:latest

Деплой на Ubuntu-сервер

Создайте на сервере директорию /app с docker-compose.yml:

version: '3.8'
services:
  app:
    image: ghcr.io/your-org/your-app:latest
    restart: always
    env_file: .env
    volumes:
      - logs:/app/logs
    healthcheck:
      test: ["CMD-SHELL", "wget -q --spider http://localhost:8000/health || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 3
  nginx:
    image: nginx:1.24-alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./certs:/etc/letsencrypt
volumes:
  logs:

Что мы сделали:

  • При обновлении новый контейнер запускается параллельно со старым.
  • NGINX перенаправляет трафик на новый контейнер после успешной проверки его состояния.
  • Старая версия удаляется только после подтверждения работоспособности новой.

Настройка NGINX в качестве обратного прокси-сервера

Создайте конфигурацию /app/nginx.conf:

events {
    worker_connections 1024;
}
http {
    upstream app_backend {
        server app:8000;
        keepalive 32;
    }
    server {
        listen 80;
        server_name ваш_домен.зона;
        location /.well-known/acme-challenge/ {
            root /var/www/certbot;
        }
        location / {
            return 301 https://$host$request_uri;
        }
    }
    server {
        listen 443 ssl http2;
        server_name ваш_домен.зона;
        ssl_certificate /etc/letsencrypt/live/ваш_домен.зона/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/ваш_домен.зона/privkey.pem;
        # Настройки безопасности TLS
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
        ssl_prefer_server_ciphers off;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 1d;
        location / {
            proxy_pass http://app_backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
    }
}

Автоматизируйте SSL через Certbot. Сначала инициализируйте сертификат вручную:

docker run -it --rm --name certbot \
  -v "/app/certs:/etc/letsencrypt" \
  -v "/app/letsencrypt:/var/www/letsencrypt" \
  certbot/certbot certonly \
  --webroot -w /var/www/letsencrypt \
  -d ваш_домен.зона

Добавьте cron для автообновления:

echo "0 3 * * * docker run --rm -v /app/certs:/etc/letsencrypt certbot/certbot renew" | sudo tee /etc/cron.d/certbot-renew

Итоговая схема работы

  1. Разработчик делает push кода в репозиторий.
  2. GitHub Actions запускает пайплайн:
  • Клонирует код — получает актуальную версию репозитория.
  • Собирает Docker-образ — создаёт контейнер с приложением, используя кеширование слоёв для ускорения.
  • Запускает тесты — выполняет юнит- и интеграционные тесты внутри временного контейнера.
  • Публикует образ — загружает собранный образ в GitHub Container Registry.
  1. При успешных тестах:
  • GitHub Actions устанавливает SSH-соединение с вашим Ubuntu-сервером.
  • Обновляет конфигурацию:
    • Копирует файл окружения (.env),
    • Останавливает старую версию приложения,
    • Запускает новую версию через Docker Compose.
  1. Nginx как реверс-прокси обеспечивает плавное переключение:
  • Перенаправляет запросы только на здоровые контейнеры.
  • Старая версия остаётся активной, пока новая не пройдет проверку.

Такая настройка обеспечивает полный цикл CI/CD с гарантией качества и безопасности.

Не забывайте проверять работоспособность. После успешного деплоя выполните:

curl -I https://ваш_домен.зона

Ожидаемый ответ: HTTP/2 200 с заголовком X-Served-By: Docker-Container

Читайте в блоге:


Loading spinner
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

VPN на VPS-сервере

Узнайте, как создать собственный VPN на VPS-сервере для защиты ваших конфиденциальных данных!

Что будем искать? Например,VPS-сервер

Мы в социальных сетях