MAATRIX / Блог / Jenkins на сервере: частые ошибки и решения

Jenkins на сервере: частые ошибки и решения

MAATRIX

Jenkins — ветеран CI/CD: тысячи плагинов, полная свобода настройки, никакой зависимости от чужого облака. Но эта свобода оборачивается и обратной стороной — типовыми граблями, на которые наступает почти каждый, кто поднимает свой сервер сборки с нуля. Разберём самые частые проблемы Jenkins на сервере и как их закрыть без переустановки с нуля.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Ошибка: Jenkins падает с OutOfMemoryError

Классика для собственного Jenkins на скромном VPS. Сборки идут нормально, а потом сервис внезапно умирает или зависает намертво, а в логе — java.lang.OutOfMemoryError: Java heap space. Причина почти всегда одна: Java-куче не хватает памяти, потому что она либо не задана явно, либо задана слишком щедро относительно реальной оперативки сервера.

Проверьте текущие настройки JVM. На Debian/Ubuntu с установкой из репозитория параметры задаются в /etc/default/jenkins, при systemd-юните — в /lib/systemd/system/jenkins.service или в override:

sudo systemctl status jenkins
sudo journalctl -u jenkins --since "1 hour ago" | grep -i outofmemory

Задайте явные границы кучи через JAVA_OPTS или JAVA_ARGS, отталкиваясь от объёма оперативки сервера, а не от значений по умолчанию:

JAVA_OPTS="-Xms512m -Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/lib/jenkins/heapdump"

-Xmx не должен приближаться к полному объёму RAM — оставьте запас для ОС, самого процесса Java (метапространство, стек потоков) и параллельных сборок. Если Jenkins крутится на 2 ГБ памяти и с ним же выполняются тяжёлые Docker-сборки, конфликт за память практически гарантирован — тут либо разносить нагрузку по разным нодам, либо переезжать на сервер побольше.

Ошибка: диск забит билдами и workspace

Через месяц-другой активной работы Jenkins начинает жаловаться на нехватку места, а /var/lib/jenkins разрастается до десятков гигабайт. Причина в том, что по умолчанию Jenkins хранит историю сборок бесконечно: артефакты, логи, рабочие директории — всё копится, пока диск не закончится.

Первым делом посмотрите, что именно ест место:

du -sh /var/lib/jenkins/jobs/*/builds | sort -rh | head -10
du -sh /var/lib/jenkins/jobs/*/workspace 2>/dev/null | sort -rh | head -10

Дальше настройте политику хранения на уровне каждой задачи — «Discard old builds» с ограничением по числу сборок или по дням. Для пайплайнов это делается прямо в Jenkinsfile:

options {
    buildDiscarder(logRotator(numToKeepStr: '20', artifactNumToKeepStr: '10'))
}

Дополнительно почистите старые рабочие директории плагином workspace cleanup или явным шагом cleanWs() в конце пайплайна. Если сборки тяжёлые (большие Docker-образы, npm-кеши, артефакты сборки Java), маленького диска на VPS не хватит в принципе — разумнее сразу закладывать быстрый SSD с запасом, чем каждую неделю разбирать завалы вручную.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Ошибка: агент (node) не подключается

Мастер Jenkins поднят, а агент, подключаемый по SSH, висит в статусе offline или падает при попытке подключения. Причин обычно две: проблемы с SSH-доступом или несовместимая версия Java на агенте.

Проверьте вручную, что мастер вообще может зайти на агент по тем же данным, что указаны в настройках ноды:

ssh -i /var/lib/jenkins/.ssh/id_ed25519 jenkins-agent@10.0.0.5 "java -version"

Если подключение падает по ключу — сверьте, что публичный ключ действительно добавлен в authorized_keys агента и что права на директорию .ssh корректные (700 на каталог, 600 на файлы). Про сам механизм ключевой аутентификации подробно разобрано в статье про SSH-ключи вместо пароля на сервере — грабли там те же самые, что и для агентов Jenkins.

Если SSH проходит, а нода всё равно не стартует — смотрите лог агента в интерфейсе Jenkins (Manage Jenkins → Nodes → выбранный агент → Log). Частая причина — на агенте стоит Java другой major-версии, чем ожидает конкретная версия Jenkins, или у пользователя агента нет прав на рабочую директорию, указанную в настройках ноды (Remote root directory).

Ошибка: Jenkins за reverse-proxy теряет стили и ссылки

Jenkins поставили за nginx с SSL, а интерфейс выглядит сломанным: нет стилей, ссылки ведут на http:// вместо https://, а вебхуки от Git-провайдера не долетают. Причина в том, что Jenkins не знает, что перед ним стоит прокси, и генерирует ссылки исходя из своего внутреннего адреса.

Решение — правильно прокинуть заголовки в конфиге nginx и явно указать Jenkins его внешний URL:

location / {
    proxy_pass         http://127.0.0.1:8080;
    proxy_set_header    Host              $host;
    proxy_set_header    X-Real-IP         $remote_addr;
    proxy_set_header    X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Proto $scheme;
    proxy_redirect      http://127.0.0.1:8080 https://ci.example.com;
}

