Skip to main content

The documentation here is for an unreleased version of Recyclarr.

Visit the documentation site for the Current Version instead.

Docker Compose

Recyclarr has an official Docker image hosted on the following platforms:

RegistryImage Name
Github Container Registry (GHCR)ghcr.io/recyclarr/recyclarr
Docker Hubrecyclarr/recyclarr
info

This guide refers exclusively to the GHCR image, but all steps apply equally to the Docker Hub image. Adjust the image name as needed.

Docker Compose Example​

The examples on this page use docker compose with a compose.yaml file, which is the recommended approach for managing container configuration in one place. If you already have a docker-compose.yml file, keep using it; Docker Compose still reads that name.

warning

The example below should not be used verbatim. Copy and paste it, then make the appropriate changes for your specific use case.

networks:
recyclarr:
name: recyclarr
external: true

services:
recyclarr:
image: ghcr.io/recyclarr/recyclarr:9
container_name: recyclarr
restart: unless-stopped
user: 1000:1000
networks: [recyclarr]
volumes:
- ./config:/config
environment:
- TZ=America/Santiago
- RECYCLARR_API_KEY=${RECYCLARR_API_KEY}

The container runs the Recyclarr server. The server stays running, syncs on a built-in schedule, and accepts commands from the CLI. Before you start it, create an API key. Then start it in the background:

docker compose up -d

Here is a breakdown of the above YAML:

  • networks
    Recyclarr needs network access to Sonarr and Radarr instances. How those services are hosted determines the network configuration. This example uses a dedicated Docker bridge network (named recyclarr) shared with those services, allowing Recyclarr to reach them directly without going through a reverse proxy.
  • image
    The official Recyclarr image, hosted on Github. The :9 tag receives all feature and bugfix updates within major version 9. See Tags for other options.
  • container_name
    Optional. Prevents Docker Compose from generating a prefixed name like prefix_recyclarr.
  • restart
    Starts the server again after a crash or a reboot of the host. Without a restart policy, scheduled syncs stop until you start the container yourself.
  • user
    Optional user and group ID for the container process. Recyclarr runs as this UID:GID, and any files it creates in the /config volume are owned by this user and group. Defaults to 1000:1000 if not specified.
  • environment
    TZ sets the time zone for the sync schedule. RECYCLARR_API_KEY sets the server's API key; see API Key.

Tags​

Docker tags represent components of the semantic version number following the format X.Y.Z, where:

  • X: Represents a major release containing breaking changes.
  • Y: Represents a feature release.
  • Z: Represents a bugfix release.

The following table describes the available tags. Using v2.1.2 as an example, the table is sorted by risk in descending order. For maximum stability, use the bottom row. For the most automatic updates (highest risk), use the top row.

TagDescription
2Latest feature and bugfix release; manual update for major releases
2.1Latest bugfix release; manual update if you want new features
2.1.2Exact release; no automatic updates

The recommended tag is the major version number (e.g. 9), which gives you all feature and bugfix releases automatically while requiring a manual update only for breaking changes.

There is no latest tag. It would move to each new major release automatically and apply breaking changes without warning, which causes problems that reading the upgrade guide and release notes first would have prevented. A major version tag lets you decide when to upgrade.

info

All docker tags described here are mutable with the exception of the three-component version number (e.g. 2.1.2 in the table above). A mutable tag is one that may change with each release of Recyclarr.

Dev Builds​

danger

Dev images are extremely unstable. They contain unreleased code and most likely have bugs.

Do not use them just to get the latest features. They are for testing changes before the next release and should not be run against production instances of Radarr or Sonarr.

Use these images at your own risk!

Every CI build of a branch in the Recyclarr repository publishes a dev image to the GitHub Container Registry (not Docker Hub), tagged with the branch name. The master branch, which holds the latest unreleased code, is ghcr.io/recyclarr/recyclarr-dev:master:

services:
recyclarr:
image: ghcr.io/recyclarr/recyclarr-dev:master

In the tag, any character in the branch name other than a letter, digit, or - becomes -, so branch feat/x is tagged feat-x. A branch name that does not start with a letter gets a b- prefix.

The tag moves to each new build of its branch. To stay on one build, pin its digest:

services:
recyclarr:
image: ghcr.io/recyclarr/recyclarr-dev:master@sha256:<digest>

The image label org.opencontainers.image.revision holds the commit SHA of the build.

When a newer build of the same branch replaces an image, the old image is deleted 30 days after its own build. A digest pin to a replaced build can stop working once that build is older than 30 days. The latest build of each branch is kept, even after the branch is deleted.

For Kubernetes, a matching dev chart is available; see Dev Chart.

Configuration​

Volumes​

  • /config
    The default directory for all Recyclarr files: configuration, state, logs, and downloaded resources. Server logs are written to /config/logs/server/. docker logs recyclarr also shows the server's log output.
Separating config, state, and data

Recyclarr can split its files into a config directory (your configuration), a state directory (sync state and job history), and a data directory (logs, downloaded resources). This lets you treat data as disposable and mount the config directory read-only.

services:
recyclarr:
image: ghcr.io/recyclarr/recyclarr:9
container_name: recyclarr
restart: unless-stopped
user: 1000:1000
environment:
- TZ=America/Santiago
- RECYCLARR_API_KEY=${RECYCLARR_API_KEY}
- RECYCLARR_CONFIG_DIR=/config
- RECYCLARR_DATA_DIR=/data
- RECYCLARR_STATE_DIR=/state
volumes:
- ./recyclarr:/config:ro # back this up
- ./state:/state # back this up
- recyclarr_data:/data # ephemeral, no backup needed
volumes:
recyclarr_data:

With this setup, /config and /state hold the files to back up, while /data holds only regenerable files. See File Structure for details on what lives in each directory.

Environment​

info

The PUID and PGID environment variables are not supported by the official Recyclarr Docker image. These are not built-in Docker features.

Recyclarr's Docker container is rootless. Use the user property (in Docker Compose) or the --user option (with the Docker CLI) to specify the user and group IDs.

  • RECYCLARR_API_KEY or RECYCLARR_API_KEY_FILE (Required, set only one)
    The server's API key, or the path of a file that contains it. The image has no default, and the server does not start without a key. See API Key.

  • TZ (Default: UTC)
    The time zone for Recyclarr's local time in the container. The sync schedule uses this time zone.

  • RECYCLARR_CONFIG_DIR (Default: /config)
    Override the config directory path inside the container. See Environment Variables.

  • RECYCLARR_DATA_DIR (Default: same as RECYCLARR_CONFIG_DIR)
    Override the data directory path inside the container for ephemeral files (resources, logs). See Environment Variables.

  • RECYCLARR_STATE_DIR (Default: state inside RECYCLARR_CONFIG_DIR)
    Override the state directory path inside the container for sync state and job history. See Environment Variables.

API Key​

The server only accepts requests that include its API key, and it does not start until you give it one. The compose example reads the key from a RECYCLARR_API_KEY variable, which Docker Compose can load from a .env file next to compose.yaml.

  1. Create the .env file with a random key:

    echo "RECYCLARR_API_KEY=$(openssl rand -hex 32)" > .env
  2. Start or recreate the container:

    docker compose up -d

You can also put the key directly in the compose file (- RECYCLARR_API_KEY=your-key-here) or load it with env_file. The key must be at least 32 characters. If the key is missing or too short, the server stops right after it starts, and docker logs recyclarr shows an error that explains why.

The CLI inside the container reads the same variable, so docker exec commands work without any other setup.

To keep the key out of the container's environment, store it in a file and give it to the container as a Compose secret. Set RECYCLARR_API_KEY_FILE instead of RECYCLARR_API_KEY:

services:
recyclarr:
# ...
environment:
- TZ=America/Santiago
- RECYCLARR_API_KEY_FILE=/run/secrets/recyclarr_api_key
secrets:
- recyclarr_api_key

secrets:
recyclarr_api_key:
file: ./recyclarr_api_key.txt

Create the file with openssl rand -hex 32 > recyclarr_api_key.txt. The container's user must be able to read it. The server reads the file again on each request, so a new key takes effect without a restart. Update cli.yml on any other machine that uses the old key.

Configuration Changes​

