CLAUDE.md and prod-check: ipx-web is what serves port 8099 now (#203)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-12 14:21:53 +00:00
parent 0c820bbde1
commit 3bab6210c5
2 changed files with 26 additions and 3 deletions

View File

@@ -1,6 +1,6 @@
--- ---
name: ipx-prod-check name: ipx-prod-check
description: Look for problems in production ipx (the iPX and ipx-directory containers on Tower) from its logs in Loki, its traces in Tempo and its metrics in Prometheus, and file what is found as Gitea issues. Use when asked to check on production, look for issues or errors in ipx, see why something is slow or failing in production, review the logs, or investigate a report about the live site. description: Look for problems in production ipx (the iPX, ipx-web and ipx-directory containers on Tower) from its logs in Loki, its traces in Tempo and its metrics in Prometheus, and file what is found as Gitea issues. Use when asked to check on production, look for issues or errors in ipx, see why something is slow or failing in production, review the logs, or investigate a report about the live site.
--- ---
# Checking production ipx # Checking production ipx
@@ -225,6 +225,17 @@ it. A snapshot whose `refused_private` is not 0 means an ipx server tried to sen
private: find which in that server's log, since the directory refuses it but the sender should not private: find which in that server's log, since the directory refuses it but the sender should not
have sent it. Many `feed check failed` lines for one feed are the publisher's, not the directory's. have sent it. Many `feed check failed` lines for one feed are the publisher's, not the directory's.
## The page
`ipx-web` (Caddy) serves the page and passes the API to ipx (#203). It logs only its own start and
errors, not requests: ipx's access log still has every API call, and a page that fails to load
shows there as `/api/page-check` answering something other than 204, 303 or 302.
```sh
docker ps --filter name=ipx-web --format '{{.Status}}'
docker logs --since 24h ipx-web 2>&1 | grep -v '"level":"info"' | tail
```
`docker logs` and `docker exec iPX ipx ...` are fine. Do not query production's Postgres `docker logs` and `docker exec iPX ipx ...` are fine. Do not query production's Postgres
directly: ask the user if a question needs the database. directly: ask the user if a question needs the database.

View File

@@ -20,8 +20,8 @@ service of the `content` project, beside audiobookshelf, immich and Plex (#208).
| Old database | `/mnt/user/ipx/state.db`, SQLite, used until the move to Postgres on 2026-09-18 and kept for rollback | `/data/state.db` | | Old database | `/mnt/user/ipx/state.db`, SQLite, used until the move to Postgres on 2026-09-18 and kept for rollback | `/data/state.db` |
| Downloads | `/mnt/user/ipx/downloads` | `/downloads` | | Downloads | `/mnt/user/ipx/downloads` | `/downloads` |
| Directory | `ipx-directory` in the same project, `192.168.1.130:8100`, public at `ipx-dir.sdf1.net` through the tunnel with no Access in front: tokens are its gate. Config `/mnt/fast/appdata/ipx-directory/directory.toml` (token hashes; Tower's own token in `tower.token` beside it), database `ipx_directory` on the same Postgres, URL in `directory.env` beside the compose file. See [docs/directory.md](docs/directory.md) | `/config/directory.toml` | | Directory | `ipx-directory` in the same project, `192.168.1.130:8100`, public at `ipx-dir.sdf1.net` through the tunnel with no Access in front: tokens are its gate. Config `/mnt/fast/appdata/ipx-directory/directory.toml` (token hashes; Tower's own token in `tower.token` beside it), database `ipx_directory` on the same Postgres, URL in `directory.env` beside the compose file. See [docs/directory.md](docs/directory.md) | `/config/directory.toml` |
| Web UI | `192.168.1.130:8099`, also `ipodderx.sdf1.net` via a Cloudflare tunnel. Once #203 is deployed, that port is `ipx-web`'s (Caddy), and ipx's own is reached only by it | `0.0.0.0:8099` | | Web UI | `ipx-web` (Caddy) in the same project, at `192.168.1.130:8099`, also `ipodderx.sdf1.net` via a Cloudflare tunnel. It serves the page and passes `/api` and `/media` to ipx, whose own port is published nowhere; its address on `ipx_default` is pinned to `192.168.64.10` (#203) | ipx `0.0.0.0:8099`, Caddy `:8080` |
| Sign-in via the tunnel | Cloudflare Access app `ipodderx`, with Authentik as its identity provider; see [docs/sso.md](docs/sso.md) | trusts `Cf-Access-Authenticated-User-Email` from `192.168.64.1`, the `ipx_default` gateway (its subnet pinned in the compose file), and only with a valid `Cf-Access-Jwt-Assertion` (`access_team`, `access_aud`) | | Sign-in via the tunnel | Cloudflare Access app `ipodderx`, with Authentik as its identity provider; see [docs/sso.md](docs/sso.md) | Caddy passes `Cf-Access-*` only from `192.168.64.1`, the `ipx_default` gateway cloudflared arrives from (`TUNNEL_PEER`; the subnet is pinned in the compose file); ipx trusts them only from Caddy, `192.168.64.10`, and only with a valid `Cf-Access-Jwt-Assertion` (`access_team`, `access_aud`) |
Work to do lives in the Gitea issues at https://git.sdf1.net/rays/ipx/issues, not in a Work to do lives in the Gitea issues at https://git.sdf1.net/rays/ipx/issues, not in a
`TODO.md`. `/src/tea` is logged in: `/src/tea issues list --login git.sdf1.net --repo rays/ipx`. `TODO.md`. `/src/tea` is logged in: `/src/tea issues list --login git.sdf1.net --repo rays/ipx`.
@@ -63,6 +63,18 @@ docker compose -f /mnt/fast/arcane/projects/ipx/compose.yaml pull ipx-directory
docker compose -f /mnt/fast/arcane/projects/ipx/compose.yaml up -d ipx-directory docker compose -f /mnt/fast/arcane/projects/ipx/compose.yaml up -d ipx-directory
``` ```
And the page, `ipx-web`, the same again; a change to `web/` alone needs only this one:
```sh
docker buildx build -f Dockerfile.web --tag 192.168.1.130:5000/ipx-web:latest . --push
docker compose -f /mnt/fast/arcane/projects/ipx/compose.yaml pull ipx-web
docker compose -f /mnt/fast/arcane/projects/ipx/compose.yaml up -d ipx-web
```
Testing sign-in from Tower itself proves nothing about the tunnel: Tower's own requests reach the
published port as `192.168.1.130`, and Caddy rightly strips their `Cf-Access-*`. Send them from a
container on another network, as cloudflared's are (#209).
**Name the service.** A bare `up -d` recreates every container in the project, which once the **Name the service.** A bare `up -d` recreates every container in the project, which once the
split lands means the frontend and directory too. Run `pull` before `up`, because `up` reuses whatever `latest` the host already has. split lands means the frontend and directory too. Run `pull` before `up`, because `up` reuses whatever `latest` the host already has.