Docker в Jenkins: образы как агенты сборки

Рейтинг: 78.5% · 14 голосов
Подробный курс по Jenkins и CI/CD: установка и настройка, плагины и Configuration as Code, конвейеры (pipeline) и Jenkinsfile, declarative и scripted, агенты, Docker и Kubernetes, общие библиотеки на Groovy, безопасность и credentials, интеграции (SonarQube, артефакты), траблшутинг. Актуально на 2026.
Ответить
Аватара пользователя
Andrey_CICD
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Docker в Jenkins: образы как агенты сборки

Сообщение Andrey_CICD »

Оглавление курса (47)
  1. Что такое Jenkins и зачем нужен CI/CD
  2. Jenkins в 2026: версии, экосистема и сравнение с GitLab CI и GitHub Actions
  3. Архитектура Jenkins: контроллер, агенты, узлы и исполнители
  4. Установка Jenkins: пакеты, Docker и Kubernetes
  5. Первичная настройка Jenkins: мастер, плагины, пользователи
  6. Плагины Jenkins: установка, обновление и ключевой набор
  7. Configuration as Code (JCasC): настройка Jenkins декларативно
  8. Конвейеры Jenkins и Jenkinsfile: pipeline as code
  9. Scripted против Declarative: два синтаксиса конвейера
  10. Структура конвейера: node, stage, steps и первый pipeline
  11. Генератор сниппетов, запуск конвейера и Replay
  12. Типы заданий Jenkins: Freestyle, Pipeline, Multibranch и Organization
  13. Декларативный конвейер: структура pipeline, agent, stages
  14. agent, environment и переменные в конвейере
  15. tools, options, parameters и triggers в декларативном конвейере
  16. stages, parallel и matrix: организация этапов
  17. Условное выполнение when и блок post
  18. Триггеры сборки: webhook от GitHub, SCM polling и расписание
  19. Параметры сборки и пользовательский ввод
  20. Управление потоком: timeout, retry, sleep и waitUntil
  21. Параллелизм и блокировки: parallel, lock, milestone
  22. Постобработка и уведомления о результате сборки
  23. Groovy для Jenkins: основы скриптового конвейера
  24. Скриптовый конвейер: логика, циклы и функции
  25. Общие библиотеки Jenkins: Shared Libraries
  26. Подключение и загрузка общих библиотек
  27. Шаги оболочки: sh, bat, powershell и коды возврата
  28. Переменные среды, withEnv и рабочие пространства
  29. Работа с файлами, артефактами и отпечатками
  30. Сборка проектов в конвейере: Maven, Gradle, npm
  31. Качество кода: SonarQube и покрытие тестами
  32. Управление артефактами: публикация в Nexus и Artifactory
  33. Docker в Jenkins: образы как агенты сборки (вы здесь)
  34. Сборка и публикация Docker-образов из конвейера
  35. Jenkins в Kubernetes: динамические pod-агенты
  36. Развёртывание в Kubernetes из конвейера
  37. Безопасность Jenkins: аутентификация и матрица прав
  38. Учётные данные Jenkins: credentials в конвейере
  39. Безопасность сценариев: Groovy sandbox и Vault
  40. Уведомления и отчёты: email, Slack, Telegram, HTML
  41. Blue Ocean и интерфейс Jenkins в 2026
  42. Автоматизация Jenkins: CLI, REST API и script console
  43. Поиск и устранение неисправностей: читаем логи конвейера
  44. Типичные ошибки конвейера: сериализация и неутверждённый код
  45. Эксплуатация Jenkins: бэкап, обновление, масштабирование
  46. Конвертация и миграция: от Freestyle к Jenkinsfile
  47. Итог: сквозной CI/CD конвейер и Jenkins против альтернатив в 2026
Знакомая боль: на агенте сборки кто-то поставил Node 18, кто-то Node 20, рядом завалялись две версии JDK, Maven из 2019 года и питон, который никто не трогает, но удалить страшно. Новый проект приезжает с требованием "нужен Go 1.23" - и ты лезешь на агент руками ставить тулчейн. Через полгода это болото инструментов (snowflake-агент) ломается на ровном месте: сборка зелёная у тебя локально и красная на CI, потому что версии разъехались. Связка docker jenkins решает это радикально: каждый стейдж запускается в свежем контейнере с ровно тем окружением, которое нужно, а сам агент остаётся тонким - на нём только Docker и больше ничего.

В этом уроке разберём, как jenkins docker agent превращает образ в одноразовую среду сборки, чем agent docker отличается от agent dockerfile, как пробросить кеш зависимостей и где разложены классические грабли с правами и сокетом.

Механика: как jenkins docker agent запускает стейдж в контейнере

Идея простая. Ты указываешь Jenkins образ, он делает примерно docker run, монтирует внутрь workspace с твоим кодом и выполняет шаги стейджа уже внутри контейнера. Закончился стейдж - контейнер удаляется. Никаких следов, никакого мусора на хосте. Воспроизводимость берётся из того, что образ один и тот же у всех: на твоей машине, на агенте, у соседа.

Минимальный рабочий пример. Берём официальный образ Maven с нужной Java и собираем проект:

Код: Выделить всё

pipeline {
    agent {
        docker { image 'maven:3.9.9-eclipse-temurin-21' }
    }
    stages {
        stage('Build') {
            steps {
                sh 'mvn -B -ntp clean verify'
            }
        }
    }
}
Здесь весь pipeline крутится в одном контейнере. Но настоящая сила jenkins docker image раскрывается, когда у каждого стейджа своё окружение. Фронтенд собираем в Node, бэкенд - в Go, и эти миры не пересекаются:

Код: Выделить всё

pipeline {
    agent none
    stages {
        stage('Frontend') {
            agent { docker { image 'node:22-alpine' } }
            steps {
                sh 'npm ci'
                sh 'npm run build'
            }
        }
        stage('Backend') {
            agent { docker { image 'golang:1.23-alpine' } }
            steps {
                sh 'go build ./...'
            }
        }
    }
}
Обрати внимание на agent none на верхнем уровне - он говорит "глобального агента нет, каждый стейдж объявляет свой сам". Это и есть современный, изолированный способ: agent docker как стандарт сборок 2026 года.

Изображение

args, reuseNode и кеш: jenkins docker на практике

Голый docker { image } работает, но в реальной жизни нужны нюансы. Самый частый - кеш зависимостей. Каждый новый контейнер стартует чистым, и если ничего не сделать, npm ci или mvn будут качать полмира заново при каждой сборке. Лечится монтированием через args - это строка, которая дословно уходит в docker run:

Код: Выделить всё

pipeline {
    agent {
        docker {
            image 'maven:3.9.9-eclipse-temurin-21'
            args '-v $HOME/.m2:/root/.m2'
        }
    }
    stages {
        stage('Build') {
            steps {
                sh 'mvn -B -ntp clean verify'
            }
        }
    }
}
Теперь локальный репозиторий Maven живёт на хосте и переживает контейнеры. Через тот же args можно докинуть переменные окружения (-e), память (--memory), пробросить порт - всё, что умеет docker run.

Второй важный флаг - reuseNode. По умолчанию, когда ты вешаешь docker-агент на отдельный стейдж внутри pipeline с обычным агентом наверху, Jenkins может выделить новый узел и новый workspace. reuseNode true говорит: "не плоди узлы, смонтируй текущий workspace с текущего агента внутрь контейнера". Это критично, когда стейджи передают друг другу артефакты по файловой системе:

Код: Выделить всё

pipeline {
    agent { label 'linux' }
    stages {
        stage('Test') {
            agent {
                docker {
                    image 'python:3.13-slim'
                    reuseNode true
                }
            }
            steps {
                sh 'pip install -r requirements.txt && pytest'
            }
        }
    }
}
agent dockerfile: собрать образ агента из репозитория

Готовый образ с Docker Hub - не всегда то, что нужно. Иногда твоя сборка требует специфический набор: тот же Node, но плюс ffmpeg, плюс пара системных пакетов, плюс твой внутренний CLI. Держать это в публичном образе глупо, тащить руками - неповторяемо. Решение - положить Dockerfile прямо в репозиторий и собирать образ агента из него:

Код: Выделить всё

pipeline {
    agent {
        dockerfile {
            filename 'Dockerfile.ci'
            dir 'build'
            additionalBuildArgs '--build-arg NODE_VERSION=22'
        }
    }
    stages {
        stage('Build') {
            steps {
                sh 'make build'
            }
        }
    }
}
Jenkins возьмёт build/Dockerfile.ci, соберёт из него образ и запустит стейджи внутри. Окружение сборки теперь версионируется вместе с кодом и проходит через тот же ревью в pull request, что и всё остальное. Поменялась версия тулчейна - это видно в диффе, а не в чьей-то памяти. Это и есть честная воспроизводимость: jenkins в docker, где даже сам образ агента - часть репозитория.

Требования и типичные грабли

Чтобы всё это работало, на агенте Jenkins должен быть установлен Docker, а пользователь, под которым крутится Jenkins, обязан иметь доступ к Docker-демону. На этом и спотыкается большинство.
  • Permission denied на сокете. Классика: "Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock". Пользователь jenkins не в группе docker. Лечится добавлением в группу (usermod -aG docker jenkins) и перезапуском службы. Помни: членство в группе docker фактически равно root на этом хосте, относись к этому как к решению по безопасности, а не как к галочке.
  • Файлы принадлежат root. Если внутри контейнера процесс работает от root, созданные в workspace файлы будут с владельцем root, и следующий стейдж или чистка workspace упадёт на правах. Лечится прокидыванием UID/GID через args, например -u 1000:1000, либо образами, которые умеют работать не от рута.
  • Docker-in-Docker и сокет хоста. Если стейджу нужно собирать сам Docker-образ, не лезь в настоящий DinD без острой необходимости - чаще пробрасывают сокет хоста через args (-v /var/run/docker.sock:/var/run/docker.sock). Это удобно, но контейнер получает полный контроль над демоном хоста. Для изолированных сборок образов разумнее посмотреть в сторону инструментов, не требующих демона.
  • Кеш не подхватывается. Смонтировал том, но кеша нет? Проверь, что путь внутри контейнера совпадает с тем, куда тулчейн реально пишет (у root это /root/.m2, у непривилегированного пользователя - другой $HOME).
