Renovate в Docker Compose: готовый файл
Зависимости в проекте устаревают тихо: сегодня библиотека на минорной версии позади, через полгода — на трёх мажорных, и обновление превращается в отдельный спринт с непредсказуемым риском. Renovate закрывает эту проблему автоматически: он сканирует репозитории по расписанию и открывает pull request на каждое обновление — вам остаётся смотреть CI и жать «мёрж». Ниже — рабочий docker-compose.yml для self-hosted Gitea, GitLab CE и Forgejo, без привязки к SaaS-версии Renovate.
Содержание
- Renovate против Dependabot и Watchtower: что именно он делает
- Готовый docker-compose.yml
- config.js: репозитории, расписание, правила автомёржа
- Запуск по расписанию: cron на хосте vs sidecar-контейнер
- Токен и подключение к self-hosted Gitea, GitLab CE, Forgejo
- Ресурсы сервера и первый запуск
- Частые ошибки при первом запуске
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Renovate против Dependabot и Watchtower: что именно он делает
Renovate — это CLI-инструмент, который клонирует репозиторий, читает манифесты зависимостей (package.json, go.mod, requirements.txt, Dockerfile, docker-compose.yml и десятки других форматов) и создаёт PR с обновлением версии, обновлённым лок-файлом и changelog в описании. Он не запускает и не перезапускает ваши сервисы — этим занимается CI/CD после мёржа.
Важно не путать его с двумя соседними инструментами:
- Watchtower обновляет уже запущенные Docker-контейнеры на новый образ прямо на сервере, без PR и без ревью — грубее, но проще. Если вам нужен именно такой сценарий, у нас есть отдельный разбор — автообновление Watchtower на VPS.
- Dependabot — облачный сервис GitHub, который на self-hosted Gitea/GitLab/Forgejo не работает вообще. Renovate — по сути открытая альтернатива, которая одинаково хорошо живёт и в облаке, и на своём сервере.
Renovate не демон: контейнер стартует, делает один проход по всем репозиториям, открывает/обновляет PR и завершается с кодом 0. Расписание вы задаёте либо через cron на хосте, либо через schedule в конфиге самого Renovate (это разные вещи, и путать их — частая причина «почему Renovate не запускается ночью»).
Готовый docker-compose.yml
Структура проекта:
renovate/
├── docker-compose.yml
├── .env
└── config.js
docker-compose.yml:
services:
renovate:
image: ghcr.io/renovatebot/renovate:latest
container_name: renovate
restart: "no"
env_file:
- .env
volumes:
- ./config.js:/usr/src/app/config.js:ro
- renovate-cache:/tmp/renovate/cache
# можно передать список репозиториев прямо аргументом,
# если не хотите прописывать его в config.js
# command: ["group/repo-1", "group/repo-2"]
volumes:
renovate-cache:
ghcr.io/renovatebot/renovate:latest тянет актуальный мажорный релиз — для прод-контура лучше зафиксировать конкретный тег (например, renovate:39), который вы сами проверили на ghcr.io/renovatebot/renovate/tags, чтобы обновление образа не подменило поведение конфига без вашего ведома.
.env:
RENOVATE_TOKEN=ваш_токен_с_правами_на_репозитории
RENOVATE_PLATFORM=gitea
RENOVATE_ENDPOINT=https://git.example.com/api/v1
LOG_LEVEL=info
renovate-cache — именованный том под кеш пакетных менеджеров (npm, go modules, pip). Без него каждый запуск заново тянет метаданные из реестров, и на большом монорепо это заметно увеличивает время прохода.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверconfig.js: репозитории, расписание, правила автомёржа
Renovate поддерживает конфиг в JSON, JSON5 и JS — последний удобнее, потому что можно писать комментарии. Базовый пример под self-hosted Gitea:
module.exports = {
platform: 'gitea',
endpoint: 'https://git.example.com/api/v1',
autodiscover: false,
repositories: ['team/backend', 'team/frontend', 'team/infra'],
onboarding: true,
onboardingConfig: {
extends: ['config:recommended'],
},
timezone: 'Europe/Moscow',
schedule: ['after 2am and before 5am every weekday'],
labels: ['dependencies'],
prConcurrentLimit: 10,
prHourlyLimit: 5,
packageRules: [
{
matchUpdateTypes: ['minor', 'patch'],
automerge: true,
automergeType: 'branch',
},
{
matchUpdateTypes: ['major'],
automerge: false,
addLabels: ['major-update'],
},
{
matchPackagePatterns: ['^eslint'],
groupName: 'eslint',
},
],
};
Ключевые поля:
repositories— список репозиториев в форматеowner/repo. Без него нуженautodiscover: true, но тогда Renovate обойдёт вообще все репозитории, куда у токена есть доступ — на большом инстансе это долго и не всегда то, что нужно.onboarding— при первом запуске на новом репозитории Renovate вместо обычного PR откроет «onboarding PR» с предложеннымrenovate.json. Пока его не смёржат, реальные обновления не начнутся — это осознанное поведение, не баг.scheduleвнутриconfig.js— это НЕ расписание запуска контейнера, а окно, в которое Renovate разрешено *создавать и обновлять* PR. Сам процесс должен быть запущен извне (см. следующий раздел), аscheduleлишь фильтрует, что делать в рамках этого запуска.packageRules— точечная настройка: где включить автомёрж без ревью (обычно patch/minor с проходящим CI), а где оставить major-обновления на ручную проверку.
Запуск по расписанию: cron на хосте vs sidecar-контейнер
Раз Renovate завершается после одного прохода, планировщик нужен снаружи. Два рабочих варианта.
Вариант 1 — cron на хосте (проще, рекомендуется для одиночного VPS):
crontab -e
0 3 * * 1-5 cd /opt/renovate && docker compose run --rm renovate >> /var/log/renovate.log 2>&1
Так контейнер поднимается раз в будни в 3:00, делает проход, пишет лог и удаляется (--rm), не оставляя мёртвых контейнеров в docker ps -a. Если crontab на сервере для вас в новинку — у нас есть отдельный разбор настройки cron-задач на VPS.
Вариант 2 — sidecar-контейнер с доступом к Docker socket (когда хочется держать всё в compose, без правки хостового crontab):
services:
renovate:
image: ghcr.io/renovatebot/renovate:latest
container_name: renovate
restart: "no"
profiles: ["manual"]
env_file:
- .env
volumes:
- ./config.js:/usr/src/app/config.js:ro
- renovate-cache:/tmp/renovate/cache
scheduler:
image: mcuadros/ofelia:latest
container_name: renovate-scheduler
restart: unless-stopped
depends_on:
- renovate
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
command: daemon --docker
labels:
ofelia.job-run.renovate.schedule: "0 0 3 * * 1-5"
ofelia.job-run.renovate.container: "renovate"
volumes:
renovate-cache:
Ofelia сам дёргает контейнер renovate по cron-выражению через Docker API. Плюс в том, что вся конфигурация живёт в одном compose-проекте и переезжает вместе с ним; минус — лишний постоянно работающий процесс с доступом к docker.sock, а это уже вопрос поверхности атаки, если сервер разделяют несколько сервисов. Для одного проекта на выделенном VPS хостовый cron честнее и проще в отладке.
Токен и подключение к self-hosted Gitea, GitLab CE, Forgejo
Renovate обращается к API вашего git-сервера, поэтому нужен персональный токен с правом читать и писать репозитории и открывать PR/MR.
Gitea / Forgejo: *Настройки профиля → Приложения → Создать новый токен*, права минимум repository (read/write) и misc для веб-хуков, если планируете их использовать. Значение RENOVATE_PLATFORM — gitea; для Forgejo на актуальных версиях Renovate тоже подходит platform: gitea совместимого режима, но если у вас свежий Forgejo и свежий Renovate, стоит проверить в официальной документации, добавлена ли отдельная платформа forgejo в вашей версии — это менялось от релиза к релизу. Если держите Forgejo, у нас есть готовый файл для самого сервиса — Forgejo в Docker Compose.
GitLab CE: *User Settings → Access Tokens*, scope — api. RENOVATE_PLATFORM=gitlab, RENOVATE_ENDPOINT указывает на https://git.example.com/api/v4. Если GitLab CE у вас ещё не поднят и есть вопросы по интеграции с CI — см. настройку GitLab CI/CD на VPS.
Токен — секрет с широкими правами на весь git-сервер, поэтому его нельзя коммитить в репозиторий вместе с config.js. Держите его только в .env, добавьте .env в .gitignore, а на проде рассмотрите более строгое хранение секретов — этому посвящена отдельная статья про управление паролями через Docker secrets.
Ресурсы сервера и первый запуск
Renovate на каждый репозиторий делает полный или частичный git clone, разворачивает lock-файлы и обращается к реестрам пакетов (npm, PyPI, Go proxy, Docker Hub) — это кратковременно, но заметно нагружает CPU и сеть на время прохода, особенно на монорепо с десятками package.json. Для 5–10 средних репозиториев обычно достаточно 2 vCPU и 2–4 ГБ RAM; если Renovate живёт на том же VPS, что и сам git-сервер (Gitea/GitLab CE) плюс CI-раннер, закладывайте запас — GitLab CE сам по себе прожорлив по памяти.
Первый запуск стоит сделать вручную, не через cron, чтобы сразу видеть логи:
cd /opt/renovate
docker compose run --rm renovate
В логе ищите строки вида Repository started для каждого репозитория и итоговую сводку Renovate finished. Если onboarding: true, ждите не обновления зависимостей, а onboarding PR с предложенным конфигом — это нормально, обновления начнутся после его мёржа.
Частые ошибки при первом запуске
| Симптом в логе | Причина | Что проверить |
|---|---|---|
Response code 401 (Unauthorized) | Токен не тот или без нужных прав | Пересоздать токен с правами repository/api, обновить .env |
Response code 404 при обращении к endpoint | Неверный путь API | Для Gitea/Forgejo — /api/v1, для GitLab — /api/v4 |
connect ECONNREFUSED | Endpoint указывает не туда (внутренний хост вместо внешнего, или наоборот) | Из контейнера renovate endpoint должен быть доступен так же, как из браузера, если контейнер не в одной docker-сети с git-сервером |
| Репозитории просканированы, но PR не появились | schedule не разрешает запись в текущее время, либо всё уже up-to-date | Временно убрать schedule из config.js для теста, посмотреть dryRun в логах |
| Onboarding PR висит без обновлений | onboarding: true и никто не смёржил предложенный конфиг | Смёржить onboarding PR или явно передать onboarding: false, если конфиг уже задан вручную |
EACCES при работе с кешем | Том renovate-cache создан с правами root, а процесс в контейнере работает не от root | Пересоздать том: docker volume rm renovate_renovate-cache и запустить заново |
Если контейнер вообще не поднимается — стоит свериться с общим чек-листом по докеру: контейнер не запускается — причины и решение.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Чем Renovate лучше, чем просто вручную раз в месяц смотреть npm outdated?
Он не даёт зависимостям накапливаться: каждое обновление приходит отдельным PR с CI-проверкой сразу, пока diff маленький и причину падения теста легко найти. Ручной разбор десятков накопившихся обновлений за раз — куда более рискованная и долгая операция.
Можно ли доверить Renovate автомёрж без ревью?
Да, но избирательно — через packageRules с matchUpdateTypes: ['patch', 'minor'] и automerge: true, обязательно при условии зелёного CI (platformAutomerge учитывает статус проверок). Major-обновления лучше оставлять на ручной мёрж — они чаще ломают API.
Нужен ли отдельный VPS под Renovate или можно на сервере с Gitea/GitLab?
Можно на том же сервере — Renovate нагружает его только на время прохода (обычно минуты), а не постоянно, в отличие от самого git-сервера или CI-раннеров.
Как часто нужно запускать Renovate?
Для активных репозиториев — раз в сутки ночью; для спокойных проектов достаточно раз в неделю. Слишком частый запуск не даёт выигрыша, а лишь чаще упирается в prHourlyLimit и создаёт шум в списке PR.
Renovate работает с приватными npm/PyPI-реестрами?
Да, через hostRules в config.js с токеном доступа к конкретному реестру — механизм отдельный от RENOVATE_TOKEN git-платформы.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →