Skip to content

Configuration Environment and CLI

Kheopsian edited this page Oct 12, 2026 · 2 revisions

🇬🇧 English · 🇫🇷 Français

Configuration: Environment Variables, CLI and Signals

Applies to Hydranos 4.4.

This page covers everything that is not in the config file: the command-line options of hydranos and hydranos-update, every environment variable the code reads, and the signals that stop the daemon cleanly. It is for people writing a compose file, a systemd unit or a Windows shortcut. For the TOML file itself, start at Configuration Reference.

No environment variable or flag overrides a config key. The only way to change a setting such as a port or a path is the config file.

hydranos command line

hydranos --help prints the exact usage:

usage: hydranos [--config <path/to/default.toml>] [--console]
       hydranos --version
       hydranos reset-password <password> [path/to/default.toml]
       hydranos hash-password <password>
Option Effect Default
--config <path> or --config=<path> Path of the config file. If the file does not exist, hydranos writes one from the built-in template, with data_dir set to a data folder beside it. Linux and macOS: /config/default.toml. Windows: default.toml beside hydranos.exe (a 4.3 install with only \config\default.toml on the current drive keeps using that one).
--console Windows: open a new console window when the process was not started from one (attaching to a parent terminal happens anyway). Does nothing on Linux. off
--version, -V Prints hydranos 4.x.y (the release number) and exits. —
--help, -h Prints the usage above and exits. —

Two subcommands work on the config file without starting the daemon. They must be the first argument:

Subcommand Effect Exit code
reset-password <password> [path] Hashes the password (bcrypt) and writes it as [auth] password_hash in the file, then checks the file still parses and prints hydranos: password set in <path>. Restart Hydranos for it to apply. The path is the first argument after the password other than --config (so reset-password '<pw>' --config /etc/hydranos/default.toml works too); without one, the default path above. username is not changed. A running daemon keeps the old hash until it restarts. 0; 2 for a missing or short password; 1 if the file cannot be read, written, or would not parse
hash-password <password> Prints the bcrypt hash, for pasting into password_hash by hand. 0; 2 for a missing or short password

Both refuse a password shorter than 8 characters (hydranos: the password must be at least 8 characters). The password is a command-line argument: it is visible to other users in the process list while the command runs and stays in your shell history. Recovery procedures: Security and Access.

Any other argument is reported and skipped, and the daemon starts normally. The line goes to stderr (the console, or the container log; not hydranos.log):

hydranos: ignoring unknown argument "--foo"; starting anyway (see hydranos --help)

The 3.x split-process flags (anything starting with --agent- or --front-, also with one dash or as --flag=value) get a longer line: ignoring <flag>: the agent/front split was removed in 4.x and Hydranos now runs as one process. Starting a normal instance. …, pointing to node enrolment. The value of --agent-addr, --agent-token, --agent-tls-cert, --agent-tls-key and --front-addr is skipped with its flag.

A --config given without a value prints hydranos: --config needs a path; using <default path> and the default path is used.

hydranos --config /etc/hydranos/default.toml
hydranos --version
hydranos reset-password 'a-long-new-password' /etc/hydranos/default.toml

On Windows, hydranos.exe is a windowed program: the output of --version, --help, reset-password and hash-password is printed before it attaches to any console, so it does not appear even in a terminal (read from the code, not tested on Windows). reset-password still writes the file and sets the exit code ($LASTEXITCODE in PowerShell); check the version in the web UI header instead. The unknown-argument lines and the log do appear in the terminal that started it.

The Docker image does not seed the file the same way: its entrypoint copies the template itself and sets data_dir to the config dir (/config, not /config/data). See Install with Docker.

hydranos-update

hydranos-update replaces the binaries with a published release from github.com/Kheopsian/Hydranos. It ships in the Windows zip and the Linux tarball, not in the Docker image (update the image instead).

Option Effect Default
--check Print the latest release and exit —
--dir <path> Folder that holds hydranos / hydranos.exe . (current folder)
--tag <vX.Y.Z> Install this release instead of the latest latest
--config <file> The daemon's config file, read only to send the updater's own downloads the way the daemon's requests go ([daemon] egress, the kill switch, the network mode). A file that does not parse stops the updater; a missing file means the default route. When the route is not plain direct, or the kill switch is armed, it prints a network: … line first. <dir>/default.toml
--yes, -y Do not ask before replacing asks [y/N]
--help, -h Print the help and exit —

