Installation and First Run - Kheopsian/Hydranos GitHub Wiki
Applies to Hydranos 4.4.
This page is for anyone installing Hydranos for the first time, on any platform. It lists what you need and which ports to open, helps you pick between Docker, Linux and Windows, and then walks through the first run, which is the same everywhere: create the admin account, find your API key, create a category, add a torrent and check that it works.
-
A folder for configuration and state. Hydranos writes its config file (
default.toml), each engine's resume state and its log file (hydranos.log) in the config folder. The store (hydra.db) goes to the data dir ([daemon] data_dir): the same folder in Docker,/var/lib/hydranoswith the bundled Linux script,datanext to the config file on Windows. Keep both on a local disk. - A folder (or mount) for torrent data. Hydranos has no default save path: every torrent goes into the save path of its category, or into a path you give explicitly. This folder only needs to exist and be writable by the process.
- Open ports, listed below.
The platform pages tell you where these folders are on each platform. Architecture explains what each file is.
| Port | Protocol | Used by | Who must reach it |
|---|---|---|---|
| 8199 | TCP | Web UI, REST API (/api), qBittorrent shim (/api/v2), MCP server (/mcp), /health, /metrics
|
You, your browser, Sonarr/Radarr/autobrr/cross-seed, scripts. Keep it on your LAN or behind a VPN/reverse proxy. |
| 16171 | TCP + UDP |
race engine: peer connections (TCP) and uTP (UDP, same port number) |
BitTorrent peers. Forward it from the internet for incoming connections. |
| 16172 | TCP + UDP |
hoard engine: peer connections (TCP) and uTP (UDP) |
BitTorrent peers. Forward it from the internet. |
| your choice | TCP + UDP | each extra engine, on its own listen_port
|
BitTorrent peers. |
| 16371 / 16372 | TCP + UDP |
race / hoard on a machine enrolled with the node enrolment script (it writes these ports instead of 16171/16172) |
BitTorrent peers. See Nodes and Multiple Machines. |
The values come from the config file: [daemon] api_port, [race] listen_port, [hoard] listen_port. By default (auto_port_forward = true) Hydranos also asks your router to forward each engine port, TCP and UDP (NAT-PMP, then UPnP; NAT-PMP on Linux only). When the router does not answer, forward both by hand. Details on Networking: Ports and Port Forwarding.
All three run the same hydranos binary, with the same web UI, APIs and engines. Pick the one that matches the machine you already have.
| Docker | Linux (bare metal) | Windows | |
|---|---|---|---|
| Artefact | image ghcr.io/kheopsian/hydranos (tag v4.4.0), linux/amd64 and linux/arm64 |
hydranos-v4.4.0-linux-<amd64|arm64>.tar.gz + .sha256
|
hydranos-v4.4.0-windows-amd64.zip + .sha256
|
| Config file |
/config/default.toml (inside the container) |
/etc/hydranos/default.toml (bundled install script) |
default.toml beside hydranos.exe (e.g. C:\Hydranos\default.toml), or the path you pass with --config
|
Store (hydra.db) |
/config (the image sets data_dir to the config folder) |
/var/lib/hydranos |
data next to the config file (e.g. C:\Hydranos\data) |
| Torrent data | a host folder you mount, e.g. /data
|
any local path | any local path |
| How it runs | container, restart: unless-stopped
|
systemd service hydranos.service
|
hydranos.exe, no console window, tray icon |
| Clean stop |
docker stop (SIGTERM), within stop_grace_period
|
systemctl stop hydranos (SIGTERM), within TimeoutStopSec
|
tray Quit Hydranos, or Ctrl+C in a console |
Interface pinning (bind_interface) |
yes | yes | no (refused: an engine that has it stays off the network) |
| Managed WireGuard | yes, with cap_add: NET_ADMIN
|
yes, with CAP_NET_ADMIN and ip/wg installed |
no |
| Updating | pull the new image, recreate the container |
/opt/hydranos/hydranos-update (installed by the bundled script) |
hydranos-update.exe, or tray Check for updates
|
On every platform a clean stop drains the API (5 s at most; open web UI tabs close their live connections themselves), tells the trackers each engine is leaving (5 s at most), then flushes each engine's resume state within HYDRANOS_STOP_TIMEOUT (120 s by default) before exiting. A restart from the web UI takes the same path and exits with code 75, so the supervisor (Docker's restart policy, systemd's Restart=on-failure) starts it again; on Windows the process starts its successor itself. A kill that does not wait for it (Docker's SIGKILL after the grace period, a systemd timeout, ending the task in Task Manager) skips that flush; see Operating Hydranos.
Install guides, in no particular order of preference:
-
Install with Docker: Compose, Unraid,
PUID/PGID. - Install on Linux (bare metal): release tarball and systemd.
- Install on Windows: zip, tray icon, starting with Windows.
Come back here for First run once the process is running.
The first time Hydranos starts, it writes a starting config file if none exists, generates an API key and stores it in that file, and opens port 8199 at once. While the engines load their torrents, the page shows a startup screen (HYDRANOS, a phase such as Restoring state…, Connecting to the network…, Opening the database… or Starting…, and <restored> / <total> torrents) and gives way to the normal page by itself; on a fresh install this takes seconds. Until then, login answers 503 with Retry-After: 5, and account creation (POST /api/setup) is refused: the startup router only routes GET /api/setup while the torrents load. If Create account fails during the startup screen (an error such as Setup failed (<status>) or Hydranos is starting …), wait for the startup screen to go and try again. No admin account and no password exist yet. Nothing prints a "temporary admin password": you create the account yourself in the browser.
Open http://<host>:8199 (for example http://192.0.2.10:8199, or http://localhost:8199 on the same machine).
sequenceDiagram
participant B as Browser
participant H as hydranos on port 8199
B->>H: GET /
H-->>B: web UI page
B->>H: GET /api/setup
H-->>B: needs_setup = true (no password_hash yet)
Note over B: Welcome to Hydranos screen
B->>H: POST /api/setup with username and password
alt torrents still loading
H-->>B: refused, the startup router only routes GET /api/setup
else caller not on loopback or a private network
Note over H: socket peer first, then the first X-Forwarded-For address
H-->>B: 403 first-run setup only answers a local caller, run hydranos reset-password on the host
else password under 8 characters
H-->>B: 400 password must be at least 8 characters
else accepted
H->>H: write [auth] username and password_hash to default.toml
H-->>B: 200 with status ok, username, api_key
end
Note over B: API key stored in this browser, page reloads
B->>H: later API calls carry the X-Api-Key header
B->>H: any later POST /api/setup
H-->>B: 409 admin account already configured
The page shows Welcome to Hydranos with the text Create your admin account to get started.
- Pick a Language if you want (it reloads the page).
-
Username is prefilled with
admin; change it if you like. An empty name also becomesadmin. - Type a password in Password (min 8 characters) and again in Confirm password. Fewer than 8 characters is refused.
- Click Create account.
If data_dir (where the store lives) is on network storage, the same screen shows a warning (Config on network storage detected …): the database cannot use its safest journal mode there; keep backups of your data_dir, or move it to a local disk.
Hydranos writes the username and a bcrypt hash of the password into the [auth] section of default.toml, hands the API key to the browser and reloads. There is one admin account; there are no other users. Next time a browser has no key, it shows Hydranos login and trades your username and password for the key.
On a fresh instance a window Import an existing library (qBittorrent / Transmission) may open by itself after the reload. Click Skip in both cases. If you are migrating from qBittorrent, read Your API key and Do not expose port 8199 below, then follow Migrating from qBittorrent instead of the Create your first category and Add your first torrent sections: that page tells you which categories to create so that they match your old client.
Want another password later? Use the Change password card under Config (at least 8 characters; you stay signed in). Lost it? Run
hydranos reset-password '<password>' [path/to/default.toml]on the host, then restart Hydranos. Details per platform on Security and Access.
The API key is the main credential for the REST API, the qBittorrent shim (as an alternative to the admin password) and the MCP server; a session cookie from a username/password login is accepted on the same routes. It is 48 hexadecimal characters, generated at first start when [daemon] api_key is empty (or still holds the published placeholder change-me-in-production), and written into default.toml.
To see it: Config › Advanced settings (default.toml) › General › api_key (with a copy button). You can also read it in the config file. Send it as the X-Api-Key header:
curl -H "X-Api-Key: YOUR_API_KEY" http://192.0.2.10:8199/api/categoriesThe curl examples on this page are written for a Linux or macOS shell. On Windows, type curl.exe (in PowerShell, plain curl is a different command) and put the whole command on one line, without the trailing \.
If Hydranos cannot write the config file, the key stays as it was: empty (every authenticated call is refused with 401) or, if the file still holds the published placeholder change-me-in-production, that public value keeps working. Fix the file permissions and restart.
Until the admin account exists, the first caller who passes the "local callers only" check can create it and receive the API key. The check looks at the address the connection comes from first: a public address is refused (403) whatever headers it sends. A connection from loopback or a private network passes, unless it carries an X-Forwarded-For header whose first address is public. Two consequences:
- a reverse proxy on your network that does not send
X-Forwarded-For(or anything else that rewrites the source to a private address) makes every caller look local; - a client on a VPN address outside the private ranges, such as Tailscale's
100.64.0.0/10, is refused: create the account from the LAN or the machine itself, or usehydranos reset-passwordon the host.
So create the account from your home network (or the machine itself) before you forward port 8199 or put it behind a public reverse proxy. Details on Security and Access.
Migrating from qBittorrent? Skip this section and the next one; follow Migrating from qBittorrent instead.
A torrent with no save path is refused (no save path: category "…" is unknown and no savepath was given), and there is no default folder. The easiest way to give every torrent a save path is a category: a name, a Mode (race or hoard, which picks the engine) and a Save Path.
In the web UI:
-
Open the Categories tab and click + New.
-
Name: for example
movies. -
Mode: if unsure, choose Hoard. Hoard is for the torrents you keep, and the race drain never touches it. Race is for racing fresh uploads, and its automatic drain can delete torrents together with their data when a disk fills. Torrents imported from qBittorrent also land in hoard. The difference is explained on Engines: Race and Hoard.
-
Save Path: a folder the process can write to, as seen by Hydranos:
Platform Example save path Docker /data/movies(inside the container, on your/datamount)Linux /srv/torrents/moviesWindows D:\Torrents\movies -
Leave Graduate to (hoard category) empty for now, and click Save.
The same with the REST API (answers 201 with the category):
curl -X POST http://192.0.2.10:8199/api/categories \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"movies","mode":"hoard","save_path":"/srv/torrents/movies"}'Replace /srv/torrents/movies with the save path for your platform from the table above.
The mode must be race or hoard (any case); any other value is refused with 400 (mode must be race or hoard, not "…"). Categories, tags and the full placement rule are on Categories and Routing.
- Open the + Add Torrent tab.
- Choose your category in Category. Its save path and mode apply automatically.
- Select a file under Or Upload .torrent (several files are accepted). With Preview contents before adding ticked, the right-hand column shows the files and trackers, read in your browser.
- Click Add Torrent.
A green line confirms it (Added … for one file, N torrents added for several). The torrent then shows on the Race tab or the Hoard tab, depending on the category's mode. If files of that torrent already exist in the save path, Hydranos hash-checks them first and only downloads what is missing; otherwise it downloads everything.
Leave the Advanced, override mode & save path section alone for now: its fields (Save Path, Mode, Put the payload in its own subfolder, Skip the hash check, the data is already on disk, Add without starting) override what the category decides. Magnets, watched folders, seeding existing data without a hash check, and those fields are covered on Adding Torrents and Existing Data.
The same upload with the REST API:
curl -H "X-Api-Key: YOUR_API_KEY" \
-F "[email protected]" \
-F "category=movies" \
http://192.0.2.10:8199/api/torrents/uploadThe file field may be named file, torrent or torrents; all three are accepted. It answers {"info_hash":"…","name":"…","engine":"hoard","mode":"hoard"} on success (engine is the engine the torrent went to, mode that engine's role), 409 with {"error":"…"} when the torrent is already added, or 400 with {"error":"…"}.
-
Header figures: the header shows the version, Upload and Download rates, and on a desktop-width window Exit IP, the public address the engines are seen from (click it to refresh).
-
Health endpoint, no key needed:
curl http://192.0.2.10:8199/health
It answers JSON whose
statusisstarting(still loading),healthy,degraded(an engine without its listener, blocked by the kill switch or held), all with HTTP 200, orunhealthywith HTTP 503 (the store does not answer, or no engine is listening for peers). The body also carriesversion,uptime,checksandproblems; see Monitoring and Logs. -
Logs: the Logs tab shows recent lines, with filters by module, level, period and text, and a Live tail. The same lines go to
hydranos.login the config folder (/config/hydranos.login Docker,/etc/hydranos/hydranos.logwith the bundled Linux script,C:\Hydranos\hydranos.logon Windows with the config atC:\Hydranos\default.toml) and to the console ordocker logs. Look for the lineshydra API listening (starting)and thenhydra API ready, and for a warning that a new API key was generated on first start. The file rotates itself at 128 MiB and keeps four old files. -
Peers: after a few minutes a downloading torrent shows peers and a download rate. If it stays at zero, check the engine ports above and Troubleshooting.
- Replacing qBittorrent behind Sonarr/Radarr: Migrating from qBittorrent.
- Learn the screens: Web UI Tour.
- Organise where torrents go: Categories and Routing.
- Add magnets, watched folders or data you already have: Adding Torrents and Existing Data.
- Before exposing anything to the internet: Security and Access.
- Something does not work: Troubleshooting.