-
Notifications
You must be signed in to change notification settings - Fork 1
Configuration
CHUB reads a single YAML file on startup: config.yml, kept in ${CONFIG_DIR} (in Docker, that's /config/config.yml — i.e. the host folder you mounted as /config).
You can edit config.yml by hand, but the Settings pages in the web UI are the easier path — every Settings page writes back through a validated API. If you do hand-edit the file:
- Keep permissions at
0600— it contains API keys. - CHUB revalidates the whole file on startup. If validation fails, CHUB won't start and the container log tells you which field is wrong.
At the top level, config.yml has these sections:
schedule: {} # when each module runs
instances: {} # your Radarr / Sonarr / Lidarr / Plex connections
notifications: {} # Discord / Email / Apprise per module
general: {} # global toggles
user_interface: {} # theme
auth: {} # your admin user (managed by the UI)
# One section per module
sync_gdrive: {}
unmatched_assets: {}
poster_renamerr: {}
border_replacerr: {}
upgradinatorr: {}
renameinatorr: {}
nohl: {}
labelarr: {}
health_checkarr: {}
jduparr: {}
nestarr: {}
poster_cleanarr: {}Unused module sections can be omitted entirely — CHUB uses safe defaults for anything missing.
Global toggles, shown in Settings → General:
general:
log_level: info # debug | info | warning | error
update_notifications: false # show a banner when a new CHUB release is out
max_logs: 9 # how many rotated log files to keep per module
webhook_initial_delay: 30 # seconds to wait after an inbound webhook before acting
webhook_retry_delay: 60 # seconds between retries
webhook_max_retries: 3
webhook_secret: "" # empty = webhooks unauthenticated; set to require a shared secret
duplicate_exclude_groups: [] # duplicate group IDs the UI should hideIf webhook_secret is set, every inbound webhook must send X-Webhook-Secret: <secret> (or ?secret=<secret> in the URL). See Webhooks.
Managed by the web UI. Don't edit unless you're trying to reset things.
auth:
username: admin
password_hash: "$2b$12$..."
jwt_secret: "<random>"
token_expiry_hours: 24To reset the admin password, see Installation → Resetting the admin password.
Your Radarr, Sonarr, Lidarr, and Plex connections. The key under each service is the name you'll reference elsewhere in config.yml (radarr_main, sonarr_4k, etc.).
instances:
radarr:
radarr_main:
url: http://radarr:7878
api: <api_key>
enabled: true
radarr_4k:
url: http://radarr-4k:7878
api: <api_key>
enabled: true
sonarr:
sonarr_main:
url: http://sonarr:8989
api: <api_key>
lidarr:
lidarr_main:
url: http://lidarr:8686
api: <api_key>
plex:
plex_main:
url: http://plex:32400
api: <x_plex_token>For Plex, the api field is the X-Plex-Token, not your Plex Pass login. Plex has a short guide for finding your token.
About URLs: CHUB refuses to connect to cloud-metadata addresses or unrouteable ranges as a safety check. Use a normal IP or hostname your container can resolve — http://radarr:7878 works if CHUB and Radarr share a Docker network.
Testing: in Settings → Instances, each instance has a Test button. Run it after adding or editing an entry.
One entry per module that should run on a schedule. Anything not listed here is manual-only (triggered by you from the dashboard, or by a webhook).
schedule:
poster_renamerr:
type: cron
expression: "0 */4 * * *" # every 4 hours
jduparr:
type: interval
minutes: 720 # every 12 hours
upgradinatorr:
type: cron
expression: "15 3 * * *" # daily at 03:15type is either cron (with expression) or interval (with minutes). The Settings → Schedule page has a form that writes this for you.
CHUB also runs a built-in system-health probe every 6 hours. You don't configure it.
One entry per module that should send notifications, plus an optional main entry for global notifications.
notifications:
main:
discord:
enabled: true
webhook: https://discord.com/api/webhooks/...
poster_renamerr:
discord:
enabled: true
webhook: https://discord.com/api/webhooks/...
mention_role: "123456789"
upgradinatorr:
apprise:
enabled: true
url: "discord://..."
health_checkarr:
email:
enabled: true
from: chub@example.com
to: [you@example.com]
smtp_host: smtp.example.com
smtp_port: 587
username: chub
password: <smtp_password>Discord, Email, and Apprise are supported. Apprise's URL format covers dozens of other services — see the Apprise README for the catalog.
user_interface:
theme: dark # light | darkThis is the server-wide default. Each browser also remembers its own choice, so toggling the theme in the header sticks on that device.
Every module has its own section. See Modules for what each one does and the full set of fields; a few common shapes:
poster_renamerr:
dry_run: false
action_type: copy # copy | move | hardlink
source_dirs: [/kometa]
destination_dir: /posters
run_border_replacerr: false
run_cleanarr: false
report_unmatched_assets: false
instances:
- radarr_main
- sonarr_main
- plex_main:
library_names: ["Movies", "TV Shows"]
add_posters: trueupgradinatorr:
dry_run: false
instances_list:
- instance: radarr_main
count: 10
tag_name: chub-upgradinatorr
ignore_tag: ignore
unattended: false
search_mode: upgrade # upgrade | missing | cutoffborder_replacerr:
source_dirs: [/posters]
destination_dir: /posters
border_width: 26
border_colors: ["#ff7300"]
holidays:
- name: halloween
schedule: "10-01:10-31"
colors: ["#FF6600", "#000000"]labelarr:
mappings:
- app_instance: sonarr_main
labels: [watched, favorite]
plex_instances:
- instance: plex_main
library_names: ["TV Shows"]When CHUB returns your config to the UI, it replaces these fields with ******** so they don't leak into browser storage or screenshots:
-
api,api_key -
access_token,refresh_token,token,client_secret -
password_hash,jwt_secret,webhook_secret
When you save the config back through the UI, any field still equal to ******** is kept as-is — so editing non-sensitive fields in the UI won't wipe your API keys.
The container log prints which field failed validation. Either fix the field or remove the bad section and restart — CHUB will fall back to defaults for anything missing.
docker compose logs chubSee Troubleshooting for more.