В самом Jenkins зайдите в Manage Jenkins → System и укажите правильный Jenkins URL (с https:// и без завершающего порта). Если после этого стили всё равно не подгружаются — проверьте, что nginx не режет статические ресурсы по маске /static/ и что размер заголовков и тела запроса не упирается в лимиты прокси при загрузке крупных плагинов. SSL для домена перед Jenkins удобно выпускать через Let's Encrypt — базовая настройка описана в статье про установку Let's Encrypt на VPS.

Ошибка: permission denied при работе с Docker в пайплайне

Пайплайн собирает Docker-образ или запускает контейнер, а падает с permission denied на сокете /var/run/docker.sock. Jenkins по умолчанию работает от системного пользователя jenkins, у которого нет прав на Docker — они выдаются явно.

Добавьте пользователя jenkins в группу docker и перезапустите сервис, чтобы новая группа применилась к процессу:

sudo usermod -aG docker jenkins
sudo systemctl restart jenkins

Если Jenkins сам развёрнут в контейнере, а сборки внутри него тоже используют Docker (сценарий Docker-in-Docker), пробрасывайте сокет хоста в контейнер вместо того, чтобы включать привилегированный режим бездумно — это расширяет возможности сборки, но и риски, если в пайплайн попадёт чужой код:

volumes:
  - /var/run/docker.sock:/var/run/docker.sock

Общие причины, по которым контейнер вообще не поднимается или падает сразу после старта, разобраны отдельно в статье Docker-контейнер не запускается — стоит свериться, если проблема не только в правах.

Ошибка: плагины конфликтуют после обновления

Обновили плагины скопом через Plugin Manager — и Jenkins либо не стартует, либо интерфейс сыпет ошибками в определённых разделах. Массовое обновление плагинов без разбора зависимостей — одна из самых частых причин сломанного Jenkins, потому что новые версии плагинов не всегда совместимы друг с другом или с текущей версией самого Jenkins.

Если сервис не поднимается после обновления, откатите проблемный плагин вручную. Старые версии .hpi-файлов Jenkins хранит рядом с текущими при обновлении через UI (файл с суффиксом .bak), их можно вернуть на место:

cd /var/lib/jenkins/plugins
mv problem-plugin.jpi.bak problem-plugin.jpi
sudo systemctl restart jenkins

Правило на будущее: обновляйте плагины небольшими партиями, а не разом всё, и держите резервную копию /var/lib/jenkins перед крупным обновлением — конфиги задач, credentials и сама история плагинов лежат именно там. Проверить итог после отката удобно сразу через journalctl -u jenkins -f — если стартовые ошибки исчезли, можно возвращаться к постепенному обновлению остальных плагинов.

Как выстроить стабильную работу Jenkins

Большинство описанных проблем не возникают при соблюдении нескольких правил с самого начала. Задайте явные границы Java-кучи под реальный объём памяти сервера, а не полагайтесь на значения по умолчанию. Настройте политику хранения сборок и регулярную очистку workspace, чтобы диск не забивался незаметно. Проверяйте SSH-доступ и версии Java на агентах при любых изменениях инфраструктуры. Обновляйте плагины постепенно и с бэкапом перед каждым крупным апдейтом.

Отдельно окупается адекватный сервер под сборки. Jenkins с несколькими параллельными джобами и Docker-сборками быстро упирается в CPU, память и скорость диска на минимальных тарифах. У MAATRIX сервер под Jenkins-мастер и агенты оплачивается из России картой или криптой, а конфигурацию легко нарастить, когда пайплайнов и плагинов станет больше — без миграции на новую площадку. Если планируете автоматический деплой после успешной сборки, пригодится и статья про частые ошибки автодеплоя из Git на сервере — логичное продолжение CI/CD-цепочки после самого Jenkins.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Сколько памяти нужно закладывать под Jenkins?

Для мастера без тяжёлых сборок на нём самом хватает 2 ГБ с -Xmx около 1–1.5 ГБ. Если на том же сервере крутятся Docker-сборки или несколько параллельных задач, закладывайте запас — 4 ГБ и больше, ориентируясь на реальную нагрузку.

Почему после перезапуска сервера Jenkins не поднялся сам?

Проверьте автозапуск сервиса: systemctl is-enabled jenkins. Если отключён — включите командой systemctl enable --now jenkins и убедитесь, что порт 8080 (или тот, что настроен) не занят другим процессом.

Можно ли держать Jenkins и Docker-агенты на одном VPS?

Можно для небольших проектов, но тяжёлые сборки конкурируют с самим Jenkins за CPU и память. Как только сборки станут регулярными и тяжёлыми, лучше вынести агентов на отдельный сервер или хотя бы ограничить им ресурсы.

Что делать, если забыли пароль администратора Jenkins?

Временно отключите проверку прав через security.enabled в конфиге config.xml, зайдите под любым пользователем и создайте нового администратора через Groovy-консоль или UI, после чего верните защиту обратно. Делать это стоит с локального доступа, а не через открытый в интернет интерфейс.

Нужен ли реверс-прокси перед Jenkins, если сервер и так только для CI/CD?

Да, ради SSL и удобного домена вместо IP:8080. Заодно прокси упрощает ограничение доступа по IP или базовой аутентификацией на уровне nginx, что для интерфейса сборки со значимыми правами на прод — не лишняя предосторожность.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →