SearXNG docs: document quadlet boot-persistence for the trio

Update SearXNG, Gluetun, and Valkey to describe the quadlet units instead of
compose: searxng sets Network=gluetun.container, the units install to
~/.config/containers/systemd/, and scripts/deploy-searxng-quadlet.sh deploys
them. Add a Boot Persistence section to the Stack doc. Correct the Gluetun
tunnel check (the :8000 server 404s; verify tun0 instead) and note the pinned
10.89.2.0/24 subnet.
This commit is contained in:
Frank
2026-08-18 23:42:45 -07:00
parent 71fe8c008f
commit f488382b08
4 changed files with 51 additions and 24 deletions
+6
View File
@@ -40,6 +40,12 @@ The last two rows are bare-metal systemd services, not containers. The
2026-08-17 redo, `frank-default-large` runs llama.cpp FastMTP on
Dankserver; `frank-default-small` runs vLLM on Dankclaw.
## Boot Persistence
The Gitea trio and the SearXNG trio (gluetun, searxng, valkey) run as quadlet units, so they start at boot. User linger is on. ComfyUI runs as a systemd unit around a bare process. The remaining services in the table are defined in `compose.yaml` and are not yet boot-persistent.
Deploy the SearXNG trio with `scripts/deploy-searxng-quadlet.sh dankclaw`. The Gitea units install to `~/.config/containers/systemd/` (see [[Gitea]]).
## Routing Rules
- SearXNG outbound traffic exits through the [[Gluetun]] VPN container.
+12 -8
View File
@@ -12,7 +12,7 @@ Gluetun is a lightweight VPN client container. It connects to a VPN provider (Wi
| Capabilities | `NET_ADMIN` required |
| Device | `/dev/net/tun:/dev/net/tun` |
| Ports published | searxng's 8081 → 8080 lives here |
| Healthcheck | internal on `8000` (built-in) |
| Tunnel check | the `tun0` interface exists (the `:8000` server 404s on all paths) |
## Required Environment
@@ -39,15 +39,19 @@ Warning from the wiki: do NOT set `DNS_UPSTREAM_PLAIN_ADDRESSES` to a LAN/bridge
## Attaching a Container
```yaml
services:
searxng:
network_mode: "service:gluetun"
depends_on:
- gluetun
The searxng unit reuses gluetun's network namespace:
```ini
[Container]
ContainerName=searxng
Network=gluetun.container
```
There is no need for `depends_on` for the network stack, but it orders startup cleanly.
`Network=gluetun.container` also adds a systemd dependency on gluetun, so searxng starts after the tunnel.
## Boot Persistence
gluetun runs as the `gluetun` quadlet unit (see [[SearXNG]] for the full trio). It sets `WantedBy=default.target` and user linger is on, so the tunnel starts at boot. The WireGuard credentials live in `/opt/searxng/.env` (mode 0600). Deploy with `scripts/deploy-searxng-quadlet.sh dankclaw`.
## Verify the Tunnel
+22 -9
View File
@@ -16,17 +16,30 @@ SearXNG is a privacy-respecting metasearch engine. It aggregates results from ma
## VPN Routing (critical)
All SearXNG outbound traffic exits through the Gluetun VPN container. The container attaches to Gluetun's network namespace:
All SearXNG outbound traffic exits through the Gluetun VPN container. The searxng unit sets `Network=gluetun.container`, which makes it reuse gluetun's network namespace:
```yaml
services:
searxng:
network_mode: "service:gluetun"
depends_on:
- gluetun
```ini
[Container]
ContainerName=searxng
Network=gluetun.container
```
Port publishing happens on the **gluetun** service, not on searxng. See [[Gluetun]] and the knowledge base page [[VPN Routing for SearXNG]] (KB Pattern 2 is the one used here).
Port publishing happens on the **gluetun** unit, not on searxng. See [[Gluetun]] and the knowledge base page [[VPN Routing for SearXNG]] (KB Pattern 2 is the one used here).
## Boot Persistence (Quadlet)
The trio runs as quadlet units, not podman-compose, so it starts at boot. The unit files live in `searxng/quadlet/` and install to `~/.config/containers/systemd/`.
| Unit file | Service | Role |
|-----------|---------|------|
| `searxng.network` | `searxng-network.service` | DNS-enabled bridge, subnet pinned to 10.89.2.0/24 |
| `gluetun.container` | `gluetun.service` | WireGuard tunnel; publishes 8081:8080 |
| `searxng-valkey.container` | `searxng-valkey.service` | Valkey cache, alias `valkey` |
| `searxng.container` | `searxng.service` | Reuses gluetun's netns; publishes no port |
gluetun and valkey join the searxng network. searxng reuses gluetun's netns and reaches valkey by name on that network. Each unit sets `WantedBy=default.target`. User linger is on, so the units start at boot.
Deploy with `scripts/deploy-searxng-quadlet.sh dankclaw`. It copies the units, daemon-reloads, enables them, and starts them in dependency order.
## settings.yml Keys
@@ -75,7 +88,7 @@ Two lists control access:
The whole homelab LAN `192.168.0.0/24` is in both lists. This lets local agents and browsers poll the JSON API without tripping the 4-per-hour limit. `deploy.sh` copies the file into place on each deploy.
Access SearXNG through Caddy (`search.dankclaw.local`). A direct request on the published port has no `X-Forwarded-For` header. The bot-detection cannot resolve the client and returns 429. The podman bridge subnet is in `trusted_proxies` so Caddy's request is trusted. The bridge CIDR is assigned dynamically by rootless podman. Pin the network (`podman network create` with a fixed `--subnet`) for a stable value.
Access SearXNG through Caddy (`search.dankclaw.local`). A direct request on the published port has no `X-Forwarded-For` header. The bot-detection cannot resolve the client and returns 429. The searxng network subnet 10.89.2.0/24 is in `trusted_proxies` so Caddy's request is trusted. The subnet is pinned in `searxng.network`, so the value stays stable across reboots.
## Gotchas
+11 -7
View File
@@ -18,13 +18,15 @@ The official SearXNG docker-compose ships a `searxng-valkey` container. Valkey i
## Configuration
```yaml
services:
valkey:
image: valkey/valkey:9-alpine
restart: always
volumes:
- /opt/searxng/valkey:/data
The valkey unit is `searxng-valkey.container` (see [[SearXNG]] for the trio). It joins the searxng network and is reachable by the name `searxng-valkey` (container name) and the alias `valkey`:
```ini
[Container]
ContainerName=searxng-valkey
Network=searxng.network
NetworkAlias=valkey
Image=docker.io/valkey/valkey:9-alpine
Volume=/opt/searxng/valkey:/data
```
SearXNG connects to it via `settings.yml`:
@@ -34,6 +36,8 @@ valkey:
url: "valkey://searxng-valkey:6379/0"
```
It sets `WantedBy=default.target`. User linger is on, so it starts at boot.
## Volumes
| Container path | Host path (convention) |