Только для посетителей нашего блога: получите дополнительные 3 месяца бесплатно + скидку 10% на трехгодичный план YSBLOG10
Захватить сделку

Как создать CI/CD на сервере Linux с помощью Docker и Git

Для создания CI/CD на сервере LinuxПодготовьте защищенный хост, подключите свой репозиторий Git, установите средство запуска или оркестратор CI (Jenkins, GitHub Actions Runner или GitLab Runner), определите задания конвейера или YAML-файлы для сборки, тестирования и упаковки вашего приложения, а затем разверните его на тестовой/производственной среде через SSH или контейнеры, используя секреты. manageмониторинг, откат и отслеживание.

В этом руководстве вы узнаете, как создать CI/CD на сервере Linux, используя проверенные методы DevOps. Мы рассмотрим несколько подходов: Jenkins, саморазмещаемые раннеры GitHub Actions, GitLab Runner и облегченный конвейер Bash, чтобы вы могли выбрать то, что подходит вашему стеку и бюджету.

Я поделюсь реальными шагами, командами и советами по безопасности, основанными на более чем 12-летнем опыте создания конвейеров для веб-хостинга и облачных сред.


Что такое CI/CD на сервере Linux?

CI/CD (непрерывная интеграция/непрерывная доставка) автоматизирует процессы сборки, тестирования и развертывания приложений. На сервере Linux это означает использование средства запуска или оркестратора для получения изменений в коде, запуска тестов, создания артефактов или контейнеров и надежного развертывания в вашей среде.

Что такое CI/CD на сервере Linux?

В число основных инструментов входят Git, Docker, Jenkins, GitHub Actions, GitLab CI и Nginx.


Для кого это предназначено и что вы будете строить?

Этот учебный материал идеально подходит для разработчиков, системных администраторов и небольших команд, которым нужен безопасный и поддерживаемый интерфейс. Конвейер CI / CDВы настроите сервер на базе Ubuntu/Debian, добавите агент CI, сконфигурируете конвейеры и развернете контейнеризированное веб-приложение за Nginx с возможностью отката. Мы также рассмотрим секреты, брандмауэры, журналы и мониторинг.

  • Сервер на Linux (рекомендуется Ubuntu 22.04+ или Debian 12)
  • Доступ с правами root или sudo. SSH ключи
  • Репозитории Git (GitHub, GitLab, Bitbucket)
  • Docker и Docker Compose (или среда выполнения языка, например Node.js/Python/Java)
  • Домен и DNS (необязательно, но рекомендуется для HTTPS)

Совет по хостингу: Для большинства небольших задач CI/CD подойдет VPS-сервер или облачный экземпляр с 2–4 виртуальными процессорами и 4–8 ГБ оперативной памяти. Если вы предпочитаете... manageпомощь, YouStableVPS хостинг и manageПланы серверов d упрощают развертывание CI/CD с предварительно защищенными образами, снимками и круглосуточной поддержкой.


Шаг 1: Базовая настройка сервера (безопасность прежде всего)

Перед установкой инструментов CI обеспечьте безопасность сервера. Используйте пользователя без прав root, SSH-ключи, брандмауэр и необходимые пакеты.

# Create a non-root user
sudo adduser ci
sudo usermod -aG sudo,docker ci

# SSH hardening (on your local machine)
ssh-copy-id ci@your_server_ip

# Basic packages and updates
sudo apt update && sudo apt -y upgrade
sudo apt -y install git curl ufw fail2ban ca-certificates gnupg lsb-release

# Enable firewall
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw --force enable

# Install Docker (official repo)
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Allow ci user to run docker without sudo (re-login required)
sudo usermod -aG docker ci

Дополнительно: Установите Nginx для обратного проксирования вашего приложения и завершения TLS-соединения. Давайте зашифровать.

sudo apt -y install nginx
sudo ufw allow "Nginx Full"

# Example minimal reverse proxy (adjust server_name and upstream)
sudo bash -c 'cat >/etc/nginx/sites-available/app.conf' <<EOF
server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
EOF
sudo ln -s /etc/nginx/sites-available/app.conf /etc/nginx/sites-enabled/app.conf
sudo nginx -t && sudo systemctl reload nginx

