12 Tips to Self-host Renovate Bot
Tags: devops, tooling, gitlab, renovate
Published: 2022-04-04 00:38:03

Updating dependencies is boring. Despite its importance, we always find excuses to avoid updating them in the phrase of “if it ain't broke, don't fix it” or “there are more important features to work on”. Over time, the maintainability of the projects deteriorates. The team ends up with a 3-year-old dependency where no one is brave enough to bump it.

So, what’s the solution? Let the robots do our boring job!

In this article, you will learn tips on running a self-hosted [Renovate](https://github.com/renovatebot/renovate) bot with GitLab as an example. If you’re looking for a guide on how to start using Renovate on GitHub, I’d highly recommend you to [read this](https://www.freecodecamp.org/news/update-dependencies-automatically-with-github-actions-and-renovate/#Getting-Started).

## TL;DR

- Why use Renovate
- Getting started on self-hosted Renovate (GitLab as an example)
- How to run Renovate locally
- Debugging Renovate jobs
- 12 useful Renovate tips

Disclaimer: these tips are my own opinions from lessons gathered from hours working. Enjoy!

---

## Why Use Renovate

In short, Renovate ([official doc](https://docs.renovatebot.com/)) helps to update project dependencies (private or third-party) automatically. 

How? Renovate parses our projects’ dependency management files such as `package.json`, `pyproject.toml`, `go.mod` file and raises a pull/merge request (PR/MR) with the updated dependencies accordingly.

Renovate is highly customizable via a simple configuration file (`config.js`). With rather intuitive configuration settings, it also supports a [wide range of package managers](https://docs.renovatebot.com/modules/manager/#supported-managers).

Today, Renovate supports many other Git platforms such as Bitbucket, Gitea, or even Azure DevOps. On top of that, it’s [used by a lot of popular development communities or companies](https://github.com/renovatebot/renovate#who-uses-renovate) such as Uber, GitLab, Prisma, Netlify, etc.

### Highlight

The best part about Renovate is its ability to auto-merge PRs/MRs. 

That aside, the flexibility provided by the `[packageRules` feature](https://docs.renovatebot.com/configuration-options/#packagerules) which is used to apply rules to specific dependencies (in individual or group) is incredibly handy.

## How To Run Self-hosted Renovate on GitLab

To run Renovate on self-hosted GitLab, you’ll need a private GitLab project ([i.e. repository](https://about.gitlab.com/blog/2016/01/27/comparing-terms-gitlab-github-bitbucket/) in the following). This bot repository will be used to host [GitLab runners](https://docs.gitlab.com/runner/) which run Renovate for your other projects.

Next, assuming that you already have GitLab runners installed and set up, you’ll need the following in the bot project:

1. Configure the following CI/CD variables:
    1. `RENOVATE_TOKEN` — GitLab [Personal Access Token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#creating-a-personal-access-token) (PAT) with scopes: `read_user`, `api`, and `write_repository`.
    2. `GITHUB_COM_TOKEN` —  GitHub PAT with minimum scope.
2. `config.js` (NOTE: here’s a [more complex example](https://gitlab.com/gitlab-org/frontend/renovate-gitlab-bot/-/blob/main/renovate/config.js)).
    
    ```javascript
    // Example config.js from https://github.com/renovatebot/renovate/blob/main/docs/usage/examples/self-hosting.md
    
    module.exports = {
      endpoint: 'https://self-hosted.gitlab/api/v4/',
      token: '**gitlab_token**',
      platform: 'gitlab',
      onboardingConfig: {
        extends: ['config:base'],
      },
      repositories: ['username/repo', 'orgname/repo'],
    };
    ```
    
3. `.gitlab-ci.yml`. If you need a more complex example, check out [this example from the GitLab team](https://gitlab.com/gitlab-org/frontend/renovate-gitlab-bot/-/blob/main/.gitlab-ci.yml). Otherwise, here’s a minimal example; do update accordingly:
    
    ```yaml
    image: renovate/renovate:32.6.12
    
    variables:
        LOG_LEVEL: debug
    
    renovate:on-schedule:
        tags:
            - your-gitlab-runner-tag-if-any
        only:
            - schedules
        script:
            - renovate $RENOVATE_EXTRA_FLAGS
    
    renovate:
        tags:
            - your-gitlab-runner-tag-if-any
        except:
            - schedules
        script:
            - renovate $RENOVATE_EXTRA_FLAGS
    ```
    
4. Lastly, you’ll need to run Renovate at regular intervals (e.g. every hour) using the GitLab project’s [CI/CD Schedules](https://docs.gitlab.com/ee/ci/pipelines/schedules.html) feature. Do note that this is different from Renovate’s own [schedule](https://docs.renovatebot.com/configuration-options/#schedule).

Check the [source](https://gitlab.com/renovate-bot/renovate-runner) for more details. Though, the steps above should be sufficient.

## How To Run Renovate Locally

While I was working with a large repository (>6GB for full clone), each Renovate job may take hours to complete. Having the ability to run Renovate locally saves me a bunch of time when it comes to experimentation and debugging.

First, create a [minimum reproducible example (MRE) repository](https://github.com/renovatebot/renovate/blob/main/docs/development/minimal-reproductions.md#how-to-create-a-good-minimal-reproduction). Then, update your `config.js` to target or discover the MRE repository. To run Renovate locally:

1. It’s a lot easier to just use [Docker](https://www.docker.com/). So, make sure you’ve installed Docker.
2. To start, you’ll need to ensure that these environment variables are being exported in your shell:
    
    ```bash
    export RENOVATE_TOKEN="aa11bb22cc" # GitLab Personal Access token (PAT)
    export GITHUB_COM_TOKEN="cc33dd44ee" # GitHub PAT
    ```
    
3. Next, update your `config.js` accordingly. You’ll need to update your target `repositories` accordingly.
4. Finally, you can run Renovate using the following. To grab the latest Renovate version, check out [Docker hub](https://hub.docker.com/r/renovate/renovate/tags). Do change the following command accordingly:
    
    ```bash
    docker run \
        --rm \
        -e LOG_LEVEL="debug" \
        -e GITHUB_COM_TOKEN="$GITHUB_COM_TOKEN" \
        -v "/path/to/local/config.js:/usr/src/app/config.js" \
        renovate/renovate:"32.6.12" \
        --token "$RENOVATE_TOKEN" \
        --dry-run="true"
    ```
    
    With this, testing Renovate configuration in a fast-feedback loop manner is now possible. In case you need more comprehensive logs, try setting `LOG_LEVEL=”trace”` instead.
    
    To perform an actual run, update `--dry-run="false"`.
    

## 12 Useful Renovate Bot Tips

### General tips

1. Not sure how to get the most out of Renovate quickly? Check out this [Renovate bot cheat sheet](https://www.augmentedmind.de/2021/07/25/renovate-bot-cheat-sheet/) instead of the verboseness of [the official Renovate doc](https://docs.renovatebot.com/).
2. If you are unsure whether Renovate supports a certain functionality, always check out their [FAQ](https://docs.renovatebot.com/faq/) page first. Chances are it’s already there.
3. To disable updates for a specific package or library simply set `enabled: false` under the respective `[packageRule](https://docs.renovatebot.com/configuration-options/#packagerules)`. Example:
    
    ```javascript
    // Example config.js
    
    module.exports = {
        endpoint: 'https://your.domain.com/api/v4/',
        token: '**gitlab_token**',
        platform: 'gitlab',
        onboardingConfig: {
            extends: ['config:base'],
        },
        repositories: [
            {
                repository: 'john/next-generation-repo',
                packageRules: [
                    {
                        description: 'Disable MAJOR update types',
                        matchUpdateTypes: ['major'],
                        enabled: false,
                    },
                ],
            },
        ],
    }
    ```
    
4. Need to run some custom task or script after upgrading (e.g. a script that posts messages to Slack)? [Try `postUpgradeTasks`](https://docs.renovatebot.com/configuration-options/#postupgradetasks).
5. Keep project-specific Renovate configs on the bot repository instead of having `renovate.json` in every other repository. For this, set `[onboarding: false](https://docs.renovatebot.com/self-hosted-configuration/#onboarding)` under `module.exports`. This allows for Renovate-related configs to be abstracted away to a single repository only.

### Tips on debugging Renovate jobs

When it comes to self-hosted solutions, there’s no running away from debugging your own jobs. There could be scenarios where you’ll need to test connections to your private registry, proxy, etc. 

Here are a couple of helpful tips:

1. Try running Renovate locally to have a faster feedback loop instead of relying on your CI/CD pipelines. Plus, running locally is practically free!
2. Use `trace` `LOG_LEVEL` in case `debug` doesn’t give you enough information.
3. In case you’re working on some bespoke use cases or facing odd encounters/bugs, try Google searching with the prefix “*site:github.com/renovatebot/renovate <your keywords or phrases>*”. ([example](https://www.google.com/search?q=site%3Agithub.com%2Frenovatebot%2Frenovate+wrong+update+version+for+go.mod&ei=6xpJYua5CbiNseMPzbOy2A0&ved=0ahUKEwim2_r3__b2AhW4RmwGHc2ZDNsQ4dUDCA4&uact=5&oq=site%3Agithub.com%2Frenovatebot%2Frenovate+wrong+update+version+for+go.mod&gs_lcp=Cgdnd3Mtd2l6EANKBAhBGAFKBAhGGABQ0CdY2Edg70hoBHAAeAGAAdoBiAGQDZIBBjMyLjAuMZgBAKABAcABAQ&sclient=gws-wiz)). In most cases, you’ll find that there are already others who have filed a similar discussion or issue.

### Dealing with a large repository (e.g. GB in size)

1. If you attempt to run Renovate on a large repository, you may encounter a `SIGTERM` signal (which can be seen in your Renovate job log) due to timeout. To cope with this, increase the `[executionTimeout` setting](https://docs.renovatebot.com/self-hosted-configuration/#executiontimeout) in your `config.js`.
    
    ```javascript
    // Example config.js
    
    module.exports = {
      endpoint: 'https://your.domain.com/api/v4/',
    	executionTimeout: 1440, // minutes
      token: '**gitlab_token**',
      platform: 'gitlab',
      onboardingConfig: {
        extends: ['config:base'],
      },
      repositories: ['john/large-repo', 'doe/huge-repo'],
    };
    ```
    
2. Under your GitLab project’s CI/CD General pipelines settings, you may want to increase your job timeout (e.g. 10 hours) as Renovate may take a long time on an uncached run on large repositories.
3. You may want to set `persistRepoData: true` for faster `git fetch` between runs.
    
    ```javascript
    // Example config.js
    
    module.exports = {
        endpoint: 'https://your.domain.com/api/v4/',
        token: '**gitlab_token**',
        platform: 'gitlab',
        persistRepoData: true,
        onboardingConfig: {
            extends: ['config:base'],
        },
        repositories: ['john/repo'],
    }
    ```
    
4. On some occasions, you may run into `ERROR: Disk space error - skipping`. Here, you may want to provision a runner with increased disk size. E.g. if you are using AWS EC2, try to increase the size of the volume.

---

## Conclusion

Over the past few months, I have been using Renovate bot extensively; on GitHub, and self-hosted GitLab. Today, I am using Renovate on most of my active projects on GitHub to automate dependency updates. So far, Renovate was able to fit 99% of my use cases.

Keeping our project dependencies up-to-date is often overlooked. Yet, overlooking such work often comes at a great cost. The fact that we can leverage Renovate’s ability to do such grunt work is quite a blessing.

I hope this article saves you enough time instead of having you groom through pages of GitHub discussions and issues. Thanks for reading!

---

_This article was originally published on [jerrynsh.com](https://jerrynsh.com/12-tips-to-self-host-renovate-bot/)_