- C# 54%
- Shell 41.4%
- Dockerfile 4.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .forgejo/workflows | ||
| .github | ||
| patches/sonarr-search-patch | ||
| scripts | ||
| .dockerignore | ||
| .gitignore | ||
| Dockerfile | ||
| README.md | ||
| themepark | ||
Sonarr in Docker optimized for Unraid
Sonarr is a PVR for Usenet and BitTorrent users. It can monitor multiple RSS feeds for new episodes of your favorite shows and will grab, sort and rename them. It can also be configured to automatically upgrade the quality of files already downloaded when a better quality format becomes available.
Update: The container will check on every start/restart if there is a newer version available (you can also choose between stabel and nightly version - keep in mind that switching from a stable to a nightly version and vice versa will/can break the container).
Manual Version: You can also set a version manually by typing in the version number that you want to use for example: '2.0.0.5250' (without quotes) - you can also change it to 'latest' or 'nightly' like described above (works only for stable builds - don't forget to disable updates in the WebGUI if you are using a specific version).
ATTENTION: Don't change the port in the Sonarr config itself.
Migration: If you are migrating from another Container please be sure to deltete the files/folders 'logs', 'xdg' and 'config.xml', don't forget to change the root folder for your tv shows and select 'No, I'll Move the Files Myself'!
WARNING: The main configuration of the paths has a performance and disk usage impact: slow, I/O intensive moves and wasted disk space. For a detailed guide to change that see https://trash-guides.info/hardlinks/#unraid .
Env params
| Name | Value | Example |
|---|---|---|
| DATA_DIR | Folder for configfiles and the application | /sonarr |
| SONARR_REL | Select if you want to download a stable or prerelease | nightly |
| MONO_START_PARAMS | Only change if you know what you are doing! | --debug |
| UID | User Identifier | 99 |
| GID | Group Identifier | 100 |
| UMASK | Umask value for new created files | 0000 |
| DATA_PERMS | Data permissions for config folder | 770 |
| INDEXER_RATE_LIMIT_MS | Throttle between requests to the same indexer, applied by the search patch | 250 |
| DISABLE_INDEXER_RATE_PATCH | Set to 'true' to start Sonarr without the search patch | true |
Faster indexer searches
Sonarr waits 2 seconds between any two requests that share a rate limit key. Every indexer request uses the indexer id as that key, so the pages of a single search (up to 10 pages of 100 results per indexer) and every tier of a season search are serialized behind that delay - a single search easily spends 40-60 seconds waiting.
This image ships a small .NET startup hook (/opt/scripts/sonarr-search-patch/SonarrSearchPatch.dll, source in patches/) that caps that interval for requests carrying an indexer key. Requests without a key, like import list refreshes, keep Sonarr's stock 2 second delay.
INDEXER_RATE_LIMIT_MS(default250, clamped to 0-60000) sets the new interval. Lower values finish searches faster but hit the indexer API more often, so stay above the limits your indexers allow.DISABLE_INDEXER_RATE_PATCH=truestarts Sonarr without the hook.
The hook is fail-safe: if it cannot load Harmony or patch the rate limiter it logs why and Sonarr runs unmodified. When it is active the container log shows lines such as:
---Search patch enabled, indexer rate limit set to 250ms---
[sonarr-search-patch] initialized, indexer rate limit will be 250ms
[sonarr-search-patch] patched NzbDrone.Common.TPL.RateLimitService.WaitAndPulseAsync -> 250ms for rate limited requests
[sonarr-search-patch] verification: prefix attached to NzbDrone.Common.TPL.RateLimitService.WaitAndPulseAsync
Run example
docker run --name Sonarr -d \
-p 8989:8989 \
--env 'SONARR_REL=nightly' \
--env 'MONO_START_PARAMS=--debug' \
--env 'UID=99' \
--env 'GID=100' \
--env 'UMASK=0000' \
--env 'DATA_PERMS=770' \
--volume /mnt/cache/appdata/sonarr:/sonarr \
--volume /mnt/user/TV-Shows:/mnt/tv \
--volume /mnt/user/Downloads:/mnt/downloads \
ich777/sonarr
Building and pushing the image
.forgejo/workflows/build-image.yaml builds this repository into a container image and pushes it to the local registry. It is a manual workflow (workflow_dispatch) and never runs on push, so an image is only produced when it is started.
In the web UI: Actions → Build and push image → Run workflow. The defaults are prefilled for 10.10.10.222:5000/sonarr:
| Input | Default | Meaning |
|---|---|---|
registry |
10.10.10.222:5000 |
Registry host and port |
repository |
sonarr |
Image path inside the registry |
tags |
latest |
Space or comma separated tags, e.g. searchpatch 4.0.15 |
platforms |
linux/amd64 |
More than one platform needs buildx and binfmt on the runner |
push |
true |
Untick to only build, the image then stays in the runner |
pull |
true |
Build with --pull so newer base images are used |
runner |
docker |
Label of a runner that has access to a Docker daemon |
The same run can be started from a shell, for example with a token that has write:repository:
curl -X POST \
-H "Authorization: token $TOKEN" \
-H 'Content-Type: application/json' \
http://10.10.10.220:3000/api/v1/repos/soultaco83/docker-sonarr/actions/workflows/build-image.yaml/dispatches \
-d '{"ref":"master","inputs":{"tags":"searchpatch","platforms":"linux/amd64","push":"true"}}'
Requirements on the machine that runs the job:
-
A runner registered for this repository (or its owner) with the label given in
runner- without a runner the dispatched run stays queued forever. The job needs a Docker daemon it can reach: either host mode (ubuntu-latest:host) or a container label with the socket mounted (container.docker_host: automountin the runner config). -
The registry has to be listed as insecure on that Docker daemon because it is served over plain HTTP:
{ "insecure-registries": ["10.10.10.222:5000"] }in
/etc/docker/daemon.json, then restart Docker. Without it the push fails withhttp: server gave HTTP response to HTTPS client. -
Credentials are optional. Anonymous pushes need no configuration; for an authenticated registry add the repository secrets
REGISTRY_USERNAMEandREGISTRY_PASSWORDand the workflow logs in before pushing.
The .NET SDK image and the base image are pulled on every run while pull is enabled, which briefly needs internet access from the runner. INDEXER_RATE_LIMIT_MS is not a build argument, it is read when the container starts.
This Docker was mainly edited for better use with Unraid, if you don't use Unraid you should definitely try it!