Configuration Environment and CLI - Kheopsian/Hydranos GitHub Wiki
π¬π§ English Β· π«π· FranΓ§ais
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 --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.tomlOn 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 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
.sha256file published beside it. - Only binaries already present in
--dirare replaced;default.toml, the data folder andhydranos.logare not in the archive and are never touched. - If the installed version already equals the latest and no
--tagis given, it stops there. -
Windows: if
hydranos.exeis 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 totaskkill /IM hydranos.exe /Twithout/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 withhydranos is still running after 60s -- stop it yourself, nothing was replaced. Oncehydranos.exeis gone, it swaps the files. See Install on Windows. The tray's Check for updates runshydranos-update.exe --dir <its own folder>in acmdwindow. -
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 hydranosReleases 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.
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.
| 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. |
| 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.
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. |
| 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.
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.
| 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/SIGINThandler 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, systemdTimeoutStopSec; 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 (loggedrestart request received, β¦), then exits with code 75 (EX_TEMPFAIL) instead of 0, so thatRestart=on-failure,restart: unless-stoppedor 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 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 linestop requested by the updater, then the drain logged astray 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.
- Configuration Reference β the config file and where each section is documented
- Operating Hydranos β stop, restart, backup, updates
-
Monitoring and Logs β
hydranos.log, the Logs tab,/health,/metrics -
VPN and Egress β
TYPHON_ANNOUNCE_PROXYand what leaves through where -
Install with Docker β the compose file and the
/configvolume