Пара слов про актуальность на 2026. Современный declarative pipeline и docker-агенты - это рабочий стандарт, а не эксперимент. Под капотом Jenkins LTS живёт в районе ветки 2.541.x с минимальной Java 17 (ветка 2.541.x - последняя с поддержкой Java 11, дальше только 17 и 21), так что и сам контроллер, и образы агентов имеет смысл держать на свежей Java. Если ты пришёл из мира GitHub Actions или GitLab CI, где контейнер на job - это встроенная норма (image: в .gitlab-ci.yml или container: в workflow), то agent docker даёт Jenkins ту же модель "чистая среда на каждый запуск". А вот Blue Ocean из старых руководств - это наследие: проект давно не развивается и получает только редкие правки безопасности, строить визуализацию на нём в 2026 не стоит, смотри на встроенный Pipeline-граф и Stage View.

Мини-лаба

Повтори руками:
  • Сделай простейший Jenkinsfile с agent { docker { image 'node:22-alpine' } } и шагом sh 'node --version'. Убедись, что версия Node берётся из образа, а не с агента.
  • Добавь второй стейдж с другим образом (python:3.13-slim) и agent none наверху. Посмотри в логе, как поднимаются два разных контейнера.
  • Подключи кеш через args '-v $HOME/.npm:/root/.npm', запусти npm ci дважды и сравни время второй сборки.
  • Положи в репозиторий Dockerfile.ci с парой extra-пакетов и переключись на agent { dockerfile { filename 'Dockerfile.ci' } }.
  • Специально сломай права: запусти контейнер от root, создай файл в workspace, затем добавь -u 1000:1000 и сравни владельца файлов.
Контрольные вопросы
  • Зачем нужен agent none на верхнем уровне pipeline, если у каждого стейджа свой docker-агент?
  • Чем отличается agent { docker } от agent { dockerfile } и когда выбирать второе?
  • Что делает reuseNode true и какую проблему он решает при передаче артефактов между стейджами?
  • Почему проброс /var/run/docker.sock внутрь контейнера - это удобно, но опасно с точки зрения безопасности?
Итог

Docker-агенты убирают зоопарк инструментов с агента и дают каждой сборке чистое, версионируемое окружение. agent { docker { image } } - быстрый способ взять готовый образ, agent { dockerfile } - собрать свой прямо из репозитория. args монтирует кеш и крутит параметры docker run, reuseNode держит стейджи в одном workspace. А все грабли сводятся к двум словам - права и сокет: дай Jenkins доступ к Docker-демону осознанно и следи за владельцем файлов. Это и есть современный, воспроизводимый CI без сюрпризов "у меня собиралось".
👍2 ❤️1 🔥1 😄 🤔1
Аватара пользователя
elixir77
Сообщения: 1
Зарегистрирован: 04 июн 2026, 04:07

Re: Docker в Jenkins: образы как агенты сборки

Сообщение elixir77 »

Наконец-то дошло зачем agent none сверху - думал это опечатка, а это чтобы глобального агента не было и каждый стейдж сам выбирал контейнер. Спасибо, теперь логично.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
Pajda
Сообщения: 1
Зарегистрирован: 26 май 2026, 20:58

Re: Docker в Jenkins: образы как агенты сборки

Сообщение Pajda »

Поймал ровно те грабли с правами - файлы после npm создавались от root и cleanWs падал. Помог -u 1000:1000 в args. Может стоит в урок ещё про образы которые сразу от непривилегированного юзера работают?
👍 ❤️ 🔥 😄 🤔
Ответить
← Предыдущая глава
Управление артефактами: публикация в Nexus и Artifactory
Следующая глава →
Сборка и публикация Docker-образов из конвейера

Все главы курса «Jenkins: конвейеры CI/CD от основ до продакшена»

Поделиться темой: ✈ Telegram VK
Похожие запросы: что такое jenkins простыми словамикак установить jenkins на linux и в dockerпервичная настройка jenkins после установкикакие плагины jenkins нужны новичкукак настроить агенты jenkins для сборкиcicd для начинающих с чего начать на jenkins

Вернуться в «Jenkins: конвейеры CI/CD от основ до продакшена»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя