This is the default deployment mode. Enabled Renamarr jobs run immediately, repeat every hour unless configured otherwise, and the container remains running with restart: unless-stopped.
- Copy/Rename config.yml.example to
config.yml - Update
config.ymlas needed.- See Configuration for further explanation
- Bring up app using provided docker-compose.yml
Each invocation runs every enabled job once and exits without restarting when no recurring jobs are configured.
- Copy/Rename config.yml.example to
config.yml - Update
config.ymlas needed- Set
sonarr[].renamarr.schedule.enabledtofalsefor every enabled Renamarr instance. - Set
radarr[].renamarr.schedule.enabledtofalsefor every enabled Renamarr instance.
- Set
- Invoke the app from your scheduler using the provided docker-compose.yml
Image tags ending in -dev can be used for troubleshooting purposes, but are not intended for normal usage. Pre-release images are tagged with their specific release version and do not change or overwrite the latest or latest-dev tags.
This job uses the Sonarr API/Radarr API to do the following
Sonarr API access uses devopsarr/sonarr-py, and Radarr API access uses devopsarr/radarr-py. Existing Sonarr and Radarr configuration remains unchanged.
- Iterate over all items (Movies or Series)
- Checks if any items need to be renamed
- Radarr get_api_v3_rename
- Sonarr get_api_v3_rename
- Triggers a rename on any item that need be renamed
- Series renames are batched up, for one rename call per series
- Movie renames are discovered per movie, then initiated in one batch command with all movie IDs that need a rename
- Checks if any items need to be renamed
This config option is useful if you have audio/video codec information as part of your mediaformat, and you are transcoding files after import. This will initiate a rescan of the files in your library, so that the mediainfo will be updated. Then renamarr will come through and detect changes, and rename the files
This config option will rename series or movie folders when they no longer match your configured MediaFormat.
- uses /api/v3/series/{id}/folder endpoint to determine if the series folder requires an update
- uses /api/v3/series/editor endpoint to update series rootFolderPath to it's current value
- moving the folder in place
- uses /api/v3/movie/{id}/folder endpoint to determine if the movie folder requires an update
- uses /api/v3/movie/editor endpoint to update movie rootFolderPath to it's current value
- moving the folder in place
- sends a Sonarr
RescanSeriescommand to rescan series after successful folder moves - sends a Radarr
RefreshMoviecommand to rescan movies after successful folder moves - Series and movies are processed in bulk at the end of the run, per root folder
Analysis, file rename, and post-move rescan commands use the same polling settings. Renamarr checks each command immediately, then checks every command_polling.check_interval_seconds until it succeeds, reports a completed failure, encounters a status-check error, or reaches command_polling.timeout_seconds. The timeout applies separately to each asynchronous command; it is not an HTTP request or whole-scan timeout.
The application runs enabled jobs immediately on startup. Renamarr jobs repeat every hour by default. Set renamarr.schedule.enabled to false to run once, or configure the interval in days, hours, and minutes.
The process remains running while at least one recurring job is registered. It exits after the initial run when every enabled Renamarr job has schedule.enabled set to false.
Logs are always written to stdout.
Each successful run ends with file and folder rename totals in the following format:
Finished Renamarr successfully | file renames: [ success=0, failed=0, skipped=373 ] | folder renames: [ success=0, failed=0, skipped=373 ]
Failed runs report the same totals at ERROR level after their individual errors. At DEBUG level, each run also reports its item count and analysis outcomes.
Set sonarr[].renamarr.log_to_file or radarr[].renamarr.log_to_file to true to enable per-instance log files. If the target log path is not writable, renamarr logs a warning to stdout and continues running without logging to file.
When enabled, logs for that instance are written under LOG_DIR (/logs by default) using one of these paths:
sonarr/<name>.logradarr/<name>.log
Don't forget to mount /logs outside the container to persist log files
To avoid permission issues when creating log files, set the user option in docker-compose to match the desired runtime UID/GID.
| Environment Variable | Description | Default |
|---|---|---|
LOG_LEVEL |
Log level passed to Loguru for stdout and file sinks. DEBUG also adds source location to log lines. |
INFO |
LOG_DIR |
Directory containing per-instance log files. | /logs |
LOG_ROTATION |
Rotation schedule passed to Loguru for file log rotation. | 00:00 |
LOG_RETENTION |
Retention period passed to Loguru for rotated log files. | 7 days |
For more details on LOG_RETENTION or LOG_ROTATION values, see the official documentation
| Name | Type | Required | Default Value | Description |
|---|---|---|---|---|
sonarr |
Array | No | [] | Sonarr instances; when present, must contain at least one instance |
sonarr[].name |
string | Yes | N/A | user friendly instance name, used in log messages |
sonarr[].url |
string | Yes | N/A | url for sonarr instance |
sonarr[].api_key |
string | Yes | N/A | api_key for sonarr instance |
sonarr[].renamarr.enabled |
boolean | No | False | enables/disables renamarr functionality |
sonarr[].renamarr.hourly_job |
boolean | No | N/A | Deprecated: compatibility alias for schedule.enabled; an explicit schedule.enabled takes precedence |
sonarr[].renamarr.schedule.enabled |
boolean | No | True | enables recurring Renamarr jobs; when false, Renamarr runs once at startup |
sonarr[].renamarr.schedule.interval.days |
integer | No | 0 | days between Renamarr jobs |
sonarr[].renamarr.schedule.interval.hours |
integer | No | 0 | hours between Renamarr jobs |
sonarr[].renamarr.schedule.interval.minutes |
integer | No | 0 | minutes between Renamarr jobs |
sonarr[].renamarr.analyze_files |
boolean | No | False | This will initiate a rescan of the files in your library. This is helpful if you are transcoding files, and the audio/video codecs have changed. |
sonarr[].renamarr.rename_folders |
boolean | No | False | This will rename series folders when the current series folder no longer matches your MediaFormat |
sonarr[].renamarr.log_to_file |
boolean | No | False | writes logs for this Sonarr instance to LOG_DIR/sonarr/<name>.log with daily rotation |
sonarr[].renamarr.command_polling.timeout_seconds |
integer | No | 120 | maximum time to wait for each analysis, rename, or rescan command |
sonarr[].renamarr.command_polling.check_interval_seconds |
integer | No | 3 | seconds between command-status checks after the immediate first check |
radarr |
Array | No | [] | Radarr instances; when present, must contain at least one instance |
radarr[].name |
string | Yes | N/A | user friendly instance name, used in log messages |
radarr[].url |
string | Yes | N/A | url for radarr instance |
radarr[].api_key |
string | Yes | N/A | api_key for radarr instance |
radarr[].renamarr.enabled |
boolean | No | False | enables/disables renamarr functionality |
radarr[].renamarr.hourly_job |
boolean | No | N/A | Deprecated: compatibility alias for schedule.enabled; an explicit schedule.enabled takes precedence |
radarr[].renamarr.schedule.enabled |
boolean | No | True | enables recurring Renamarr jobs; when false, Renamarr runs once at startup |
radarr[].renamarr.schedule.interval.days |
integer | No | 0 | days between Renamarr jobs |
radarr[].renamarr.schedule.interval.hours |
integer | No | 0 | hours between Renamarr jobs |
radarr[].renamarr.schedule.interval.minutes |
integer | No | 0 | minutes between Renamarr jobs |
radarr[].renamarr.analyze_files |
boolean | No | False | This will initiate a rescan of the files in your library. This is helpful if you are transcoding files, and the audio/video codecs have changed. |
radarr[].renamarr.rename_folders |
boolean | No | False | This will rename movie folders when the current movie folder no longer matches your MediaFormat |
radarr[].renamarr.log_to_file |
boolean | No | False | writes logs for this Radarr instance to LOG_DIR/radarr/<name>.log with daily rotation |
radarr[].renamarr.command_polling.timeout_seconds |
integer | No | 120 | maximum time to wait for each analysis, rename, or rescan command |
radarr[].renamarr.command_polling.check_interval_seconds |
integer | No | 3 | seconds between command-status checks after the immediate first check |
Schedule interval values must be non-negative integers, and the combined interval cannot exceed 30 days. When scheduling is enabled, the combined interval must be greater than zero. A zero interval is valid only when schedule.enabled is false.
When schedule.interval is omitted or empty, Renamarr uses the default interval of one hour.
Command-polling values must be positive integers. check_interval_seconds cannot exceed timeout_seconds. The section is optional; omitting command_polling, or the entire renamarr section, uses a two-minute timeout and a three-second check interval.
The container publishes application health through Docker's native health status. Renamarr refreshes an internal heartbeat while the scheduler is idle and from a background thread while a job is running. The health check is observational: Docker Compose's restart policy does not restart a running container solely because it becomes unhealthy. A logically stuck job can remain healthy while its heartbeat thread continues running.
The heartbeat is stored under /tmp. Containers invoked by an external scheduler may finish before Docker runs a health check. For these runs, use the container’s completion status and Renamarr logs rather than Docker health status.
The included Compose configurations run Renamarr with a read-only root filesystem. The heartbeat is written to /tmp, so that path is mounted as a writable tmpfs.
When file logging is enabled, /logs must also be mounted as a writable volume; otherwise, Renamarr warns and continues with stdout logging.
See Local Development for local development requirements, environment details, and startup commands.
The mise configuration installs the development toolchain and provides tasks for the common workflows:
mise install
mise run sync
mise run check
mise run audit
mise run docker-build