Skip to content

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.

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_password

This 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.

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.
  • 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 value or 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 under C:\Program Files, so a .env file there needs an administrator and is best avoided.
  • Native or systemd — your service unit’s environment, or the shell that launches Weaver.
  • A .env file — Weaver loads .env from its current working directory at startup. Handy locally, but surprising under systemd, where the working directory may not be what you expect. A malformed .env stops startup.
Showing all configuration variables.
CategoryNameDescriptionDefaultAllowed values
Network & HTTPWEAVER_HTTP_BIND_ADDRESSIP 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.0IPv4 or IPv6 literal. An unparsable value stops startup.
Network & HTTPWEAVER_HTTP_ALLOWED_HOSTSRestricts 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 answeredComma-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 & HTTPWEAVER_CORS_ALLOWED_ORIGINSBrowser origins allowed to call the API cross-site.empty, no cross-origin accessComma-separated exact origins such as https://host:port. A trailing slash, path, query, or fragment stops startup.
Network & HTTPWEAVER_RSS_ALLOW_PRIVATE_NETWORKAllows RSS feed fetches to reach private, loopback, and link-local addresses. Needed for a feed hosted on your own LAN.falseBoolean tokens. An unrecognized value stops startup.
Network & HTTPWEAVER_UI_RESTARTWhether 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 regardlessBoolean tokens. An unrecognized value disables the restart rather than enabling it.
Network & HTTPWEAVER_DEPLOYMENT_ENVOverrides 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 dockerdocker, container, or native. Any other value falls back to automatic detection.
Auth & SecurityWEAVER_ACCESS_MODEMoves 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.unsetExactly authenticated. Empty counts as unset; any other value stops startup.
Auth & SecurityWEAVER_SECURE_COOKIESMarks 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.falseBoolean tokens. An unrecognized value stops startup.
Auth & SecurityWEAVER_METRICS_AUTH_REQUIREDRequires authentication on the Prometheus metrics endpoint. Turn off only on a trusted network.trueBoolean tokens. An unrecognized value stops startup.
Auth & SecurityWEAVER_STRICT_SECURITYRefuses 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.falseBoolean tokens. Post-processing scripts are refused when they would run, not at startup, so turning it on never strands a running instance.
Auth & SecurityWEAVER_TRUSTED_CIDRSWith 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 anywhereComma-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 & SecurityWEAVER_TRUSTED_PROXIESPins 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 → SecurityComma-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 & SecurityWEAVER_BOOTSTRAP_LOGIN_USERNAMEUsername for a login created automatically on a first start, so an instance can be provisioned without visiting the setup screen.first-run only; unsetNon-empty after trimming, valid UTF-8. Requires exactly one of the two password variables; an empty or lone username stops startup.
Auth & SecurityWEAVER_BOOTSTRAP_LOGIN_PASSWORDPassword for the bootstrap login.first-run only; unsetNon-empty, valid UTF-8. Setting this and the file variable stops startup.
Auth & SecurityWEAVER_BOOTSTRAP_LOGIN_PASSWORD_FILEReads the bootstrap password from a file instead, so it never appears in a compose file or process list.first-run only; unsetPath 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 & SecurityWEAVER_REQUIRE_SETUP_CODEMakes 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; unset1 or true, in any case. Any other value leaves the default.
Auth & SecurityWEAVER_ENCRYPTION_KEYMaster 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 fileBase64 key. Invalid base64 or wrong length stops startup. Never copied into the data directory.
Auth & SecurityWEAVER_RESET_LOGINClears 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.unsetExactly 1 or true, case-sensitive and not trimmed. TRUE and 1 are ignored. Logs a warning when it fires.
Storage & PathsWEAVER_DATABASE_URLPoints Weaver at an external PostgreSQL database instead of the local SQLite file.unset, SQLite at <config-dir>/weaver.dbpostgres://, postgresql://, or sqlite:. Any other scheme stops startup.
Storage & PathsWEAVER_DATA_DIRHas 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 nativelyNon-empty path. An empty value still stops startup — the value is validated, then ignored.
Storage & PathsWEAVER_INTERMEDIATE_DIRSeeds the directory holding in-progress downloads.first-run seed; falls back to <data-dir>/intermediateNon-empty path. An empty value stops startup.
Storage & PathsWEAVER_COMPLETE_DIRSeeds 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>/completeNon-empty path. An empty value stops startup.
Storage & PathsWEAVER_CLEANUP_AFTER_EXTRACTSeeds whether archive files are deleted after a successful extraction.first-run seedBoolean tokens. An unrecognized value, including empty, stops startup.
Usenet ServersWEAVER_SERVER_<N>_HOSTNAMESeeds server N’s hostname. Required for that server to be created.first-run seed; required per indexNon-empty string. Indexes must start at 1 and be contiguous; a gap stops startup.
Usenet ServersWEAVER_SERVER_<N>_PORTSeeds server N’s NNTP port.first-run seed; 563 with TLS, 119 withoutInteger 165535. Zero or non-numeric stops startup.
Usenet ServersWEAVER_SERVER_<N>_TLSSeeds whether server N connects over TLS. Also selects the default port.first-run seed; trueBoolean tokens. An unrecognized value stops startup.
Usenet ServersWEAVER_SERVER_<N>_USERNAMESeeds server N’s login username.first-run seed; unsetAny string. Empty is stored as “not set” rather than failing.
Usenet ServersWEAVER_SERVER_<N>_PASSWORDSeeds server N’s login password. Stored encrypted.first-run seed; unsetAny string. Empty is stored as “not set”. Cannot be supplied from a file.
Usenet ServersWEAVER_SERVER_<N>_CONNECTIONSSeeds the maximum simultaneous connections to server N.first-run seed; 10Integer 165535. Zero or non-numeric stops startup.
Usenet ServersWEAVER_SERVER_<N>_PRIORITYSeeds server N’s priority. Lower numbers are tried first.first-run seed; 0Unsigned integer. Non-numeric stops startup.
Usenet ServersWEAVER_SERVER_<N>_ACTIVESeeds whether server N is enabled.first-run seed; trueBoolean tokens. An unrecognized value stops startup.
Usenet ServersWEAVER_SERVER_<N>_BACKFILLSeeds whether server N is treated as a backfill or fill server.first-run seed; falseBoolean tokens. An unrecognized value stops startup.
Usenet ServersWEAVER_SERVER_<N>_RETENTION_DAYSSeeds server N’s advertised article retention.first-run seed; 0, meaning unknownUnsigned integer days. Non-numeric stops startup.
Usenet ServersWEAVER_SERVER_<N>_MAX_DOWNLOAD_SPEEDSeeds a per-server speed cap in bytes per second.first-run seed; 0, meaning unlimitedUnsigned integer bytes/second. Non-numeric or an implausibly large value stops startup.
Usenet ServersWEAVER_SERVER_<N>_TLS_CA_CERTSeeds a custom CA certificate path for verifying server N’s TLS certificate.first-run seed; unset, uses the system trust storeFile path. Empty is stored as “not set”.
Usenet ServersWEAVER_SERVER_<N>_PIPELININGSeeds 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; falseBoolean tokens. An unrecognized value stops startup, and so does a misspelled field name.
Usenet ServersWEAVER_SERVER_<N>_DOWNLOAD_QUOTA_ENABLEDSeeds whether a download quota is enforced for server N.first-run seed; falseBoolean tokens. An unrecognized value stops startup.
Usenet ServersWEAVER_SERVER_<N>_DOWNLOAD_QUOTA_LIMIT_BYTESSeeds server N’s quota size.first-run seed; 0Unsigned integer bytes. Non-numeric or an implausibly large value stops startup.
Usenet ServersWEAVER_SERVER_<N>_DOWNLOAD_QUOTA_PERIODSeeds how often server N’s quota resets.first-run seedone_time, daily, weekly, monthly. Anything else stops startup.
Usenet ServersWEAVER_SERVER_<N>_DOWNLOAD_QUOTA_RESET_TIME_MINUTES_LOCALSeeds the local time of day the quota resets, as minutes past midnight.first-run seed; 0, midnightInteger 01439. Outside that range stops startup.
Usenet ServersWEAVER_SERVER_<N>_DOWNLOAD_QUOTA_WEEKLY_RESET_WEEKDAYSeeds the weekday a weekly quota resets on.first-run seed; monmon, tue, wed, thu, fri, sat, sun. Anything else stops startup.
Usenet ServersWEAVER_SERVER_<N>_DOWNLOAD_QUOTA_MONTHLY_RESET_DAYSeeds the day of month a monthly quota resets on.first-run seed; 1Integer 131. Outside that range stops startup.
Performance & LimitsWEAVER_DIRECT_UNPACKWhether 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.true1, 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 & LimitsWEAVER_MAX_DOWNLOAD_SPEEDSeeds the global download speed cap in bytes per second.first-run seed; unset, no capUnsigned integer bytes/second; 0 also means unlimited. Non-numeric stops startup.
Performance & LimitsWEAVER_SQLITE_MAX_CONNECTIONSSQLite connection pool size.16Positive integer, clamped to 1..64. Invalid values are ignored rather than failing.
Performance & LimitsWEAVER_POSTGRES_MAX_CONNECTIONSPostgreSQL connection pool size.16Positive integer, clamped to 2..128. Invalid values are ignored rather than failing.
LoggingRUST_LOGLog verbosity and per-module filtering.unset, uses the built-in defaultRust tracing filter, e.g. info or weaver=debug. Invalid directives are dropped rather than failing.
LoggingWEAVER_LOG_FILEWrites logs to a file in addition to the console and the in-app log view.Linux and macOS: unset. Windows: %LOCALAPPDATA%\weaver\logs\weaver.logWritable file path. The —log-file flag wins over this. If set explicitly and unopenable, startup fails.
Container RuntimePUIDUser ID the container drops to. /config is re-owned to it.1000Numeric UID. Only applied when the container starts as root; skipped entirely under —user.
Container RuntimePGIDGroup ID the container drops to.1000Numeric GID. Same root-only caveat as PUID.
Container RuntimeUMASKFile-creation mask applied before Weaver starts. Docker only.unset, inherits the container defaultOctal mode such as 022. An invalid value stops the container.
Container RuntimeTZTimezone used for bandwidth quota windows and reset boundaries, and passed through to post-processing scripts.Docker: Etc/UTC. Native: unset, uses the system UTC offsetAny tzdata zone name, e.g. America/New_York. Not validated by Weaver.
Homebrew ServiceWEAVER_CONFIGHomebrew only. Config directory the service wrapper passes to —config. Has no effect in Docker or a native run.$(brew —prefix)/var/weaverAbsolute path.
Homebrew ServiceWEAVER_PORTHomebrew only. Port the service wrapper passes to —port. Has no effect in Docker or a native run.9090Integer 165535.
Homebrew ServiceWEAVER_BASE_URLHomebrew 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.

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_HOST is a fatal error, not a silently dropped variable. That is deliberate — it stops a mistyped password from leaving a server half-configured.

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, and on, 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_LOGIN is the strictest: only the exact lowercase strings 1 or true, 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.

Weaver does not apply a blanket _FILE convention. Two secrets can come from a file, and the rest cannot:

  • The bootstrap login passwordWEAVER_BOOTSTRAP_LOGIN_PASSWORD_FILE reads the password from a path, which is the one to prefer with Docker secrets. Set it or WEAVER_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_key on Linux. Weaver checks WEAVER_ENCRYPTION_KEY first, 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.