Configuration
You can configure Weaver with environment variables for network binding, security, storage paths, Usenet servers, performance limits, logging, and container runtime behavior.
Most day-to-day configuration belongs in the Weaver UI, which writes to Weaver’s database. Use environment variables when a setting must be known before startup, belongs to the host or container, or needs to be managed by your service manager — and for provisioning a fresh instance without clicking through the UI.
This page lists the variables intended for operators to set. Weaver reads a number of additional variables for test harnesses, profiling, benchmarks, and build tooling — those are deliberately not documented here, because setting them on a live instance either does nothing or causes problems.
Some Variables Only Apply On First Run
Section titled “Some Variables Only Apply On First Run”This is the most important thing to know about configuring Weaver from the environment.
The Storage, Usenet Servers, and speed-limit variables are seeds, not overrides. They write into the database only when the matching setting is still empty. Once a value exists — because Weaver already started once, or because you changed it in the UI — the environment variable is silently ignored, with no warning that it was skipped.
Practically that means:
- Set them before the first start to provision an instance from a compose file.
- Changing one later does nothing. Change the setting in the UI instead.
- The entire
WEAVER_SERVER_<N>_*block is skipped if any server already exists.
Rows below that behave this way are marked first-run seed in their Default column. Everything else is read on every start and takes effect immediately.
Weaver Only Listens Locally Until You Say Otherwise
Section titled “Weaver Only Listens Locally Until You Say Otherwise”Weaver listens on 127.0.0.1, so a fresh instance is reachable from the machine it runs on and nowhere else. A desktop or single-machine install needs no network configuration at all.
To reach it from another machine, change Listen address in Settings → Security → Network access and restart Weaver. That is the normal route on a desktop, Windows, Homebrew, or systemd install. It works because the loopback default always leaves the UI reachable from the machine Weaver runs on.
WEAVER_HTTP_BIND_ADDRESS takes precedence over the saved setting, which is what a deployment wants:
- Docker, Podman, Unraid. Nothing to do. The container image ships
WEAVER_HTTP_BIND_ADDRESS=0.0.0.0. A container’s loopback is its own network namespace, so listening there would only make the published port unreachable. Publishing a port is already the deliberate step that exposes it. Because the environment wins, the field is read-only in the UI. - Provisioning from a compose file or unit. Set the variable, and it applies on every start, whatever is saved.
- Override it only for something narrower, such as a host-network container that should answer on loopback alone.
A change made in the UI applies at the next restart. Until then the page shows both the address in force and the one saved for the restart.
The two other fields in that section, Trusted proxy addresses or CIDRs and Remembered-session CIDRs, apply immediately. WEAVER_TRUSTED_PROXIES pins the first from the environment. WEAVER_TRUSTED_CIDRS pins the second only together with WEAVER_ACCESS_MODE=authenticated; on a fresh install without that, it selects the older access settings instead, permanently. Security And Access explains all three and what listening wider does and doesn’t change.
Provisioning A Login Without The Setup Screen
Section titled “Provisioning A Login Without The Setup Screen”Interactive installs answer these questions in the first-run wizard, in the browser. The environment route exists for headless provisioning — a compose file, an Unraid template, a fleet — where nobody clicks through a wizard: WEAVER_BOOTSTRAP_LOGIN_USERNAME, plus exactly one of WEAVER_BOOTSTRAP_LOGIN_PASSWORD or WEAVER_BOOTSTRAP_LOGIN_PASSWORD_FILE, creates the initial login while Weaver starts:
environment: WEAVER_BOOTSTRAP_LOGIN_USERNAME: admin WEAVER_BOOTSTRAP_LOGIN_PASSWORD_FILE: /run/secrets/weaver_login_passwordThis runs only when no login is stored yet — and completing it means the wizard never appears. Once credentials exist, the variables are ignored entirely — they cannot change, reset, or re-assert a password, and leaving them in a compose file is harmless. To rotate a password, use the UI; to recover from a lockout, clear the login with WEAVER_RESET_LOGIN first, which lets bootstrap create a fresh one on the next start.
Unlike the storage and server seeds, a malformed bootstrap request is fatal rather than silent. Setting both password variables, an empty username or password, an unreadable password file, or a username with no password all stop startup with a message naming the variable.
An install upgraded from before 0.12.0 keeps its older access settings until you set WEAVER_ACCESS_MODE=authenticated. While it keeps them, it is asked one question on its first open after the upgrade. Credentials already exist, so there is no login step — only the browser-access question, plus the binding question where that setting is still editable, and a one-click Keep my current setup that stores login-required and preserves pre-upgrade behaviour exactly. WEAVER_TRUSTED_CIDRS suppresses the prompt entirely and WEAVER_HTTP_BIND_ADDRESS removes the binding half of it, so a deployment is never asked about something its environment already pins. See Upgrading.
There Is No Port Or Base URL Variable
Section titled “There Is No Port Or Base URL Variable”Weaver’s listen port and base URL are command-line flags, not environment variables. WEAVER_HTTP_BIND_ADDRESS controls the bind address only.
- Docker hardcodes them in the image command (
--config /config serve --port 9090). To change the port, override the command — setting a variable will not work. See Reverse Proxy for a subpath example. - Homebrew does expose them, through its own service wrapper. See the Homebrew Service rows at the bottom of the table.
Where to set these
Section titled “Where to set these”- Docker — the
environment:block in your compose file. - Homebrew —
$(brew --prefix)/etc/weaver/config.env. The wrapper exports everything in that file, so any variable on this page works there, not just the three it ships with. - Windows — a Windows environment variable, set with
setx NAME valueor through System Properties, then exit and relaunch Weaver from the Start Menu. The tray application hands its environment to the server it starts, so anything set before launch applies. The install directory sits underC:\Program Files, so a.envfile there needs an administrator and is best avoided. - Native or systemd — your service unit’s environment, or the shell that launches Weaver.
- A
.envfile — Weaver loads.envfrom its current working directory at startup. Handy locally, but surprising under systemd, where the working directory may not be what you expect. A malformed.envstops startup.
| Category | Name | Description | Default | Allowed values |
|---|---|---|---|---|
| Network & HTTP | WEAVER_HTTP_BIND_ADDRESS | IP address the web UI and API bind to. Also settable in Settings > Security, which is the easier route on a desktop or service install; this variable wins over that setting when both are present. | 127.0.0.1; the container image ships 0.0.0.0 | IPv4 or IPv6 literal. An unparsable value stops startup. |
| Network & HTTP | WEAVER_HTTP_ALLOWED_HOSTS | Restricts the hostnames Weaver answers. Empty answers every hostname. Once set, only the listed names, localhost, and plain IP addresses are answered, and other names get 421. On an install still using the access settings from before 0.12.0, every name other than localhost and IP addresses must be listed. | empty, every hostname is answered | Comma-separated hostnames or IP addresses, such as weaver,weaver.example.com. Use hostnames only, without https:// or a path. Add :port only when that port must match. |
| Network & HTTP | WEAVER_CORS_ALLOWED_ORIGINS | Browser origins allowed to call the API cross-site. | empty, no cross-origin access | Comma-separated exact origins such as https://host:port. A trailing slash, path, query, or fragment stops startup. |
| Network & HTTP | WEAVER_RSS_ALLOW_PRIVATE_NETWORK | Allows RSS feed fetches to reach private, loopback, and link-local addresses. Needed for a feed hosted on your own LAN. | false | Boolean tokens. An unrecognized value stops startup. |
| Network & HTTP | WEAVER_UI_RESTART | Whether the browser may restart Weaver — the setup screens’ Restart Weaver button and the restart API. Set to 0 when a supervisor Weaver cannot see owns restarts (a service wrapper around the binary, for example), so a UI-triggered exit cannot race it into starting a second copy. | true; container installs are refused regardless | Boolean tokens. An unrecognized value disables the restart rather than enabling it. |
| Network & HTTP | WEAVER_DEPLOYMENT_ENV | Overrides deployment detection. Container-detected installs are never offered the restart button and skip the setup screens’ network question; native is the escape hatch when automatic detection misreads a machine. | unset, detection decides; the container image ships docker | docker, container, or native. Any other value falls back to automatic detection. |
| Auth & Security | WEAVER_ACCESS_MODE | Moves an install that predates 0.12.0 to the 0.12.0 access model, where every browser signs in. Once an install with a login starts with it, the move is permanent and the variable can be removed. An install without a login opens setup instead. New installs already use this model, unless they start with WEAVER_TRUSTED_CIDRS and without this variable, which selects the older model instead. Set both together on a fresh install. | unset | Exactly authenticated. Empty counts as unset; any other value stops startup. |
| Auth & Security | WEAVER_SECURE_COOKIES | Marks every session cookie Secure, so browsers only send it over HTTPS. Without it, Weaver already marks the cookie Secure for sign-ins made over HTTPS, directly or through a trusted proxy that sends X-Forwarded-Proto: https. | false | Boolean tokens. An unrecognized value stops startup. |
| Auth & Security | WEAVER_METRICS_AUTH_REQUIRED | Requires authentication on the Prometheus metrics endpoint. Turn off only on a trusted network. | true | Boolean tokens. An unrecognized value stops startup. |
| Auth & Security | WEAVER_STRICT_SECURITY | Refuses post-processing script execution outright. On an install still using the access settings from before 0.12.0, it also refuses to start while the UI listens beyond loopback without a login, or while any network skips the login. | false | Boolean tokens. Post-processing scripts are refused when they would run, not at startup, so turning it on never strands a running instance. |
| Auth & Security | WEAVER_TRUSTED_CIDRS | With WEAVER_ACCESS_MODE=authenticated, pins Remembered-session CIDRs: the networks where Remember this browser is honoured. Browsers still sign in. Matched against the browser’s resolved address, which behind a proxy is only real when the proxy is trusted. Without WEAVER_ACCESS_MODE, a fresh install started with this variable adopts the access settings from before 0.12.0, permanently; on those settings it gives the listed networks full administrative access without logging in while no login exists, logs a warning at every start, and cannot be combined with WEAVER_STRICT_SECURITY. | empty; the list is managed in Settings → Security, where empty means browsers can be remembered anywhere | Comma-separated CIDRs such as 192.168.1.0/24,fd00::/8. An empty entry or an invalid CIDR stops startup. Makes the field read-only. |
| Auth & Security | WEAVER_TRUSTED_PROXIES | Pins Trusted proxy addresses or CIDRs: reverse proxies whose forwarded browser address Weaver believes. From those addresses Weaver reads the browser from X-Forwarded-For and HTTPS from X-Forwarded-Proto. Forwarding headers from anywhere else are ignored. Setting it also makes first-run setup ask for the setup code. On an install still using the access settings from before 0.12.0, this variable is the only way to set trusted proxies. | empty; the list is managed in Settings → Security | Comma-separated addresses or CIDRs, such as 172.20.0.5; a bare address means that host alone. An empty entry or an invalid value stops startup rather than being skipped. List only proxies you run, never a Docker gateway or a whole private range. |
| Auth & Security | WEAVER_BOOTSTRAP_LOGIN_USERNAME | Username for a login created automatically on a first start, so an instance can be provisioned without visiting the setup screen. | first-run only; unset | Non-empty after trimming, valid UTF-8. Requires exactly one of the two password variables; an empty or lone username stops startup. |
| Auth & Security | WEAVER_BOOTSTRAP_LOGIN_PASSWORD | Password for the bootstrap login. | first-run only; unset | Non-empty, valid UTF-8. Setting this and the file variable stops startup. |
| Auth & Security | WEAVER_BOOTSTRAP_LOGIN_PASSWORD_FILE | Reads the bootstrap password from a file instead, so it never appears in a compose file or process list. | first-run only; unset | Path to a regular file containing UTF-8. One trailing newline is stripped. A missing file, a directory, non-UTF-8, or an empty password stops startup. |
| Auth & Security | WEAVER_REQUIRE_SETUP_CODE | Makes first-run setup ask for the one-time setup code even when Weaver listens on loopback only. Installs listening beyond loopback, or behind WEAVER_TRUSTED_PROXIES, always ask for it. | first-run only; unset | 1 or true, in any case. Any other value leaves the default. |
| Auth & Security | WEAVER_ENCRYPTION_KEY | Master key encrypting stored credentials such as Usenet passwords. Set this on any host without a usable OS keystore, or credentials are lost on restart. | unset, falls back to the OS keystore, then a Docker secret, then a key file | Base64 key. Invalid base64 or wrong length stops startup. Never copied into the data directory. |
| Auth & Security | WEAVER_RESET_LOGIN | Clears stored login credentials at startup. If the bootstrap variables are set, they recreate the login in the same start; otherwise setup opens again for a new login, with a setup code when Weaver listens beyond loopback. Use it to recover from a lockout, then unset it. | unset | Exactly 1 or true, case-sensitive and not trimmed. TRUE and 1 are ignored. Logs a warning when it fires. |
| Storage & Paths | WEAVER_DATABASE_URL | Points Weaver at an external PostgreSQL database instead of the local SQLite file. | unset, SQLite at <config-dir>/weaver.db | postgres://, postgresql://, or sqlite:. Any other scheme stops startup. |
| Storage & Paths | WEAVER_DATA_DIR | Has no effect. It is meant to seed the data directory, but startup fills that in from the --config path before the seed is applied, so the value is always discarded. Use WEAVER_INTERMEDIATE_DIR and WEAVER_COMPLETE_DIR to place downloads, and treat the config directory as the data directory. | not applied; the data directory is always the config directory, which is /config in Docker and the working directory natively | Non-empty path. An empty value still stops startup — the value is validated, then ignored. |
| Storage & Paths | WEAVER_INTERMEDIATE_DIR | Seeds the directory holding in-progress downloads. | first-run seed; falls back to <data-dir>/intermediate | Non-empty path. An empty value stops startup. |
| Storage & Paths | WEAVER_COMPLETE_DIR | Seeds the directory completed downloads are moved to. Set this, or completed media lands inside your config volume. | first-run seed; falls back to <data-dir>/complete | Non-empty path. An empty value stops startup. |
| Storage & Paths | WEAVER_CLEANUP_AFTER_EXTRACT | Seeds whether archive files are deleted after a successful extraction. | first-run seed | Boolean tokens. An unrecognized value, including empty, stops startup. |
| Usenet Servers | WEAVER_SERVER_<N>_HOSTNAME | Seeds server N’s hostname. Required for that server to be created. | first-run seed; required per index | Non-empty string. Indexes must start at 1 and be contiguous; a gap stops startup. |
| Usenet Servers | WEAVER_SERVER_<N>_PORT | Seeds server N’s NNTP port. | first-run seed; 563 with TLS, 119 without | Integer 1–65535. Zero or non-numeric stops startup. |
| Usenet Servers | WEAVER_SERVER_<N>_TLS | Seeds whether server N connects over TLS. Also selects the default port. | first-run seed; true | Boolean tokens. An unrecognized value stops startup. |
| Usenet Servers | WEAVER_SERVER_<N>_USERNAME | Seeds server N’s login username. | first-run seed; unset | Any string. Empty is stored as “not set” rather than failing. |
| Usenet Servers | WEAVER_SERVER_<N>_PASSWORD | Seeds server N’s login password. Stored encrypted. | first-run seed; unset | Any string. Empty is stored as “not set”. Cannot be supplied from a file. |
| Usenet Servers | WEAVER_SERVER_<N>_CONNECTIONS | Seeds the maximum simultaneous connections to server N. | first-run seed; 10 | Integer 1–65535. Zero or non-numeric stops startup. |
| Usenet Servers | WEAVER_SERVER_<N>_PRIORITY | Seeds server N’s priority. Lower numbers are tried first. | first-run seed; 0 | Unsigned integer. Non-numeric stops startup. |
| Usenet Servers | WEAVER_SERVER_<N>_ACTIVE | Seeds whether server N is enabled. | first-run seed; true | Boolean tokens. An unrecognized value stops startup. |
| Usenet Servers | WEAVER_SERVER_<N>_BACKFILL | Seeds whether server N is treated as a backfill or fill server. | first-run seed; false | Boolean tokens. An unrecognized value stops startup. |
| Usenet Servers | WEAVER_SERVER_<N>_RETENTION_DAYS | Seeds server N’s advertised article retention. | first-run seed; 0, meaning unknown | Unsigned integer days. Non-numeric stops startup. |
| Usenet Servers | WEAVER_SERVER_<N>_MAX_DOWNLOAD_SPEED | Seeds a per-server speed cap in bytes per second. | first-run seed; 0, meaning unlimited | Unsigned integer bytes/second. Non-numeric or an implausibly large value stops startup. |
| Usenet Servers | WEAVER_SERVER_<N>_TLS_CA_CERT | Seeds a custom CA certificate path for verifying server N’s TLS certificate. | first-run seed; unset, uses the system trust store | File path. Empty is stored as “not set”. |
| Usenet Servers | WEAVER_SERVER_<N>_PIPELINING | Seeds whether server N starts out allowed to pipeline BODY commands — issuing the next request before the previous article has finished arriving, which is what hides round-trip latency on a distant provider. Weaver probes for support and learns a working depth on its own, so this only sets the starting point. | first-run seed; false | Boolean tokens. An unrecognized value stops startup, and so does a misspelled field name. |
| Usenet Servers | WEAVER_SERVER_<N>_DOWNLOAD_QUOTA_ENABLED | Seeds whether a download quota is enforced for server N. | first-run seed; false | Boolean tokens. An unrecognized value stops startup. |
| Usenet Servers | WEAVER_SERVER_<N>_DOWNLOAD_QUOTA_LIMIT_BYTES | Seeds server N’s quota size. | first-run seed; 0 | Unsigned integer bytes. Non-numeric or an implausibly large value stops startup. |
| Usenet Servers | WEAVER_SERVER_<N>_DOWNLOAD_QUOTA_PERIOD | Seeds how often server N’s quota resets. | first-run seed | one_time, daily, weekly, monthly. Anything else stops startup. |
| Usenet Servers | WEAVER_SERVER_<N>_DOWNLOAD_QUOTA_RESET_TIME_MINUTES_LOCAL | Seeds the local time of day the quota resets, as minutes past midnight. | first-run seed; 0, midnight | Integer 0–1439. Outside that range stops startup. |
| Usenet Servers | WEAVER_SERVER_<N>_DOWNLOAD_QUOTA_WEEKLY_RESET_WEEKDAY | Seeds the weekday a weekly quota resets on. | first-run seed; mon | mon, tue, wed, thu, fri, sat, sun. Anything else stops startup. |
| Usenet Servers | WEAVER_SERVER_<N>_DOWNLOAD_QUOTA_MONTHLY_RESET_DAY | Seeds the day of month a monthly quota resets on. | first-run seed; 1 | Integer 1–31. Outside that range stops startup. |
| Performance & Limits | WEAVER_DIRECT_UNPACK | Whether eligible archives are unpacked while they download rather than after the whole set has landed. On by default since 0.11.0, where it was previously off; this variable is now the opt-out. It exists for incident response — the durable switch is enabled under [direct_unpack] in the config file, and this wins over it. | true | 1, true, on, yes or 0, false, off, no, case-insensitive. Read once at startup. An unrecognized value is ignored rather than stopping startup, falling back to the config file and then the default. |
| Performance & Limits | WEAVER_MAX_DOWNLOAD_SPEED | Seeds the global download speed cap in bytes per second. | first-run seed; unset, no cap | Unsigned integer bytes/second; 0 also means unlimited. Non-numeric stops startup. |
| Performance & Limits | WEAVER_SQLITE_MAX_CONNECTIONS | SQLite connection pool size. | 16 | Positive integer, clamped to 1..64. Invalid values are ignored rather than failing. |
| Performance & Limits | WEAVER_POSTGRES_MAX_CONNECTIONS | PostgreSQL connection pool size. | 16 | Positive integer, clamped to 2..128. Invalid values are ignored rather than failing. |
| Logging | RUST_LOG | Log verbosity and per-module filtering. | unset, uses the built-in default | Rust tracing filter, e.g. info or weaver=debug. Invalid directives are dropped rather than failing. |
| Logging | WEAVER_LOG_FILE | Writes logs to a file in addition to the console and the in-app log view. | Linux and macOS: unset. Windows: %LOCALAPPDATA%\weaver\logs\weaver.log | Writable file path. The —log-file flag wins over this. If set explicitly and unopenable, startup fails. |
| Container Runtime | PUID | User ID the container drops to. /config is re-owned to it. | 1000 | Numeric UID. Only applied when the container starts as root; skipped entirely under —user. |
| Container Runtime | PGID | Group ID the container drops to. | 1000 | Numeric GID. Same root-only caveat as PUID. |
| Container Runtime | UMASK | File-creation mask applied before Weaver starts. Docker only. | unset, inherits the container default | Octal mode such as 022. An invalid value stops the container. |
| Container Runtime | TZ | Timezone used for bandwidth quota windows and reset boundaries, and passed through to post-processing scripts. | Docker: Etc/UTC. Native: unset, uses the system UTC offset | Any tzdata zone name, e.g. America/New_York. Not validated by Weaver. |
| Homebrew Service | WEAVER_CONFIG | Homebrew only. Config directory the service wrapper passes to —config. Has no effect in Docker or a native run. | $(brew —prefix)/var/weaver | Absolute path. |
| Homebrew Service | WEAVER_PORT | Homebrew only. Port the service wrapper passes to —port. Has no effect in Docker or a native run. | 9090 | Integer 1–65535. |
| Homebrew Service | WEAVER_BASE_URL | Homebrew only. Reverse-proxy path prefix the wrapper passes to —base-url. Has no effect in Docker or a native run. | / | Path prefix such as /weaver. |
Provisioning Servers From The Environment
Section titled “Provisioning Servers From The Environment”Server variables are numbered, starting at 1. This seeds two servers on a fresh instance:
environment: WEAVER_SERVER_1_HOSTNAME: news.example.com WEAVER_SERVER_1_USERNAME: myuser WEAVER_SERVER_1_PASSWORD: mypassword WEAVER_SERVER_1_CONNECTIONS: "30" WEAVER_SERVER_2_HOSTNAME: block.example.net WEAVER_SERVER_2_USERNAME: otheruser WEAVER_SERVER_2_PASSWORD: otherpassword WEAVER_SERVER_2_BACKFILL: "true"Two rules are stricter than you might expect, and both stop startup rather than being ignored:
- Indexes must be contiguous from 1. Jumping from
_1_to_3_fails. - Field names must be spelled exactly. A typo like
WEAVER_SERVER_1_HOSTis a fatal error, not a silently dropped variable. That is deliberate — it stops a mistyped password from leaving a server half-configured.
Boolean Values Are Not Uniform
Section titled “Boolean Values Are Not Uniform”Weaver does not use one boolean syntax everywhere, so copy the accepted values from the row you’re setting rather than assuming.
- Most settings accept
1,true,yes, andon, case-insensitive, and reject anything else by refusing to start. - The Storage and Usenet Server seeds treat an empty value as invalid too, so
WEAVER_CLEANUP_AFTER_EXTRACT=fails rather than falling back to the default. WEAVER_RESET_LOGINis the strictest: only the exact lowercase strings1ortrue, with no surrounding whitespace.
Note also that the security and seed variables stop startup on a bad value, while the performance limits silently fall back to their defaults. A typo in a pool size will not be announced.
Supplying Secrets
Section titled “Supplying Secrets”Weaver does not apply a blanket _FILE convention. Two secrets can come from a file, and the rest cannot:
- The bootstrap login password —
WEAVER_BOOTSTRAP_LOGIN_PASSWORD_FILEreads the password from a path, which is the one to prefer with Docker secrets. Set it orWEAVER_BOOTSTRAP_LOGIN_PASSWORD; setting both stops startup rather than picking one. - The master encryption key — can come from a Docker secret at the fixed path
/run/secrets/weaver_encryption_keyon Linux. Weaver checksWEAVER_ENCRYPTION_KEYfirst, then that secret, then its on-disk key file.
Everything else, including Usenet passwords, must be supplied as plain environment values: there is no WEAVER_SERVER_1_PASSWORD_FILE.
Related
Section titled “Related”- Installation covers where each install method puts its configuration.
- Storage Layout explains the data, intermediate, and complete directories.
- Servers configures the same server records in the UI.
- Security And Access covers the in-app authentication controls.
- Reverse Proxy runs Weaver under a subpath.