Every variable¶
Every variable the stack reads, grouped as on Settings → Stack
environment, which writes any of them for you to paste into your
settings: Portainer's environment variables, or .env with Docker Compose.
Only FERRULE_VERSION is required; everything else has a default or is
optional.
- Paid: used only during the trial or with a Business or MSP licence.
- Secret: never shown back by Ferrule. Settings writes a placeholder, or makes a new key or password for you.
- Stack: read by Docker Compose, for another service, a port or an overlay, rather than by Ferrule itself.
Stack¶
| Variable | Default | What it does |
|---|---|---|
COMPOSE_PROFILESstack |
— | Optional services this stack also runs. Whether Portainer passes it on depends on its version. One of: gotify, igotify, postgres, apprise. |
WEB_PORTstack |
8090 |
The dashboard's port on the Docker host. |
TZ |
— | The time zone for quiet hours, backups and the daily inventory. Unset is UTC. For example America/Los_Angeles. |
DASHBOARD_URL |
— | Where this dashboard is reached: notifications link to it, and OIDC returns to it. For example https://ferrule.example.com. |
FERRULE_VERSIONstack |
— | Required: the release to run, such as 0.9.0, or qa for what is under test. Never latest. For example 0.9.0. |
FERRULE_IMAGEstack |
git.uglyhousesneedlove.com/steve/ferrule |
Where the image is published. Change it only if told to. |
VERSIONstack |
gitops |
With docker-compose.build.yml: the version label of a build from source. |
UniFi¶
| Variable | Default | What it does |
|---|---|---|
UNIFI_ENABLED |
true |
false turns off Network, Protect, WAN and the probe, for a stack that watches only hypervisors and storage. |
UNIFI_HOST |
— | The console that runs Network, by its address. For example https://192.168.1.1. |
UNIFI_API_KEYsecret |
— | Settings → Control Plane → Integrations on the console. |
UNIFI_USERNAME |
— | A local-only, read-only admin, with MFA off. It reaches fans, port errors, optics and the WAN history. For example telemetry. |
UNIFI_PASSWORDsecret |
— | That admin's password. |
UNIFI_SITE |
default |
The site's internal name, if you renamed it. |
UNIFI_OS |
true |
false only for a self-hosted standalone Network controller. |
UNIFI_VERIFY_TLS |
false |
true once the consoles have trusted certificates. |
POLL_INTERVAL |
30s |
How often devices are read. Under 10s is clamped. |
REQUEST_TIMEOUT |
20s |
How long one request to a console may take. |
Protect¶
| Variable | Default | What it does |
|---|---|---|
PROTECT_ENABLED |
true |
false if you do not run Protect. |
PROTECT_BOOTSTRAP |
true |
false keeps to the supported Protect API, and gives up disk health and NVR temperatures. |
PROTECT_HOST |
— | Only when Protect runs on its own console, such as a UNVR. It needs its own credentials. For example https://192.168.1.4. |
PROTECT_API_KEYsecret |
— | An API key made on the Protect console itself. |
PROTECT_USERNAME |
— | A local-only, read-only admin on the Protect console. For example telemetry. |
PROTECT_PASSWORDsecret |
— | That admin's password. |
WAN and probe¶
| Variable | Default | What it does |
|---|---|---|
WAN_ENABLED |
true |
false if there is no WAN here worth watching. |
WAN_POLL_INTERVAL |
60s |
Paces the WAN history reads. The floor is 30s. |
WAN_DASHBOARD_SCALE |
24h |
7d asks the controller for its widest window of outages. One of: 24h, 7d. |
SPEEDTEST_INTERVAL |
15m |
How often the speed test history is read again. |
BACKFILL_ON_START |
true |
false records from now on only, without importing the controller's recent history. |
PROBE_TARGETS |
— | Turns the demarcation probe on. wan_next_hop is your ISP's first router, written literally. Never 192.168.100.1. For example lan_gateway=192.168.1.1,wan_next_hop=203.0.113.1,internet_control=1.1.1.1. |
PROBE_INTERVAL |
60s |
Time between probe rounds. The floor is 15s. |
PROBE_COUNT |
10 |
Echoes per target in each round. |
PROBE_TIMEOUT |
2s |
How long each echo is waited for. |
Sources¶
| Variable | Default | What it does |
|---|---|---|
SOURCE_1 … SOURCE_8 |
— | One hypervisor or storage system. Settings → Add a source writes the line. For example proxmox https://pve1.lab:8006 name=pve-lab user=telemetry@pve!ro. |
SOURCE_1_SECRET … SOURCE_8_SECRETsecret |
— | The token, password or key for its slot. |
History and archive¶
| Variable | Default | What it does |
|---|---|---|
RETENTIONstack |
13w |
How long VictoriaMetrics keeps history. Settings → History storage plans it. For example 26w. |
LEDGER_RETENTION |
8760h |
How long the archive keeps outages, alerts and events. |
License¶
| Variable | Default | What it does |
|---|---|---|
FERRULE_LICENSEsecret |
— | A license key, one line starting FERRULE1. Unset runs the trial, then Community. |
Sign-in¶
| Variable | Default | What it does |
|---|---|---|
ADMIN_USERNAME |
admin |
The local admin's name. |
ADMIN_PASSWORDsecret |
— | Turns sign-in on, free in every edition. At least 12 characters. Changing it: A new admin password signs everyone out. |
SESSION_TTL |
168h |
How long a sign-in lasts. |
METRICS_TOKENsecret |
— | Lets a Prometheus scraper read /metrics with Authorization: Bearer and this token. |
SETTINGS_KEYpaid, secret |
— | Needed for local users and groups; encrypts them on the volume. Keep a copy outside the stack. Changing it: A new key cannot read the users and groups the old one encrypted: they would be lost. Export settings first. |
Single sign-on¶
| Variable | Default | What it does |
|---|---|---|
OIDC_ISSUERpaid |
— | The provider's issuer URL. Redirect URI: DASHBOARD_URL/auth/oidc/callback. For example https://login.microsoftonline.com/<tenant>/v2.0. |
OIDC_CLIENT_IDpaid |
— | The application's client ID at the provider. |
OIDC_CLIENT_SECRETpaid, secret |
— | The application's client secret. |
OIDC_ROLESpaid |
— | Who gets which role: who:role entries separated by ;. Anyone matching nothing is refused. For example ferrule-admins:admin; it-team:operator; @example.com:viewer. |
OIDC_NAMEpaid |
— | The button's label: Sign in with … For example Microsoft. |
OIDC_SCOPESpaid |
— | Some providers need groups added. For example openid profile email. |
OIDC_GROUPS_CLAIMpaid |
— | Where the provider puts groups. For example groups. |
OIDC_REDIRECT_URLpaid |
— | Only if it is not DASHBOARD_URL plus /auth/oidc/callback. |
LDAP_URLpaid |
— | ldaps://, or ldap:// with STARTTLS. Plain ldap:// is refused. For example ldaps://dc1.corp.example. |
LDAP_STARTTLSpaid |
false |
true for ldap:// with STARTTLS. |
LDAP_VERIFY_TLSpaid |
true |
false only to try things out. |
LDAP_CA_CERTpaid |
— | Your internal CA's certificate, when the directory's is not publicly trusted. |
LDAP_BIND_DNpaid |
— | A read-only service account that can search for users. For example CN=svc-ferrule,OU=Service,DC=corp,DC=example. |
LDAP_BIND_PASSWORDpaid, secret |
— | That account's password. |
LDAP_BASE_DNpaid |
— | Where to search. For example DC=corp,DC=example. |
LDAP_ROLESpaid |
— | Group DNs to roles, from each user's memberOf, separated by ;. For example CN=Ferrule Admins,OU=Groups,DC=corp,DC=example:admin. |
LDAP_USER_FILTERpaid |
— | Covers Active Directory and OpenLDAP as it is. For example (\|(uid={user})(sAMAccountName={user})(userPrincipalName={user})). |
LDAP_GROUP_ATTRpaid |
— | Direct membership only; nested groups are not followed. For example memberOf. |
Notification channels¶
| Variable | Default | What it does |
|---|---|---|
GOTIFY_URL |
— | Your Gotify, or http://gotify for the bundled one. For example http://gotify. |
GOTIFY_TOKENsecret |
— | An application token from Gotify. |
NTFY_URLsecret |
— | The topic's full URL. On ntfy.sh the topic is the secret, so it is treated as one. |
NTFY_TOKENsecret |
— | An access token, if the topic needs one. |
PUSHOVER_TOKENsecret |
— | The application's token. |
PUSHOVER_USERsecret |
— | Your user or group key. |
DISCORD_WEBHOOK_URLsecret |
— | Server settings → Integrations → Webhooks. |
SMTP_HOST |
— | The mail server. Email also needs SMTP_FROM and SMTP_TO. For example smtp.example.com. |
SMTP_PORT |
587 |
587 for STARTTLS, 465 for TLS. |
SMTP_TLS |
— | Unset is starttls, or tls on port 465. A password is never sent unencrypted. One of: starttls, tls, none. |
SMTP_USERNAME |
— | If the server needs a sign-in. |
SMTP_PASSWORDsecret |
— | That sign-in's password. |
SMTP_FROM |
— | The sender address. For example [email protected]. |
SMTP_TO |
— | Where to send; several, comma separated. For example [email protected], [email protected]. |
SLACK_WEBHOOK_URLpaid, secret |
— | An incoming webhook from a Slack app. |
TEAMS_WEBHOOK_URLpaid, secret |
— | A Workflows webhook: Post to a channel when a webhook request is received. |
PAGERDUTY_ROUTING_KEYpaid, secret |
— | An Events API v2 integration key. Critical alerts only. |
WEBHOOK_URLpaid, secret |
— | JSON to Home Assistant, n8n or anything else. |
WEBHOOK_SECRETpaid, secret |
— | Signs each body: X-Ferrule-Signature carries its HMAC. |
APPRISE_URLpaid |
— | An apprise-api server, such as the bundled one. For example http://apprise:8000. |
APPRISE_URLSpaid, secret |
— | The services to notify, as Apprise URLs separated by spaces. |
APPRISE_KEYpaid, secret |
— | A configuration stored on the Apprise server, instead of APPRISE_URLS. |
What notifies¶
| Variable | Default | What it does |
|---|---|---|
NOTIFY_DEFAULT |
bad |
The lowest severity that notifies. Settings → Notifications sets it. One of: bad, warn, off. |
NOTIFY_RULES |
— | Overrides by tab or alert type. Settings → Notifications writes them. For example wan=warn port_slow=off. |
NOTIFY_DELAY |
2m |
Send only if still active this long later. |
NOTIFY_ON_CLEAR |
true |
Also send when an alert clears. |
NOTIFY_REPEAT |
off |
Send a critical alert again while it is still active: off, or how often. For example 4h. |
NOTIFY_QUIET |
— | Only critical gets through; warnings arrive as one summary after. Read in TZ. For example 22:00-07:00. |
Gotify and iGotify¶
| Variable | Default | What it does |
|---|---|---|
GOTIFY_ADMIN_USERstack |
admin |
The bundled Gotify's admin. |
GOTIFY_ADMIN_PASSWORDsecret, stack |
— | Set it: unset, the bundled Gotify's admin password is admin. Changing it: Gotify reads this only when it first starts. Change the password in Gotify itself. |
GOTIFY_PORTstack |
8091 |
The bundled Gotify's port on the Docker host. |
IGOTIFY_PORTstack |
8092 |
The bundled iGotify's port on the Docker host. |
IGOTIFY_GOTIFY_URLSstack |
http://gotify |
The Gotify iGotify relays from. |
IGOTIFY_CLIENT_TOKENSsecret, stack |
— | Only when Gotify and iGotify are not on public domains; then set all three. |
IGOTIFY_SECNTFY_TOKENSsecret, stack |
— | Only when Gotify and iGotify are not on public domains; set with IGOTIFY_CLIENT_TOKENS. |
APPRISE_PORTstack |
8093 |
The bundled Apprise's port on the Docker host. |
Backups¶
| Variable | Default | What it does |
|---|---|---|
BACKUP_NAME |
ferrule |
Names this site's backups. Each site sharing a target needs its own; a rebuilt site keeps its name. |
BACKUP_KEYsecret |
— | Encrypts backups. Keep a copy outside the stack: without it an encrypted backup cannot be restored. Changing it: Backups already taken stay under the old key. Keep it, or they cannot be restored. |
BACKUP_AT |
03:30 |
When the daily archive backup runs, in TZ. |
BACKUP_HISTORY |
true |
Also back up history, weekly. |
BACKUP_HISTORY_DAY |
sunday |
Which day. One of: sunday, monday, tuesday, wednesday, thursday, friday, saturday. |
BACKUP_KEEP |
14 |
Archive backups kept on each target. |
BACKUP_HISTORY_KEEP |
4 |
History backups kept on each target. |
BACKUP_RESTORE |
auto |
off never restores by itself into an empty archive. One of: auto, off. |
Backup share¶
| Variable | Default | What it does |
|---|---|---|
BACKUP_NFS_SERVERstack |
— | With docker-compose.backup-nfs.yml under the stack's Additional paths. For example 192.168.1.20. |
BACKUP_NFS_PATHstack |
— | The export. For example /volume1/backups. |
BACKUP_NFS_OPTIONSstack |
nfsvers=4.1,rw,soft,timeo=150 |
Mount options. |
BACKUP_SMB_SERVERstack |
— | With docker-compose.backup-smb.yml under the stack's Additional paths. For example nas.lan. |
BACKUP_SMB_SHAREstack |
— | The share's name. For example backups. |
BACKUP_SMB_USERNAMEstack |
— | An account that can write to the share. |
BACKUP_SMB_PASSWORDsecret, stack |
— | Its password, with no comma in it. |
BACKUP_SMB_VERSIONstack |
3.0 |
The SMB protocol version. |
Backup to S3¶
| Variable | Default | What it does |
|---|---|---|
BACKUP_S3_ENDPOINTpaid |
— | Wasabi, Backblaze B2, Cloudflare R2, MinIO or AWS. For example s3.us-east-1.wasabisys.com. |
BACKUP_S3_REGIONpaid |
us-east-1 |
Must match the bucket's region. |
BACKUP_S3_BUCKETpaid |
— | Make the bucket first. For example my-ferrule-backups. |
BACKUP_S3_PREFIXpaid |
ferrule |
The folder in the bucket. |
BACKUP_S3_ACCESS_KEYpaid, secret |
— | A key with list, read, write and delete on that bucket only. |
BACKUP_S3_SECRET_KEYpaid, secret |
— | Its secret. |
Inventory¶
| Variable | Default | What it does |
|---|---|---|
INVENTORY |
on |
off stops the daily run; taking one by hand still works. One of: on, off. |
INVENTORY_ATpaid |
02:30 |
When the daily run is taken, in TZ. |
INVENTORY_KEEPpaid |
365 |
Days of runs to keep; 2557 keeps seven years. |
INVENTORY_DB_PASSWORDpaid, secret |
— | The database writer's password. On its own it uses the stack's postgres profile. Changing it: The bundled database keeps the password it was created with. Change it there too (ALTER ROLE ferrule), or the copy stops. |
INVENTORY_DB_READER_PASSWORDpaid, secret |
— | Makes a read-only ferrule_reader login for Grafana and Power BI. At least 12 characters. |
INVENTORY_DB_URLpaid, secret |
— | A PostgreSQL you run instead: postgres://user:password@host:5432/database?sslmode=verify-full. |
INVENTORY_DB_CApaid |
— | Your CA's certificate, for a server whose certificate it signed. Turns on verify-full. |
INVENTORY_DB_BINDstack |
127.0.0.1 |
Where the bundled database listens on the Docker host; 0.0.0.0 for Power BI on another machine. |
INVENTORY_DB_PORTstack |
5432 |
The bundled database's port on the Docker host. |
Assistant¶
| Variable | Default | What it does |
|---|---|---|
AI_1 … AI_4paid |
— | One model the assistant can ask: pick its provider, and the line is written for you. |
AI_1_KEY … AI_4_KEYpaid, secret |
— | The API key for its slot, for a hosted model. |
AI_TIMEOUT |
5m |
How long to wait for an answer, unless a slot says timeout=. |
Assistant: old single-model settings¶
| Variable | Default | What it does |
|---|---|---|
AI_PROVIDERpaid |
— | From before there were slots: one model, used as slot 1 when AI_1 is not set. One of: claude, openai, gemini, xai, llamacpp, lmstudio, ollama, local. |
AI_URLpaid |
— | With AI_PROVIDER: the address of a model you run. For example http://llm.lan:8080/v1. |
AI_MODELpaid |
— | With AI_PROVIDER: the model's name as the provider lists it. For example claude-opus-5-5. |
AI_API_KEYpaid, secret |
— | With AI_PROVIDER: the provider's API key. |
AI_CONTEXTpaid |
— | With AI_PROVIDER: the context window in tokens, when the provider's own figure is not right. For example 32768. |
HMS-Docker¶
| Variable | Default | What it does |
|---|---|---|
TELEMETRY_HOSTNAMEstack |
telemetry.localhost |
With docker-compose.hms-docker.yml: the dashboard's hostname on Traefik. |
GOTIFY_HOSTNAMEstack |
gotify.localhost |
The bundled Gotify's hostname on Traefik. |
IGOTIFY_HOSTNAMEstack |
igotify.localhost |
The bundled iGotify's hostname on Traefik. |
TRAEFIK_MIDDLEWARESstack |
internal-ipallowlist@file |
The Traefik middlewares in front of each. |