Unknown options are ignored. Behaviour, from the code:

  • Nothing is replaced unless the archive downloads and its SHA-256 matches the .sha256 file published beside it.
  • Only binaries already present in --dir are replaced; default.toml, the data folder and hydranos.log are not in the archive and are never touched.
  • If the installed version already equals the latest and no --tag is given, it stops there.
  • Windows: if hydranos.exe is running, it sets the daemon's stop event (Local\HydranosStop), which gives the same clean stop as the tray's Quit Hydranos, and waits up to 60 s. A daemon older than 4.4 has no such event: the updater then falls back to taskkill /IM hydranos.exe /T without /F, which does not stop it, so quit from the tray first. If it is still running after 60 s (a very large flush), the updater ends with hydranos is still running after 60s -- stop it yourself, nothing was replaced. Once hydranos.exe is gone, it swaps the files. See Install on Windows. The tray's Check for updates runs hydranos-update.exe --dir <its own folder> in a cmd window.
  • Linux: it does not stop anything. It swaps the files and prints note: restart the service for the new binaries to take effect.
# packaging/install.sh installs it in /opt/hydranos; the config is in /etc/hydranos, so name it
/opt/hydranos/hydranos-update --dir /opt/hydranos --config /etc/hydranos/default.toml --check
sudo /opt/hydranos/hydranos-update --dir /opt/hydranos --config /etc/hydranos/default.toml --yes && sudo systemctl restart hydranos

hydranos-engine (gone)

Releases no longer ship hydranos-engine (hydranos-engine.exe): every engine runs inside the hydranos process, and the only binaries in the archives are hydranos and hydranos-update. A copy left in /opt/hydranos by an older install is never started and can be deleted. History: Upgrading from 3.x.

Environment variables read by hydranos

These are read by the daemon itself, on every platform unless noted. They are read once, at startup (or the first time the code path runs): changing them needs a restart.

For users

Variable Values Default Effect
RUST_LOG a tracing filter: warn, info, debug, or per module, e.g. info,typhon_engine::tracker=debug info Log level for the console, hydranos.log and the Logs tab alike.
HYDRANOS_LOG_STDOUT any value unset When the variable exists (any value, even 0 or false), no hydranos.log is written. The console output is always on; this variable only removes the file. Without it, the file is written beside the config file and rotates itself at 128 MiB, keeping four old files (hydranos.log.1 to .4) (see Monitoring and Logs).
HYDRANOS_STOP_TIMEOUT a duration: 120 (seconds), 60s, 2m, 1m30s, 1h (units largest first, each once; no sign, no fraction) 120 Bounds the resume-data flush at a clean stop. Past it, Hydranos leaves with what is written and logs shutdown flush hit HYDRANOS_STOP_TIMEOUT; leaving with what is saved; otherwise shutdown flush complete. 0 means: do not wait for the flush. A value that does not parse (30s1m, 1.5m, -5, empty) logs HYDRANOS_STOP_TIMEOUT="…" is not a duration (use 120, 60s, 2m or 1m30s); using 120 s at startup and uses 120. Keep your supervisor's stop timeout above it: Operating Hydranos.
TYPHON_ANNOUNCE_PROXY a proxy URL, e.g. socks5h://192.0.2.10:1080 unset Fallback proxy for the HTTP/HTTPS tracker announces and webseed fetches of every engine that has no proxy of its own (no announce_proxy, no SOCKS5 peer proxy), and for the RSS feed and .torrent downloads made for such an engine. For such an engine, UDP trackers are not announced while it is set. A URL that does not parse makes those announces fail; they never go direct instead. An empty value means unset. The Network sub-tab lists it under Set in the environment. Per-engine keys: VPN and Egress.
TYPHON_DISABLE_UTP 1 or true (any case) unset No uTP socket: peers over TCP only, for every engine.
HYDRANOS_WORKER_THREADS integer > 0 number of CPU cores, capped at 32 Size of the main worker thread pool.

Tuning and diagnostics (leave unset unless you know why)

Variable Values Default Effect
HYDRANOS_ENGINE_NET 0, false or off on Every engine loads its torrents but stays off the network: no listener, no peers, no announces, no DHT, and no managed WireGuard tunnel is brought up. Port forwarding (NAT-PMP/UPnP) is still requested for the engines' ports unless auto_port_forward = false. Any other value, or unset, means on. Used to inspect a copy of a catalogue without telling its trackers.
HYDRANOS_LINK_SCAN_THREADS integer > 0, capped at 256 16 Parallel file checks of the background hardlink scanner (used by workflows, see Workflows).
TYPHON_SESSION_RUNTIMES integer > 0 number of CPU cores (not capped) Number of runtimes that carry peer connections.
TYPHON_RECHECK_TORRENTS integer > 0 4 How many torrents are hash-checked at the same time.
TYPHON_RECHECK_CONCURRENCY integer > 0 16 Parallel piece reads inside one recheck.
TYPHON_NO_MSE 1 unset Outgoing peer connections skip the encrypted (MSE/PE) fallback.
TYPHON_DIAL_TRACE_IH a 40-character hex info hash unset Logs every outgoing-connection decision for that one torrent. Any other length is ignored.
TYPHON_RESUME_JSON 1 unset Also writes resume state as JSON files beside the per-engine state.db.
TYPHON_STATE_DB 0 on Disables the per-engine state.db and keeps only JSON resume files. Debug only: do not set it on an instance you care about.

