Настройка CI/CD для сайта через Jenkins
Jenkins — зрелая open-source система автоматизации. Требует собственного сервера, зато никаких ограничений на минуты, агенты, параллельные сборки. Для организаций с жёсткими требованиями к изоляции инфраструктуры или большими объёмами сборок — оправданный выбор.
Установка
# Ubuntu 22.04, Java 17 обязателен
apt install fontconfig openjdk-17-jre
wget -O /usr/share/keyrings/jenkins-keyring.asc \
https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
https://pkg.jenkins.io/debian-stable binary/" | tee /etc/apt/sources.list.d/jenkins.list
apt update && apt install jenkins
systemctl enable --now jenkins
# Доступен на :8080
Минимум: 2 CPU, 4 GB RAM. Для нагруженного CI с параллельными сборками — 4+ CPU, 8+ GB.
Declarative Pipeline (Jenkinsfile)
Хранить Jenkinsfile в репозитории — единственный правильный подход. Freestyle jobs через UI не версионируются.
pipeline {
agent any
tools {
nodejs 'NodeJS-20'
}
environment {
DEPLOY_HOST = credentials('deploy-host')
DEPLOY_KEY = credentials('deploy-ssh-key')
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Install') {
steps {
sh 'npm ci'
}
}
stage('Test') {
steps {
sh 'npm test'
}
post {
always {
junit 'test-results/**/*.xml'
}
}
}
stage('Build') {
steps {
sh 'npm run build'
}
}
stage('Deploy') {
when {
branch 'main'
}
steps {
sshagent(['deploy-ssh-key']) {
sh '''
rsync -avz --delete dist/ deploy@${DEPLOY_HOST}:/var/www/mysite/
ssh deploy@${DEPLOY_HOST} "cd /var/www/mysite && php artisan cache:clear"
'''
}
}
}
}
post {
failure {
telegramSend(message: "Build failed: ${env.JOB_NAME} #${env.BUILD_NUMBER}", chatId: '-1001234567890')
}
success {
cleanWs()
}
}
}
Управление учётными данными
Credentials хранятся в Jenkins Credentials Store (Manage Jenkins → Credentials). Никогда не прописывайте секреты в Jenkinsfile. Типы:
- Secret text — токены, API-ключи
- SSH Username with private key — деплой по SSH
- Username with password — docker registry, базы данных
- Certificate — mTLS
withCredentials([
string(credentialsId: 'telegram-token', variable: 'TG_TOKEN'),
sshUserPrivateKey(credentialsId: 'deploy-key', keyFileVariable: 'SSH_KEY')
]) {
sh 'ssh -i $SSH_KEY deploy@server "..."'
}
Параллельные стадии
stage('Test & Lint') {
parallel {
stage('Unit Tests') {
steps { sh 'npm test' }
}
stage('Lint') {
steps { sh 'npm run lint' }
}
stage('Type Check') {
steps { sh 'npx tsc --noEmit' }
}
}
}
Три задачи выполняются одновременно — экономия времени при наличии свободных executor'ов.
Docker-агенты
Вместо установки зависимостей на мастер — запуск каждой стадии в контейнере:
pipeline {
agent none
stages {
stage('Build') {
agent {
docker {
image 'node:20-alpine'
args '-v /tmp/.npm:/root/.npm'
}
}
steps {
sh 'npm ci && npm run build'
}
}
stage('PHP Tests') {
agent {
docker {
image 'php:8.3-cli'
args '--network=host'
}
}
steps {
sh 'composer install && php artisan test'
}
}
}
}
Мультибранч Pipeline
Multibranch Pipeline автоматически создаёт джобы под каждую ветку и PR:
- New Item → Multibranch Pipeline
- Branch Sources → Git/GitHub/GitLab
- Jenkinsfile обнаруживается автоматически в каждой ветке
Для PR из форков можно настроить when { changeRequest() } — отдельное поведение для pull request builds.
Blue Ocean
Плагин Blue Ocean даёт современный UI для пайплайнов — наглядная визуализация стадий, параллельных веток, логов. Устанавливается через Manage Plugins. Не заменяет классический UI, но упрощает навигацию командам.
Shared Libraries
Для нескольких проектов с одинаковым пайплайном — вынесите общий код в Shared Library:
// vars/deployToServer.groovy в репозитории jenkins-shared-libs
def call(String host, String path) {
sshagent(['deploy-ssh-key']) {
sh "rsync -avz dist/ deploy@${host}:${path}"
}
}
// В Jenkinsfile проекта
@Library('jenkins-shared-libs') _
deployToServer('prod.mysite.com', '/var/www/mysite')
Сроки настройки
Установка и первый рабочий пайплайн — 2–3 дня: установка сервера, плагины, Jenkinsfile, отладка. Настройка мультибранч, Docker-агентов, shared libraries — ещё 3–5 дней. Jenkins требует больше времени на начальную настройку, чем облачные решения, но даёт полный контроль над инфраструктурой.