Шаг 2: Выберите архитектуру CI/CD

  • Самостоятельно размещаемый раннер GitHub Actions: Тесная интеграция с GitHub, конвейеры обработки YAML, высокая скорость работы с монорепозиториями.
  • GitLab Runner: Работает с GitLab CI/CD, используя исполняемые файлы shell, Docker или Kubernetes.
  • Дженкинс: Обладает высокой расширяемостью, богатым набором плагинов, отлично подходит для сложных оркестровок с использованием нескольких репозиториев.
  • Lightweight Bash: Небольшие команды могут создавать скрипты для сборки, тестирования и развертывания, запускаемые веб-хуками или cron.

Выберите один из основных путей ниже. Вы можете комбинировать их по мере масштабирования (например, Actions для CI и Ansible для CD).

Вариант A: Самостоятельно размещенный раннер GitHub Actions

Запускайте рабочие процессы на собственном сервере Linux для полного контроля и локальности кэша. Зарегистрируйте средство запуска в настройках вашего репозитория GitHub > Действия > Средства запуска.

# As ci user
mkdir -p ~/actions-runner && cd ~/actions-runner
# Download the latest runner from GitHub (replace version/URL from GitHub UI)
curl -o actions-runner.tar.gz -L https://github.com/actions/runner/releases/download/vX.Y.Z/actions-runner-linux-x64-X.Y.Z.tar.gz
tar xzf actions-runner.tar.gz

# Configure (use the token from GitHub Runner setup)
./config.sh --url https://github.com/your-org/your-repo --token YOUR_TOKEN --labels self-hosted,linux,prod

# Install as a service
sudo ./svc.sh install
sudo ./svc.sh start
sudo systemctl status actions.runner.*

Пример рабочего процесса GitHub Actions для сборки, тестирования, контейнеризации Docker и развертывания с помощью Docker Compose локально на сервере:

name: CI/CD
on:
  push:
    branches: [ "main" ]
jobs:
  build-test-deploy:
    runs-on: self-hosted
    steps:
      - uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install deps & test
        run: |
          npm ci
          npm test --if-present

      - name: Build Docker image
        run: |
          docker build -t registry.example.com/myapp:${GITHUB_SHA::7} .
          docker tag registry.example.com/myapp:${GITHUB_SHA::7} registry.example.com/myapp:latest

      - name: Push image (if using private registry)
        env:
          REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
          REGISTRY_PASS: ${{ secrets.REGISTRY_PASS }}
        run: |
          echo "$REGISTRY_PASS" | docker login registry.example.com -u "$REGISTRY_USER" --password-stdin
          docker push registry.example.com/myapp:${GITHUB_SHA::7}
          docker push registry.example.com/myapp:latest

      - name: Deploy with Compose
        run: |
          docker compose pull || true
          docker compose up -d --remove-orphans
          docker image prune -f

Создайте минимальный файл docker-compose.yml в вашем репозитории:

services:
  app:
    image: registry.example.com/myapp:latest
    restart: unless-stopped
    ports:
      - "8080:8080"
    env_file:
      - .env

Вариант B: GitLab Runner на Linux

Используйте GitLab CI/CD с командной оболочкой или исполнителем Docker. Зарегистрируйте свой раннер с помощью токена проекта или группы.

curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
sudo apt -y install gitlab-runner

# Register runner (shell executor for simplicity)
sudo gitlab-runner register \
  --url https://gitlab.com/ \
  --registration-token YOUR_TOKEN \
  --executor shell \
  --description "linux-shell-runner"

Пример файла .gitlab-ci.yml:

stages: [test, build, deploy]

variables:
  DOCKER_HOST: "unix:///var/run/docker.sock"

test:
  stage: test
  script:
    - npm ci
    - npm test --if-present

build:
  stage: build
  script:
    - docker build -t registry.example.com/myapp:$CI_COMMIT_SHORT_SHA .
    - docker tag registry.example.com/myapp:$CI_COMMIT_SHORT_SHA registry.example.com/myapp:latest
    - echo $REGISTRY_PASS | docker login registry.example.com -u $REGISTRY_USER --password-stdin
    - docker push registry.example.com/myapp:$CI_COMMIT_SHORT_SHA
    - docker push registry.example.com/myapp:latest
  only:
    - main

deploy:
  stage: deploy
  script:
    - docker compose pull
    - docker compose up -d --remove-orphans
    - docker image prune -f
  environment:
    name: production
  only:
    - main

Вариант C: Конвейер Jenkins на Linux

