Files
usenet-indexer/seed-node/README.md
T
Daan MeijerandClaude Opus 5.5 f9e9295d3e
Test and deploy / test (push) Successful in 1m12s
Test and deploy / deploy (push) Failing after 43s
seed-node: step-by-step guide for running a node on a remote server
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 13:11:17 +02:00

96 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Seeding node
A seeding node indexes old article ranges for the indexer (CONCEPT.md D37,
D38). It asks the seed API for a range over HTTPS, fetches that range's
headers over its own NNTP connections, groups them into files, and posts the
results back. It only makes outgoing connections: no port forwarding,
database or Redis.
## What a node needs
- Docker with the compose plugin (`docker compose version` works).
- Outgoing HTTPS to `seed.exp.sforum.nl` (the seed API) and
`gitea.exp.sforum.nl` (to build the image), and outgoing NNTP to the news
server (port 563 for TLS).
- Per connection: roughly 0.4 CPU core and 1–3 MB/s download (headers come
gzip-compressed); a few hundred MB of RAM per node. Disk: about 1.5 GB for
the image.
- An NNTP account. Every connection a node opens counts against that
account's connection limit, next to the ~40 the indexer itself uses if it's
the same account. Too many gives `481`/`502` errors at login.
## 1. On the indexer (homelab): a token for the node
cd ~/dev/usenet-indexer
docker compose exec web node ace seed:token my-server
This prints a token starting with `sn_` once. Treat it like a password: it
lets the holder lease ranges and submit results. Running the command again
for the same name replaces the token; `--disable` revokes it.
## 2. On the server: get the files
mkdir -p ~/usenet-seed-node && cd ~/usenet-seed-node
curl -fsSLO https://gitea.exp.sforum.nl/daan/usenet-indexer/raw/branch/master/seed-node/compose.yaml
curl -fsSL -o node.env https://gitea.exp.sforum.nl/daan/usenet-indexer/raw/branch/master/seed-node/node.env.example
chmod 600 node.env
## 3. Configure `node.env`
| Setting | Value |
|---|---|
| `SEED_URL` | `https://seed.exp.sforum.nl` (leave as is) |
| `SEED_TOKEN` | the token from step 1 |
| `SEED_CONNECTIONS` | ranges worked on at once, one NNTP connection each. Start with 2–4. |
| `NNTP_HOST`, `NNTP_PORT`, `NNTP_SECURE` | the news server; over the internet use TLS: port `563`, `NNTP_SECURE=true` (for Eweka: `news.eweka.nl`) |
| `NNTP_USER`, `NNTP_PASSWORD` | the NNTP account |
Leave the block below "Required by the app's configuration, but unused" as
it is: the app checks these settings at startup, but a node never uses them.
## 4. Start it
docker compose up -d --build
docker compose logs -f
The first build takes a few minutes. A working node logs:
[ info ] Seeding node for https://seed.exp.sforum.nl with 2 connection(s).
[ info ] [1] alt.binaries.ath 49834000000–49835999999
[ info ] [1] done: 2,000,000 headers in 237 s (8,450/s)
With nothing planned it waits and asks again every minute (no log lines).
## 5. Plan work and follow it (on homelab)
docker compose exec web node ace seed:plan alt.binaries.ath alt.binaries.mom --days 365
docker compose exec web node ace seed:status
`seed:plan` queues ranges of 2 million articles from below what is already
indexed down to `--days` back (or everything the server has, without
`--days`), newest first and interleaved across groups. It takes over the
rest of those groups' backfill. `seed:status` shows ranges per status,
articles reached, and per node its leases and headers.
## Day to day
- **Update** after a new version of the indexer:
`docker compose build --pull && docker compose up -d`
- **Stop**: `docker compose stop` gives the node's ranges back; another node
resumes them after the last batch that was stored.
- **A node that disappears** (crash, network) loses its ranges to other
nodes after 15 minutes without a batch. A range that fails 5 times is set
aside as `failed` (see `seed:status`).
- **Remove a node**: `docker compose down` on the server, then
`docker compose exec web node ace seed:token my-server --disable` on homelab.
## Troubleshooting
| Log line | Meaning |
|---|---|
| `The seed API rejected this node token` | wrong or revoked `SEED_TOKEN`; the node stops |
| `Seed API …: 404 …; retrying` | the seed API is restarting (a deploy on homelab); the node retries |
| `NNTP: unexpected reply "481 …"` or `"502 …"` | NNTP login refused: wrong account, or too many connections on it; lower `SEED_CONNECTIONS` |
| `Range … failed: …` | the range is given back and retried later, possibly by another node |
| `Range … passed to another node; dropping it.` | this node was too slow to report (15 minutes); harmless |