Для создания 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 это означает использование средства запуска или оркестратора для получения изменений в коде, запуска тестов, создания артефактов или контейнеров и надежного развертывания в вашей среде.

В число основных инструментов входят 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 Упростите вертикальное и горизонтальное масштабирование.