- Correct off-by-one in UID mapping: container UID N → host UID (100000 + N - 1), not (100000 + N) - Deploy script auto-fixes UID ownership on every deploy - Bitcoin UI nginx uses __BITCOIN_RPC_AUTH__ placeholder injected from secrets at deploy time - container rules updated for rootless podman architecture Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2.5 KiB
2.5 KiB
globs
| globs | |||||||
|---|---|---|---|---|---|---|---|
|
Container Security Rules (Archipelago — Rootless Podman)
Rootless Podman Architecture
- Podman runs as
archipelagouser (UID 1000), NOT root — never usesudo podman - UID namespace mapping via subuid: container UID N → host UID (100000 + N)
- Container images stored in
~/.local/share/containers/storage/(NOT /var/lib/containers) - Container subnet:
10.89.0.0/16(rootless), not10.88.0.0/16(rootful) - XDG_RUNTIME_DIR must be
/run/user/1000— required for podman socket loginctl enable-linger archipelagorequired for containers to survive logout
Container Security (Non-Negotiable)
- Drop ALL capabilities, add only what's required (
--cap-drop=ALL --cap-add=...) - Set
--security-opt=no-new-privileges:trueon all containers - Use
--read-only+ tmpfs where possible (safe apps: searxng, grafana, filebrowser, electrumx, nostr-rs-relay, ollama, indeedhub) - Pin image versions — never use
:latesttag - Mount secrets as read-only files, never pass as environment variables when possible
- Set memory and CPU limits on all containers
- All containers must have
--restart unless-stopped
Volume Ownership (Critical for Rootless)
- Volume directories must be owned by the MAPPED UID, not the container UID
- Formula:
host_uid = 100000 + container_uid - UID 0 (most apps) →
sudo chown -R 100000:100000 /var/lib/archipelago/{app} - UID 101 (bitcoin) →
sudo chown -R 100101:100101 /var/lib/archipelago/bitcoin - UID 70 (postgres) →
sudo chown -R 100070:100070 /var/lib/archipelago/postgres-* - UID 472 (grafana) →
sudo chown -R 100472:100472 /var/lib/archipelago/grafana - UID 999 (mariadb) →
sudo chown -R 100999:100999 /var/lib/archipelago/mysql-*
Systemd Service Requirements
ProtectHome=no— podman needs~/.local/share/containers/PrivateTmp=no— podman runtime uses/tmp/podman-run-1000/RestrictNamespaces=must NOT be set — rootless podman creates user namespacesSystemCallFilter=must NOT be set — rootless podman needs clone/unshare- UFW
DEFAULT_FORWARD_POLICY="ACCEPT"— required for LAN access to container ports
Network Rules
- Apps needing inter-container DNS: use
--network=archy-net(bitcoin, lnd, electrumx, mempool, btcpay, fedimint) - Standalone apps: default bridge network
- Tailscale only:
--network=host+NET_ADMIN+NET_RAW+/dev/net/tun