In all integer variables above, a value that does not parse (or is 0) is ignored and the default applies. HYDRANOS_STOP_TIMEOUT follows its own rules (table above).

Test-only variables HYDRANOS_INTEROP_* exist in the source but are compiled only into the test suite.

Variables read only by the Docker entrypoint

The image's entrypoint.sh reads these before it starts hydranos. They have no effect on a bare-metal or Windows install.

Variable Values Default Effect
HYDRANOS_CONFIG_DIR a path /config Folder where the entrypoint looks for default.toml, seeds it on first run (with data_dir set to this folder) and passes it as --config. Also the folder that is chowned when PUID/PGID are set.
PUID / PGID numeric ids unset (runs as root) When either is set, the daemon runs as that uid/gid (the other one defaults to 1000). Ignored if the container already runs as a non-root user.
HYDRANOS_SKIP_CHOWN 1 unset With PUID/PGID: skip the recursive chown of the config dir. The payload folders are never chowned.
HYDRANOS_CAP_NET_ADMIN 1 unset With PUID/PGID: keep CAP_NET_ADMIN after the privilege drop (as an ambient capability, so the ip and wg commands inherit it), if the container was granted it (cap_add: [NET_ADMIN]). Managed WireGuard needs it in that setup; so does fwmark routing. Without the grant it prints hydranos: CAP_NET_ADMIN not available, add --cap-add=NET_ADMIN for managed WireGuard and fwmark routing and starts without it. Without PUID/PGID the daemon runs as root and keeps the granted capability anyway. See Managed WireGuard.

The entrypoint also raises the open-file limit (ulimit -n 1000000, falling back to 200000, silently skipped if not allowed), and always starts hydranos with --config "$HYDRANOS_CONFIG_DIR/default.toml".

It refuses the 3.x variables HYDRANOS_ENGINE_ID and HYDRANOS_ENGINES: when either is non-empty it prints, on stderr, hydranos: ignoring <VAR>: the 3.x agent mode was removed in 4.x and Hydranos now runs as one process. Starting a normal instance on <config dir>/default.toml. … Remove <VAR> from the container's environment to silence this., then seeds and starts as usual.

The image itself sets one variable:

Variable Value Effect
MALLOC_CONF prof:true,prof_active:true,lg_prof_sample:19,prof_prefix:/config/jeprof Turns on jemalloc heap sampling, so that SIGUSR1 can write a heap profile (see Signals). Profiles go to /config/jeprof.* even if you moved HYDRANOS_CONFIG_DIR.

Variables that do nothing in 4.4

Variable Where you may have seen it What really happens
HYDRANOS_ENGINE_BIN systemd units from before 4.4 Read by nothing (gone from the shipped unit).
HYDRANOS_DATA_DIR entrypoints from before 4.4 Never read by hydranos, no longer exported; the data dir comes only from [daemon] data_dir.
HYDRANOS_ENGINE_ID, HYDRANOS_ENGINES 3.x setups Refused by the entrypoint with a message (above); the container starts normally on its config. Remove them.
HYDRANOS_CONFIG_DIR outside Docker systemd units written by the enrolment script before 4.4 (the 4.4 units no longer set it) Read only by entrypoint.sh; the daemon uses --config.
HYDRANOS_AGENT_TOKEN, HYDRANOS_ENGINE_ROLE, HYDRANOS_ENGINE_LISTEN_PORT, HYDRANOS_ENGINE_ENABLE_IPV6 comments in older default.toml templates Read by nothing.
TYPHON_SELF_IPS older docs Read only by the standalone hydranos-engine, which is no longer shipped; never by hydranos.
Any HYDRA_* variable (HYDRA_LOG_STDOUT, HYDRA_STOP_TIMEOUT, HYDRA_CONFIG_DIR, …) old wiki pages No code reads a HYDRA_ prefix. Use the HYDRANOS_* name where one exists in the tables above.
TYPHON_ANNOUNCE_PASSKEY, TYPHON_ANNOUNCE_V6_PROXY old wiki pages Do not exist. Per-tracker passkeys are set on the Trackers tab: Trackers and Announces.

The shipped docker-compose.yml sets stop_grace_period: 150s and offers HYDRANOS_STOP_TIMEOUT: 120 in a comment (see Install with Docker).

