Как Jenkins взаимодействует с Docker?
Интеграция Jenkins с Docker — это использование Docker-контейнеров в качестве изолированных сред для выполнения сборок, тестирования и упаковки приложений в рамках CI/CD пайплайна.
Представьте, что Jenkins — это прораб на стройке, а Docker-контейнеры — это одноразовые рабочие помещения. Для каждого вида работ (покраска, электрика, сантехника) прораб заказывает отдельный контейнер-бытовку с нужными инструментами. После завершения работы бытовка утилизируется — на стройплощадке чисто, инструменты не путаются, краска не пачкает электрику.
1. Docker как агент сборки
Каждая сборка выполняется в чистом контейнере — изоляция, воспроизводимость, отсутствие конфликтов между проектами:
Пример
pipeline {
agent {
docker {
image 'maven:3.9-eclipse-temurin-17'
args '-v $HOME/.m2:/root/.m2 --network=host'
}
}
stages {
stage('Build') {
steps { sh 'mvn clean package' }
}
}
}
Ключевой приём — монтирование кэша Maven (-v $HOME/.m2:/root/.m2), чтобы зависимости не скачивались заново при каждой сборке.
2. Разные Docker-образы для разных стадий
Каждая стадия пайплайна может использовать свой образ с нужным набором инструментов:
Пример: разные образы для сборки, тестов и публикации Docker-образа
pipeline {
agent none
stages {
stage('Build') {
agent { docker { image 'maven:3.9-eclipse-temurin-17' } }
steps { sh 'mvn clean package -DskipTests' }
}
stage('Test') {
agent { docker { image 'maven:3.9-eclipse-temurin-17' } }
steps { sh 'mvn test' }
}
stage('Build Docker Image') {
agent { label 'docker' }
steps {
script {
def app = docker.build("company/my-app:${env.BUILD_NUMBER}")
docker.withRegistry('https://nexus.company.com:8083', 'nexus-credentials') {
app.push()
app.push('latest')
}
}
}
}
}
}
3. Docker Compose для интеграционных тестов
Когда интеграционные тесты требуют внешних зависимостей (база данных, брокер сообщений, кэш), Docker Compose позволяет поднять всё окружение прямо на агенте:
Пример
stage('Integration Tests') {
steps {
sh 'docker-compose -f docker-compose.test.yml up -d'
sh 'mvn verify -Pintegration-tests'
}
post {
always {
sh 'docker-compose -f docker-compose.test.yml down -v'
}
}
}
Блок post { always { ... } } гарантирует остановку контейнеров даже при падении тестов.
4. Dockerfile как агент
Если ни один публичный образ не подходит, можно указать Dockerfile из репозитория проекта — Jenkins соберёт из него образ и запустит сборку внутри:
Пример
agent {
dockerfile {
filename 'Dockerfile.build'
dir 'ci'
additionalBuildArgs '--build-arg MAVEN_VERSION=3.9'
}
}
Сравнение подходов к использованию Docker в Jenkins
| Подход | Когда использовать | Преимущество |
|---|---|---|
docker { image '...' } |
Стандартные инструменты (Maven, Gradle, Node) | Простота, готовые образы |
dockerfile { ... } |
Нужен специфичный набор инструментов | Полный контроль над окружением |
| Docker Compose | Интеграционные тесты с зависимостями | Полное окружение для тестов |
docker.build() + docker.push() |
Упаковка приложения в Docker-образ | Публикация образа в registry |
Вывод
Docker в Jenkins решает проблему «на моей машине работает» и обеспечивает полную воспроизводимость сборок. Эфемерные контейнеры-агенты — это стандарт в современных CI/CD пайплайнах.
На собеседовании: могут спросить, зачем монтировать
.m2при использовании Docker-агента. Ответ: чтобы Maven не скачивал все зависимости при каждой сборке — кэш зависимостей сохраняется между запусками контейнера на хосте.