Almost no blog names a category the Directory can use, so a feed can carry one of its own in config.toml, set by an admin in the feed's settings and used when the feed names none. The feed's own iTunes category still wins. The field offers the categories the Directory already shows, so a blog about games joins Games rather than starting a second chip. Setting it on a feed from an OPML promotes it to config, as any other shared setting does. Closes #10. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
122 lines
5.8 KiB
Markdown
122 lines
5.8 KiB
Markdown
# Configuration
|
|
|
|
One TOML file, read at startup and re-read whenever the web UI writes to it — most changes take
|
|
effect without a restart. Default location `$XDG_CONFIG_HOME/ipx/config.toml`
|
|
(`~/.config/ipx/config.toml`), overridden with `--config` or `$IPX_CONFIG`.
|
|
|
|
| What | Where | Override |
|
|
|---|---|---|
|
|
| Config | `~/.config/ipx/config.toml` | `--config`, `$IPX_CONFIG` |
|
|
| Database | `~/.local/share/ipx/state.db` | `$IPX_DATA_DIR` |
|
|
| Control socket | `$XDG_RUNTIME_DIR/ipx.sock` | `[general] socket` |
|
|
| Downloads | `[general] download_dir` | — |
|
|
|
|
`~` is expanded in paths. The database is SQLite in WAL mode; back it up by copying `state.db`
|
|
while the daemon is stopped, or with `sqlite3 state.db .backup`.
|
|
|
|
## `[general]`
|
|
|
|
```toml
|
|
[general]
|
|
download_dir = "~/Podcasts"
|
|
socket = "/run/user/1000/ipx.sock"
|
|
schedule = "every 1h" # "every 30m", "every 4h", "2d", "90" (minutes)
|
|
organize = "feed" # "feed" | "date"
|
|
max_total_gb = 50 # 0 = unlimited
|
|
max_age_days = 30 # 0 = keep forever
|
|
max_new_per_check = 3 # per feed, per scan. 0 = unlimited
|
|
media_types = ["audio", "video"]
|
|
```
|
|
|
|
* **`schedule`** — how often feeds are re-checked. A feed's own `<ttl>` still wins when it asks to
|
|
be polled *less* often, and a per-feed `schedule` overrides both. Admin-only from the UI.
|
|
* **`organize`** — `feed` files downloads under the feed's folder; `date` under `YYYY-MM-DD`.
|
|
* **`max_total_gb`** — the reaper deletes to get back under this, oldest first, keeping a 50 MB
|
|
pad. Kept items are never deleted, and a file only counts as read once every subscriber has
|
|
read it. `0` disables it entirely.
|
|
* **`max_age_days`** — items older than this with no file on disk are pruned from the database.
|
|
Kept ones stay. `0` disables it.
|
|
* **`max_new_per_check`** — the cap that stops a new subscription pulling a whole back catalogue.
|
|
`0` means unlimited, which is rarely what you want: subscribing to an OPML of 80 feeds with no cap
|
|
fetched 216 files and 22 GB in one scan.
|
|
* **`media_types`** — top-level MIME types taken automatically. Anything else is still listed and
|
|
can be fetched by hand; blog feeds put each article's header image in an `<enclosure>`, and
|
|
without this the disk fills with artwork. Empty takes everything.
|
|
|
|
## `[torrent]`
|
|
|
|
```toml
|
|
[torrent]
|
|
enabled = true
|
|
seed_ratio = 1.0 # stop seeding at this ratio ...
|
|
seed_time_mins = 60 # ... or after this long, whichever comes first
|
|
port_range = "6881-6889"
|
|
stall_mins = 30 # give up on a torrent making no progress
|
|
```
|
|
|
|
A `.torrent` body is handed to the torrent path whatever MIME type it was advertised as. Torrents
|
|
run on their own tasks (two at a time) so a slow swarm never blocks a scan.
|
|
|
|
## `[web]`
|
|
|
|
```toml
|
|
[web]
|
|
enabled = true
|
|
bind = "0.0.0.0:8099" # 127.0.0.1:8080 by default
|
|
token = "" # generated and saved on first run
|
|
trusted_header = "" # e.g. "Cf-Access-Authenticated-User-Email"
|
|
trusted_proxies = ["127.0.0.1", "::1"]
|
|
auto_create_users = true
|
|
sign_out_url = "" # e.g. "/cdn-cgi/access/logout"
|
|
session_days = 30
|
|
```
|
|
|
|
* **`token`** — the shared secret, which signs in as the **admin**. `?token=…` sets a cookie, so
|
|
you paste it once per browser. It is what the Docker healthcheck and any scripts use.
|
|
* **`trusted_header`** — a header naming the signed-in user, set by whatever fronts ipx. Empty
|
|
disables that path. See [sso.md](sso.md).
|
|
* **`trusted_proxies`** — addresses allowed to assert that header, and the entire security boundary
|
|
for it. Name the proxy, never a subnet.
|
|
* **`auto_create_users`** — create an account the first time the proxy vouches for a new name.
|
|
* **`sign_out_url`** — where Sign out sends someone the proxy signed in: the proxy's own sign-out,
|
|
`/cdn-cgi/access/logout` behind Cloudflare Access. Empty sends them to the sign-in page, where
|
|
the proxy signs them straight back in.
|
|
* **`session_days`** — sign a session out after this long without a request.
|
|
|
|
It is plain HTTP. On a LAN bind everything crosses the network in the clear — and a feed URL can
|
|
itself carry a credential. Put TLS in front of it if that matters.
|
|
|
|
## `[feeds.<id>]`
|
|
|
|
The table key is the feed id: stable, human-readable, and used in paths and the API. `ipx add`
|
|
derives it from the feed title.
|
|
|
|
```toml
|
|
[feeds.atp]
|
|
url = "https://atp.fm/rss"
|
|
folder = "Accidental Tech Podcast" # default: the feed title
|
|
schedule = "every 6h" # overrides [general] for this feed
|
|
media_types = ["audio"] # overrides [general] for this feed
|
|
category = "Technology" # the Directory's, if the feed names none
|
|
username = "ray" # HTTP basic auth
|
|
password_env = "IPX_ATP_PASS" # preferred over a literal `password`
|
|
```
|
|
|
|
With more than one account, **`keywords`, `auto_download`, `allow_explicit` and
|
|
`max_new_per_check` live on each person's subscription in the database**, not here — the values in
|
|
config.toml are the fallback for a feed nobody has claimed. The keys above describe the feed itself
|
|
and are the same for everyone. See [users.md](users.md).
|
|
|
|
Feeds derived from a subscribed OPML are **not** written here: the OPML is the source of truth and
|
|
they are re-derived on every scan. Editing one in the UI promotes it to a real config entry.
|
|
|
|
## Environment
|
|
|
|
| Variable | Effect |
|
|
|---|---|
|
|
| `IPX_CONFIG` | Config file path |
|
|
| `IPX_DATA_DIR` | Directory holding `state.db` |
|
|
| `IPX_LOG` | What reaches stderr (`ipx=debug`, `ipx::scan=debug`, …) |
|
|
| `IPX_UI_LOG` | What the in-process log buffer captures for the UI's Log view |
|
|
| `http_proxy` / `https_proxy` | Honoured for feed and enclosure fetches |
|