The enrolment script install.sh reads HYDRANOS_VERSION_PIN (a release tag) on every path, Docker image tag included; without it, the node takes the controller's version from its /health. That is the script, not the daemon. See Nodes and Multiple Machines.

Setting a variable on Windows

A shortcut cannot set an environment variable. Without --config, hydranos.exe uses the default.toml beside it, so the --config below is only needed for a config elsewhere. Either set it for one start in PowerShell ($env:RUST_LOG = "debug"; & "C:\Hydranos\hydranos.exe" --config "C:\Hydranos\default.toml"), or for your account with setx RUST_LOG debug or Start › type environment › Edit environment variables for your account. A running Hydranos keeps the old values: quit from the tray and start it again (sign out and back in if a Startup-folder shortcut still does not see it). Details: Install on Windows.

Signals (Linux)

Signal Effect
SIGTERM Clean stop. The web server stops accepting requests (the UI's event stream and live log tail close themselves; anything still open after 5 s is left behind), every engine sends stopped to its trackers (5 s at most), every engine's resume state is written, one thread per engine, within HYDRANOS_STOP_TIMEOUT, managed WireGuard tunnels are taken down, then the process exits with code 0. Logged as SIGTERM received, draining the API and flushing resume data.
SIGINT (Ctrl+C) Same clean stop.
SIGUSR1 Writes a jemalloc heap profile to the prof_prefix of MALLOC_CONF (/config/jeprof.* in Docker). Without prof:true in MALLOC_CONF (bare metal, by default) no profile is expected (not tested on bare metal); if jemalloc refuses the dump, the log shows jemalloc prof.dump failed: …. Does not stop anything.
SIGUSR2 Sets jemalloc's dirty/muzzy decay to 0 on every arena, returning freed memory to the system now, and logs the before/after resident size. The setting stays until the next restart (more CPU, less held memory). Does not stop anything.
SIGHUP, SIGQUIT, others No handler: default system behaviour (the process ends without the flush; as PID 1 in a container they are ignored). There is no config reload on SIGHUP.
SIGKILL Immediate end. Resume state falls back to the last periodic save (every 300 s): progress since then is lost and re-checked at the next start.

Things to know:

  • The SIGTERM/SIGINT handler is installed with the HTTP listener, in the first second of startup, before the torrents are loaded. A stop that arrives during the load is heard: the load finishes, nothing more starts, and the departures and the flush run (stop requested during startup; flushing and leaving).
  • The worst case is about 5 s (drain) + 5 s (departures) + HYDRANOS_STOP_TIMEOUT, 130 s by default. Give your supervisor more than that (stop_grace_period / docker stop -t, systemd TimeoutStopSec; the shipped files use 150 s): sizing is on Operating Hydranos.
  • Restart from the web UI or the API (Apply & restart, POST /api/settings/restart) is not a signal but takes the same path (logged restart request received, …), then exits with code 75 (EX_TEMPFAIL) instead of 0, so that Restart=on-failure, restart: unless-stopped or any policy that restarts on failure brings Hydranos back. A process started by hand stays stopped. See Operating Hydranos.
  • Every 300 s (Linux only) the daemon also logs one jemalloc allocated=… resident=… line.

Windows

Windows has no signals. Each of these gives the same clean stop as SIGTERM (drain, departures, bounded flush), logged as <trigger>: draining the API and flushing resume data:

  • Quit Hydranos in the tray icon menu (tray quit);
  • Ctrl+C or Ctrl+Break in the console the process is attached to (started from a terminal, or with --console);
  • closing that console window (console closed), signing out (sign-out), shutting Windows down (system shutdown);
  • hydranos-update, through the stop event (an info line stop requested by the updater, then the drain logged as tray quit: …); the event, like the tray icon, exists once the torrents are loaded.

Windows allows only a few seconds after a console close, a sign-out or a shutdown, so the flush may be cut short there: quit from the tray before shutting down. How these console events reach a windowed hydranos.exe started without a console has not been tested. taskkill /F and End task in Task Manager never run the flush; taskkill without /F does nothing. A restart from the web UI saves the same way, then hydranos.exe starts its successor itself (same arguments) and exits with code 75. SIGUSR1/SIGUSR2 and the memory stats line do not exist on Windows (no jemalloc there). Service wrappers and start-up options: Install on Windows.

See also

Hydranos 4.4 · 🇬🇧

Start

Install

Use

Integrate

Network & machines

Operate

Reference


Hydranos 4.4 · 🇫🇷

Démarrer

Installer

Utiliser

Intégrer

Réseau & machines

Exploiter

Référence


Clone this wiki locally