The server checks your YAML configuration once a minute and applies edits without a restart. Run docker compose logs recyclarr to see whether it reloaded the configuration or found errors. See Configuration Changes.

Changes to settings.yml need a restart:

docker compose restart recyclarr

Scheduling​

By default, the server syncs every configured Sonarr and Radarr instance once a day at midnight, using the time zone set by TZ. To change when syncs run, set server.schedule.cron in settings.yml:

server:
schedule:
cron: 0 4 * * * # Every day at 4:00 AM

See server.schedule for how the server handles overlapping and missed syncs.

Using an External Scheduler​

To start syncs from another scheduler instead (for example, cron on the host), turn off the built-in schedule:

server:
schedule:
enabled: false

Then have your scheduler run the sync command through docker exec:

docker exec recyclarr recyclarr sync

The scheduler can also start syncs through the HTTP API instead.

Running CLI Commands​

The image includes the recyclarr CLI. Run it with docker exec while the container is running. The CLI sends each command to the server in the same container, so the server must be running. See Client and Server for how the CLI and server work together.

Using Docker Compose:

docker compose exec recyclarr recyclarr [command] [options]

Or using Docker directly:

docker exec recyclarr recyclarr [command] [options]

Examples:

# Sync Sonarr and show debug logs
docker exec recyclarr recyclarr sync sonarr --log debug

# Do a preview (dry run) sync for Radarr
docker exec recyclarr recyclarr sync radarr --preview

# Create configs/hd-bluray-web.yml in the container's configuration directory
docker exec recyclarr recyclarr config create -t hd-bluray-web

Syncs you start this way wait in the same queue as scheduled syncs. See the CLI reference for all commands.

HTTP API​

The server listens on port 7982 inside the container. The CLI inside the container does not need this port published. To call the API from outside the container, publish the port in your compose file:

services:
recyclarr:
ports:
- 7982:7982

To use a different port on the host, change the first number (for example, 8000:7982). See the API reference for the available endpoints.

The server serves plain HTTP, so the API key is not encrypted on the way to it. Before you publish the port beyond a network you trust, put TLS in front of it. See Network Security.

Every API request must send the API key as a bearer token:

curl -H "Authorization: Bearer $RECYCLARR_API_KEY" http://localhost:7982/api/v1/sync/jobs

To run CLI commands on another machine against this server, set server.base_url and server.api_key in that machine's cli.yml:

server:
base_url: http://recyclarr:7982
api_key: your-key-here

Health Check​

The image has a built-in Docker health check. Every 30 seconds it requests /livez on the management port (7983 inside the container) and marks the container unhealthy when the server does not respond. docker ps and docker compose ps show the result.

The health check works without publishing port 7983. Publish it only when something outside the container needs the health probes or Prometheus metrics, such as an uptime monitor:

services:
recyclarr:
ports:
- 7982:7982
- 7983:7983

Stopping the Container​

When the container stops, the server cancels any sync that is running. Changes already applied to Sonarr or Radarr stay in place. Queued syncs do not run when the container starts again.

Troubleshooting​

See the Troubleshooting page.

Advanced Configuration​

Read-Only Container​

For additional security, the container filesystem can be made read-only. This requires two changes in Docker Compose:

  1. Add the read_only: true setting to the service configuration.
  2. Mount /tmp (inside the container) to a volume. This path must be writable for Recyclarr to run. Using tmpfs is recommended since these files are temporary by design, and keeping them in memory offers some performance benefits.

Using the example compose.yaml from the top of this page, add the following:

services:
recyclarr:
image: ghcr.io/recyclarr/recyclarr:9
read_only: true # <-- Add this to enable read-only mode
tmpfs: /tmp # <-- Mount /tmp to a volume
# ...

Prevent in-container privilege escalation​

For additional security, run Recyclarr with --security-opt=no-new-privileges to prevent privilege escalation. This prevents the container from gaining new privileges via setuid and setgid binaries like su and sudo.

Add security_opt: ['no-new-privileges:true'] to the service configuration:

services:
recyclarr:
image: ghcr.io/recyclarr/recyclarr:9
security_opt: ['no-new-privileges:true'] # Add this line
# ...