Jenkins — это мощная платформа для сложных рабочих процессов и продвижения в различных средах.

# Install Java and Jenkins
sudo apt -y install openjdk-17-jre
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee \
  /usr/share/keyrings/jenkins-keyring.asc > /dev/null
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
  https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
  /etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt update && sudo apt -y install jenkins
sudo systemctl enable --now jenkins
# Access: http://your_server_ip:8080 (retrieve initial admin password)

Пример файла Jenkinsfile (декларативный):

pipeline {
  agent any
  environment {
    REGISTRY = 'registry.example.com'
    IMAGE = 'myapp'
  }
  stages {
    stage('Checkout') {
      steps { checkout scm }
    }
    stage('Test') {
      steps {
        sh 'npm ci'
        sh 'npm test --if-present'
      }
    }
    stage('Build & Push Image') {
      steps {
        withCredentials([usernamePassword(credentialsId: 'registry-creds', usernameVariable: 'USER', passwordVariable: 'PASS')]) {
          sh '''
            echo "$PASS" | docker login $REGISTRY -u "$USER" --password-stdin
            TAG=$(git rev-parse --short HEAD)
            docker build -t $REGISTRY/$IMAGE:$TAG .
            docker tag $REGISTRY/$IMAGE:$TAG $REGISTRY/$IMAGE:latest
            docker push $REGISTRY/$IMAGE:$TAG
            docker push $REGISTRY/$IMAGE:latest
          '''
        }
      }
    }
    stage('Deploy') {
      steps {
        sh 'docker compose pull && docker compose up -d --remove-orphans'
      }
    }
  }
  post {
    always { sh 'docker image prune -f || true' }
  }
}

Вариант D: Облегченная система CI/CD на основе Bash (без Orchestrator)

Для очень небольших проектов используйте Git-хук post-receive или скрипт cron для сборки и развертывания. Главное — простота, но безопасность.

#!/usr/bin/env bash
set -euo pipefail

REPO_DIR=/opt/myapp
cd "$REPO_DIR"

echo "==> Pulling latest..."
git fetch --all
git checkout main
git pull --ff-only

echo "==> Running tests..."
npm ci
npm test --if-present

echo "==> Building & deploying..."
docker build -t myapp:latest .
docker compose up -d --build --remove-orphans
docker image prune -f

Секреты, переменные окружения и откаты

  • Храните секреты на платформе (секреты GitHub, переменные GitLab CI, учетные данные Jenkins). Никогда не добавляйте в репозиторий файлы .env.
  • Используйте конфигурации, специфичные для вашей среды: .env.staging и .env.production с надежно защищенными секретами manageЕсли возможно, пожалуйста.
  • Помечайте релизы тегами (например, семантическими версиями) и сохраняйте предыдущую версию для быстрого отката с помощью Docker Compose или символической ссылки на каталог релиза.
  • Методы развертывания «синий/зеленый» или «канареечный» снижают риски для приложений с высокой интенсивностью трафика.

Контрольный список по усилению безопасности

  • Принцип наименьших привилегий: Запускать программы-раннеры от имени пользователей без прав root; ограничить использование sudo.
  • Сети: Закройте неиспользуемые порты с помощью UFW; по возможности изолируйте сети сборки и производства.
  • СШ: Аутентификация по ключам, отключение входа по паролю, регулярная смена ключей.
  • зависимости: Сканируйте изображения с помощью Trivy или Grype; закрепляйте базовые изображения и часто создавайте сетку.
  • Журналы событий и оповещения: Включить fail2ban; отправлять журналы в центральную систему; отслеживать работу служб запуска.
  • Резервные копии и снимки: Автоматизируйте процесс через панель управления хостингом; ежемесячно проводите тестовое восстановление.

Поиск и устранение неисправностей и мониторинг

  • Проверить услуги: systemctl status jenkins, gitlab runner, or actions.runner.*
  • Журналы участников забега: journalctl -u “actions.runner*” -e, journalctl -u gitlab-runner -e
  • Логи Docker: docker ps, docker logs события Docker
  • Нгинкс: sudo tail -f /var/log/nginx/access.log /var/log/nginx/error.log
  • Распространенные неисправности: Отсутствуют переменные среды, неверные учетные данные реестра, брандмауэр блокирует исходящие зеркальные копии реестра или пакетов.

