Jenkins - это инструмент, который часто используют для тестирования и сборок программ. Очень часто, в этих процессах, используется Docker. В этой статье будет рассмотрены базовые операции по созданию контейнера Docker с Jenkins.
В статье подразумевается, что Docker у вас уже установлен.
Запуск контейнера
На данный момент официальный образ с Jenkins не поддерживается более 2 лет. Вместе него, разработчиками Jenkins, предлагается использовать образ jenkins/jenkins.
Сам образ может быть получен двумя путями. Первый - это обычное скачивание через 'pull'. Кроме названия образа так же можно указать версию JDK:
# последняя версия
docker pull jenkins/jenkins
# для windows
docker pull jenkins/jenkins:jdk11-hotspot-windowsservercore-2019
# с Java 11
docker pull jenkins/jenkins:jdk11
Второй способ - выполнить инструкцию 'run', которая запускает контейнер. Если образ не был скачен, то это будет сделано. В инструкции ниже использованы следующие параметры:
- '-d' (detach) - запуск контейнера в фоновом режиме;
- '-p' - порты, разделенные двоеточием. Первое значение говорит о сервере, второй о контейнере. Пакеты, поступающие на указанный порт сервера, будут перенаправлены на указанный порт контейнера. 8080 порт используется по умолчанию для доступа к веб-интерфейсу Jenkins. Параметр '-p' можно повторять открывая другие порты нужные Jenkins. 50000 порт используется для подключения агентов;
- '--name' - имя, которое будет использоваться при обращении к контейнеру.
Пример запуска контейнера:
docker run -d -p 8080:8080 -p 50000:50000 --name my_jenkins jenkins/jenkins
# получаем информацию по запущенным контейнерам
docker ps
Проверить, что вы верно открыли порт, можно открыв браузер указав IP сервера Docker и порт, указанный при запуске контейнера:
Если у вас это сделать не получается - проверьте, что у вас открыты соответствующие порты на фаерволле.
Настройка Jenkins
В окне приветствия Jenkins мы должны указать пароль, который был создан во время запуска контейнера. Этот пароль можно увидеть через логи или напрямую обратившись к файлу, где он хранится:
docker logs my_jenkins
# или открываем файл на контейнере
docker exec my_jenkins cat /var/jenkins_home/secrets/initialAdminPassword
В следующем окне нужно выбрать плагины, который вы планируете устанавливать. Это либо пакет стандартных плагинов либо основанный на вашем выборе. Первый вариант самый частый случай:
После установки плагинов (~5 минут в случае стандартных плагинов), можно создать пользователя администратора:
Последующие окна будут без варианта выбора.
Бэкап и восстановление данных Jenkins в Docker
Образ, который используется в данной статье, создает отдельный VOLUME и присоединяет его к контейнеру. Это значит, что даже если вы удалите контейнер или образ - том с данными останется.
Например, так мы можем увидеть идентификатор тома, который смонтирован у контейнера, а так же путь его расположение на хосту и в контейнере:
docker inspect my_jenkins
Так мы увидим, что содержимое обеих директорий одинаковое:
docker exec my_jenkins ls /var/jenkins_home
# у вас будет другой путь
sudo ls /var/lib/docker/volumes/656e9d2749b39c8adf812c54862a7c7e307585ef3493c52061820db6f7f26741/_data
Скопировать содержимое тома мы можем использовав обычную утилиту Linux 'cp' или аналогичную, предназначенную для Docker, с тем же именем:
# копируем из контейнера
docker cp my_jenkins:/var/jenkins_home ./jenkins_backup
# копируем из папки на хосту (у вас будет другой путь)
sudo cp -r /var/lib/docker/volumes/656e9d2749b39c8adf812c54862a7c7e307585ef3493c52061820db6f7f26741/_data ./jenkins_backup
Если мы хотим поместить файлы обратно, то это можно сделать, например, так:
# копируем с хоста
docker cp ./jenkins_backup my_jenkins:/var/jenkins_home
Т.к. мы используем отдельный VOLUME, мы можем смонтировать его и к другому контейнеру сохранив все данные:
docker run -d -p 8082:8080 -v 656e9d2749b39c8adf812c54862a7c7e307585ef3493c52061820db6f7f26741:/var/jenkins_home --name my_jenkins3 jenkins/jenkin
s
Мы можем указать читаемое название VOLUME при первом создании контейнера:
docker run -d -p 8082:8080 -v jenkins_volume:/var/jenkins_home --name my_jenkins3 jenkins/jenkins
Так как VOLUME не удаляются при удалении образов и контейнеров - вы можете сделать это самостоятельно. Перед удалением тома нужно удалить контейнеры, которые используют этот том:
docker volume rm 656e9d2749b39c8adf812c54862a7c7e307585ef3493c52061820db6f7f26741
Копирование и изменение пользователя
Контейнер с Jenkins, по умолчанию, использует одноименного пользователя c id 1000. Это значит, что вы можете столкнуться с ошибками если копируете файлы с хоста.
docker exec my_jenkins ls -la /var/jenkins_home
В зависимости от ситуации есть разные способы сменить владельца. Первый способ - это использовать параметры в Dockerfile:
- 'USER' - устанавливает пользователя, от которого будут выполняться команды;
- 'COPY --chown=' - меняет владельца при копировании файлов.
В примере ниже пример Dockerfile, в котором мы поменяем пользователя на 'root' для выполнения привилегированной операции, а затем обратно на 'jenkins'. При копировании файлов, мы сменим владельцев файла так же на jenkins:
FROM jenkins/jenkins:latest
USER root
RUN apt-get update
COPY --chown=jenkins:jenkins test_jenkins.yml /var/jenkins_home/some_folder/test_jenkins.yml
USER jenkins
Если бы мы выполняли обновление используя пользователя jenkins, то получили бы ошибку 'Acquire (13: Permission denied)'.
Еще один способ скопировать файл и изменить пользователя, но уже на запущенном контейнере:
# копируем файлы
docker cp ./some_folder my_jenkins:/var/jenkins_home/
# выполняем команду на контейнере по смене владельца
docker exec my_jenkins chown -R jenkins:jenkins /var/jenkins_home/some_folder
Так же сработает, если вы просто скопируете файлы владелец которых имеет id 1000 (такой же у Jenkins).
Запуск Jenkins через docker-compose
Для запуска контейнера через docker-compose мы создаем инструкцию. В этой инструкции мы перечисляем те же значения, что и при обычном создании контейнера. Единственно отличие - это само название параметров.
Инструкции, docker-compose, имеют формат yaml и помещаются в отдельный файл. Так мы создадим контейнер, аналогичный обычному запуску:
version: '3.7'
services:
jenkins:
image: jenkins/jenkins:latest
ports:
- 8080:8080
container_name: my_jenkins
# если нужно подключить том
# volumes:
# - jenkins_volume:/var/jenkins_home
# volumes:
# jenkins_volume:
# # Если том не был создан
# driver: local
# # Если том создан вне compose
# external: true
# name: jenkins_volume
Эта инструкция помещается в отдельный файл. По умолчанию docker-compose ищет файл с названием 'docker-compose.yml'. Если у вас это название отличается, то его нужно указывать через параметр '-f'.
Пример запуска контейнера:
docker-compose -f 'test_jenkins.yml' up -d
Остановить работу контейнеров, используя docker-compose, можно двумя способами:
# остановит работу контейнеров
docker-compose -f 'test_jenkins.yml' stop
# остановит и удалит контейнеры
docker-compose -f 'test_jenkins.yml' down
...