Migrating to 0.17: config.yaml¶
0.17 consolidates all non-secret configuration into a single config.yaml file. Previously, configuration was split across ~17 environment variables and a separate mappings.yaml. This is a manual, breaking migration — there is no automated converter. The server fails fast at startup if a retired environment variable is still set, printing the variable name and a pointer to this guide.
What changes¶
- A new
config.yamlfile holds all non-secret app settings plus themappings:anddigest:sections that previously lived inmappings.yaml. .envshrinks to secrets and infra-interpolation values only (see Stays in .env).mappings.yamlandmappings.lockare retired. The equivalent sections move verbatim intoconfig.yaml.- The validation cache file is now
config.lock(same mechanism asmappings.lock, retargeted). - The CLI binary is renamed:
notifycat-mapping→notifycat-config.
Retired environment variables¶
Every variable in this table is now a key in config.yaml. Remove it from .env / your deployment secrets and add the corresponding YAML key instead.
| Retired env var | config.yaml path | Notes |
|---|---|---|
ADDR |
server.addr |
Default :8080 |
LOG_LEVEL |
server.log_level |
Default info |
LOG_FORMAT |
server.log_format |
Default text |
DATABASE_URL |
database.url |
Default file:./data/notifycat.db; see Docker note |
NOTIFYCAT_MAPPINGS_FILE |
(removed) | Mappings content now lives directly under config.yaml's mappings: key; no separate file path needed |
SLACK_BASE_URL |
slack.base_url |
Default https://slack.com |
SLACK_REACTIONS_ENABLED |
slack.reactions.enabled |
Default true |
SLACK_REACTION_NEW_PR |
slack.reactions.new_pr |
Default eyes |
SLACK_REACTION_MERGED_PR |
slack.reactions.merged_pr |
Default twisted_rightwards_arrows |
SLACK_REACTION_CLOSED_PR |
slack.reactions.closed_pr |
Default x |
SLACK_REACTION_PR_APPROVED |
slack.reactions.approved |
Default white_check_mark |
SLACK_REACTION_PR_COMMENTED |
slack.reactions.commented |
Default speech_balloon |
SLACK_REACTION_PR_REQUEST_CHANGE |
slack.reactions.request_change |
Default exclamation |
SLACK_REACTION_BOT_REVIEW |
slack.reactions.bot_review |
Default robot_face |
GITHUB_BASE_URL |
github.base_url |
Default https://api.github.com |
NOTIFYCAT_MESSAGE_TTL_DAYS |
cleanup.message_ttl_days |
Default 30 |
NOTIFYCAT_IGNORE_AI_REVIEWS |
reviews.ignore_ai_reviews |
Default false |
NOTIFYCAT_DEPENDABOT_FORMAT |
reviews.dependabot_format |
Default true |
Stays in .env¶
Only these values remain in .env:
| Variable | Required | Notes |
|---|---|---|
GITHUB_WEBHOOK_SECRET |
Required | The secret configured on the GitHub webhook |
SLACK_BOT_TOKEN |
Required | Bot token starting with xoxb- |
GITHUB_TOKEN |
Optional | PAT for notifycat-config validate and notifycat-doctor; if unset, webhook-coverage check is skipped |
DOMAIN |
Required for Docker Compose | Public DNS name; Caddy uses it for TLS and can't read config.yaml. Also set server.domain in config.yaml for notifycat-doctor. |
ACME_EMAIL |
Required for Docker Compose | Contact email for Let's Encrypt registration |
Moving mappings.yaml into config.yaml¶
The content of mappings.yaml moves verbatim into config.yaml. The per-org schema is unchanged in 0.17.
Before (mappings.yaml):
digest:
enabled: true
schedule: "0 9 * * *"
mappings:
acme:
channel: C0123ABCDE
mentions: ["<@U0123ALICE>"]
repositories:
- api
- web
After (inside config.yaml):
digest:
enabled: true
schedule: "0 9 * * *"
mappings:
acme:
channel: C0123ABCDE
mentions: ["<@U0123ALICE>"]
repositories:
- api
- web
The mappings: and digest: keys become top-level sections in config.yaml alongside the app-settings sections. No schema changes to the per-org entries.
Fail-fast on retired variables¶
The server detects every retired variable listed above at startup. If any is set, startup is aborted before the config is loaded, with a message listing the offending variables:
config: these env vars are no longer read and now live in config.yaml: [SLACK_REACTION_NEW_PR LOG_LEVEL] — see docs/0.17-config-migration.md
Remove the listed variables from your environment (.env, Docker env block, or deployment secret manager) and add the corresponding config.yaml keys before restarting.
Docker note¶
Prior to 0.17 the Docker image set DATABASE_URL=file:/app/notifycat.db as a built-in default. The image no longer sets this variable. Operators must add database.url to their config.yaml:
database:
url: "file:/app/notifycat.db" # historical image path — use this if you were relying on the old default
If you mount a /data volume for persistence, use "file:/data/notifycat.db" instead.
CLI rename¶
The notifycat-mapping binary is renamed to notifycat-config. Subcommands and flags are unchanged.
| Old | New |
|---|---|
notifycat-mapping list |
notifycat-config list |
notifycat-mapping validate |
notifycat-config validate |
notifycat-mapping validate <owner/repo> |
notifycat-config validate <owner/repo> |
notifycat-mapping validate --force |
notifycat-config validate --force |
Update any scripts, CI jobs, or operator runbooks that call notifycat-mapping.
Migration checklist¶
- Create
config.yamlfromconfig.example.yaml— fill in any non-default values you had in.env. - Copy the
mappings:anddigest:blocks frommappings.yamlintoconfig.yamlas top-level keys. - Trim
.envto secrets +DOMAIN+ACME_EMAILonly (see Stays in .env). - Delete
mappings.yamlandmappings.lockfrom your deployment directory (they are superseded byconfig.yamlandconfig.lock). - Run
notifycat-config validateto populateconfig.lock. - Run
notifycat-doctorto confirm the full preflight. - Deploy and verify startup logs show no
FATAL: environment variablelines.