···384384385385Though some projects do a [good job](https://github.com/immich-app/immich/blob/f909648bce8cf181512f388072abb6d1141f8a23/docker/docker-compose.yml#L52) of pinning their dependencies to specific digests or patch versions, most do not. You'll often find projects that only specify a major version like `postgres:14` or `redis:8`.
386386387387-Usually, it's inferred by these projects that this version must stay the same. Even if the dependency can be updated to the next major version with breaking compatibility, the project may still depend on the version in their compose.yaml stack for some specific behavior.
387387+Usually, it's inferred by these projects that this version must stay the same. Even if the dependency can be updated to the next major version without breaking compatibility, the project may still depend on the version in their compose.yaml stack for some specific behavior.
388388389389Additionally, many projects in the selfhosted community use the *same, known, common dependencies* in this style. Dependencies like databases, cache, and queues are common in projects found in the homelab. With the Renovate config given in Nick's guide, all of these dependencies get PRs to bump major/minor versions when we really do not want them. It adds a ton of noise and alarm fatigue to have to constantly close these.
390390···408408{: file='docker-compose in renovate.json'}
409409{% endraw %}
410410411411-and in the `docker-compose.packageRules` list **at the beginning** at the following entry:
411411+and in the `docker-compose.packageRules` list **at the beginning** add the following entry:
412412413413{% raw %}
414414```json
···426426{: file='docker-compose.packageRules in renovate.json'}
427427{% endraw %}
428428429429-This will modify PR titles, add labels new PRs, and include a searchable folder name in the PR body:
429429+This will modify PR titles, add labels to new PRs, and include a searchable folder name in the PR body:
430430431431
432432_PRs specify where compose file is located, from version, and version label_
···530530531531Dockerhub already has pretty restrictive rate limiting and quotas per day. Using a caching layer, especially if you end up pinning many images to digests, can help speed up Renovate's duration and drastically reduce calls to the registry and avoid rate limiting. This is especially useful when first creating your renovate config as you may be invoking Renovate many times to observe created PRs and iterating on your config.
532532533533-> If you don't want to go to the trouble of caching during initial renovate config iteration/setup then I would suggest creating a *testing* repository to have Renovate run on. Include only a few stacks with all the image update scenarios you want to detect and use that to iterate on config building, rather than using your entire homelab monorepo as the testing grounds.
533533+> If you don't want to go to the trouble of caching during initial renovate config iteration/setup then I would suggest creating a *testing*, toy monorepo repository to have Renovate run on. Include only a few stacks with all the image update scenarios you want to detect and use that to iterate on config building, rather than using your entire homelab monorepo as the testing grounds.
534534+>
535535+> In addition to avoiding caching this makes renovate action logs much easier to read through and speeds up the action duration.
534536{: .prompt-tip}
535537536538When Renovate is fetching updates it is making plain HTTP/S calls to the upstream registries[^no-docker-daemon-proxy] so we will use [CNCF's `distribution`](https://distribution.github.io/distribution/) image as a [pull through cache](https://distribution.github.io/distribution/recipes/mirror) in order to cache image manifest information from [each upstream registry](https://distribution.github.io/distribution/recipes/mirror/#gotcha) we want to cache for.