Run the Caddy TLS ingress as a Docker container

Caddy previously ran as a host binary in /opt/caddy with a wgui-caddy
systemd/OpenRC unit. Only Caddy is containerized; the app still runs on the
host as root because it shells out to wg, ip and iptables.

- Add caddy-container-commands.ts as the single source of truth for the
  run/exec/validate/inspect argument arrays. Every value stays a separate
  argv element, the image is pinned to caddy:2.11.4-alpine, and the
  entrypoint is set explicitly because some mirrors publish the image with
  a null Entrypoint (which made Docker exec "run" as a binary).
- Rewrite install-caddy.sh: require_docker with distro-specific hints,
  pull + recreate the container, assert it is running and echo the daemon
  error instead of discarding it, normalize the admin socket path in
  existing Caddyfiles, and clean up a legacy native install only after the
  container is up so the ingress port is never unbound. Add
  --purge-legacy / --purge for hosts that want to drop the old install
  without installing the container.
- Move the admin socket to /var/lib/wgui/caddy/admin.sock so it lives
  inside the mounted Caddy dir and reloads work over docker exec.
- Validate candidate configs in a throwaway container, mounting the TLS
  dir read-only as well: provisioning the tls app loads every certificate
  referenced by a tls directive, so without that mount a route with a
  certificate failed validation and its Caddyfile was never committed.
- Report docker-based installed/version/service_active, skip
  validate/reload with a warning when the image is absent, and update the
  system setup tool check to look for docker.
- Issue certificates with a docker exec reload command and chown files to
  root:root, since the container reads them through a read-only mount.
- Update the Setup UI copy and docs (README, AGENTS.md).

Also drops the unused EmptyContent import and a stray debug log in the
client route form, and stops passing the unsupported cancel_href prop to
ClientRouteForm from the route add/edit pages.
This commit is contained in:
2026-10-21 14:34:16 +01:00
parent 2cc876b062
commit cbd5451ab7
22 changed files with 652 additions and 318 deletions
+2 -2
View File
@@ -26,7 +26,7 @@ When building, refactoring, styling, or auditing UI components and layouts, acti
## Entrypoint
`src/server.ts` — runs `bunextInit()`, starts `Bun.serve` on `0.0.0.0` (port from `SiteData.ServerPort`), serves `/media/*` via `handleMediaServer`, then runs `syncWireguardHosts()` to bring host tunnels in line with the DB.
`src/server.ts` — runs `bunextInit()`, starts `Bun.serve` on `0.0.0.0` (port from `SiteData.ServerPort`), serves `/media/*` via `handleMediaServer`, then runs `syncWireguardHosts()` to bring host tunnels in line with the DB. Caddy's data plane runs as the `wgui-caddy` Docker container (host networking, `/var/lib/wgui/caddy` and `/var/lib/wgui/tls` bind-mounted); reloads go through `docker exec`, and the admin socket lives at `/var/lib/wgui/caddy/admin.sock`.
On-disk state: WireGuard keys/configs/iptables scripts live under `/var/lib/wgui` (`grabDirNames()` in `src/utils/grab-dir-names.ts`); uploaded media under `DATA_DIR` (default `./.data`).
@@ -82,7 +82,7 @@ Server functions use `index.server.ts` alongside `index.tsx` (e.g. `single-docum
- **`src/hooks/`** — `use-admin-crud-get` (with `refetch`), `use-client-rules-map`, `use-confirm`, `use-toast`, `use-theme`, `use-fetch-get`, `use-form-init`, `use-users-get`.
- **`src/utils/`** — Cookies, crypto, dir names, IP/CIDR/port/interface validators, WireGuard interface naming. Most have `.test.ts` files.
- **`src/dict/`**, **`src/data/`** — Constants (`app-data.ts`, `site-data.ts`), user types, client rules, links.
- **`src/scripts/`** — Shell scripts: `install-wg-ui.sh`, `install-caddy.sh` (idempotent Caddy/acme ingress installer used by the UI and the full installer), `setup-wireguard.sh`, `wg-quick-manage.sh`.
- **`src/scripts/`** — Shell scripts: `install-wg-ui.sh`, `install-caddy.sh` (idempotent installer that pulls the `caddy:<version>-alpine` image and (re)creates the `wgui-caddy` Docker container plus acme.sh renewal; used by the UI and the full installer), `setup-wireguard.sh`, `wg-quick-manage.sh`.
- **`src/components/general/`** — Shared app components, all built from twui. Reach for these before writing page markup:
- Page frame: `page-header` (title, meta, primary action + overflow menu), `page-body`, `panel` (the one card style), `form-section`, `form-actions` (submit is always rendered).
- Text & status: `muted-text`, `mono-text` (IPs, keys, paths), `section-label`, `status-dot`, `inline-alert`, `empty-state`, `stat-tile`, `key-value-list`, `copy-button`, `copyable-value`.