Вопросы стоимости и масштабируемости

  • Начните с 2–4 виртуальных процессоров и 4–8 ГБ оперативной памяти; добавьте процессоры для сборки и оперативную память для слоев Docker.
  • Для повышения скорости используйте кэши сборки и средства запуска, привязанные к серверу, на котором размещен ваш реестр контейнеров.
  • По мере роста бизнеса разделяйте процессы непрерывной интеграции и производственные нагрузки, чтобы избежать конфликтов ресурсов.
  • Если вам нужна предсказуемая производительность, рассмотрите возможность участия нескольких бегунов и создания отдельной базы данных.

Комплексный пример: от развертывания до внедрения в производство.

  • Разработчик отправляет изменения в основную ветку; система непрерывной интеграции (CI) получает код.
  • Запустите модульные тесты и проверку синтаксиса.
  • Создайте образ Docker, пометьте его хешем коммита и указанием последней версии.
  • Внесите изменения в реестр и обновите Docker Compose на сервере.
  • Compose создает контейнер заново с нулевым или минимальным временем простоя.
  • Контрольная точка проверки работоспособности подтверждает успешное завершение работы; при сбоях срабатывает пожарная сигнализация.

Этот алгоритм работы является отказоустойчивым, поддается аудиту и легко воспроизводится на тестовой и производственной средах с использованием различных переменных и DNS-записей.

Рекомендации по поддержанию работоспособности вашей системы CI/CD

  • Обеспечьте высокую скорость работы конвейеров: кэшировать зависимости и распараллеливать тесты.
  • О неудачах следует говорить громко: Быстро выявляйте ошибки, уведомляйте Slack/электронную почту и присылайте журналы.
  • Неизменяемые артефакты: Создайте один раз, продвигайте через среды с тем же имиджем.
  • Идемпотентные развертывания: Двойной запуск команды `deploy` не должен привести к сбою вашего приложения.
  • Документируйте все: Файлы README, руководства по выполнению операций, шаги отката.

Часто задаваемые вопросы (FAQ)

Как выбрать между Jenkins, GitHub Actions и GitLab CI?

Используйте GitHub Actions, если ваш код размещен на GitHub и вам нужны простые рабочие процессы в формате YAML. Выберите GitLab CI для интеграции с репозиториями GitLab и запуска задач на уровне групп. Jenkins подойдет для высоконастраиваемых конвейеров, сложных процедур согласования или когда вам необходима глубокая поддержка плагинов и оркестровка нескольких репозиториев.

Требуется ли Docker для CI/CD в Linux?

Нет, но Docker упрощает воспроизводимые сборки и развертывания. Без Docker вы можете запускать сборки нативных языков программирования (Node, Python, Java) и развертывать их с помощью rsync или служб systemd. Для обеспечения согласованности и переносимости настоятельно рекомендуется использовать контейнеры.

Как обеспечить безопасность секретов в моём конвейере обработки данных?

Храните секреты на своей CI-платформе (секреты GitHub, переменные GitLab, учетные данные Jenkins). Избегайте использования файлов .env в открытом текстовом виде в репозиториях. Для сложных настроек рассмотрите HashiCorp Vault или облачную KMS. Ограничьте доступ к чтению секретов и регулярно их обновляйте.

Как проще всего откатить некорректное развертывание?

Сохраните предыдущий тег образа Docker и верните файл docker compose.yaml к этому тегу, затем выполните команду docker compose up -d. Если вы используете развертывание без контейнеров, сохраните символическую ссылку на «текущий» релиз, верните его обратно и перезапустите службу.

Можно ли запустить CI/CD на небольшом VPS?

Да. Для небольших проектов достаточно VPS с 2 vCPU/4 ГБ ОЗУ. Используйте кэширование и избегайте ресурсоемких параллельных сборок. По мере роста ваших конвейеров масштабируйте ресурсы или разделяйте среды CI и производственные нагрузки. Такие провайдеры, как... YouStable Упростите вертикальное и горизонтальное масштабирование.

Отправить по:

Санджит Чаухан

Санджит Чаухан — блогер и эксперт по SEO, посвятивший себя помощи веб-сайтам в органическом росте. Он делится практическими стратегиями, полезными советами и идеями для увеличения трафика, улучшения позиций в поисковой выдаче и максимального присутствия в интернете.

Оставьте комментарий

Ваш электронный адрес не будет опубликован. Обязательные поля помечены * *

Наверх