From 71fe8c008f15ad5d53ae55601ed0da6e3c43fc18 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 18 Aug 2026 23:34:08 -0700 Subject: [PATCH] SearXNG: move the trio out of compose into quadlet deployment Remove gluetun/searxng/valkey from dankclaw/compose.yaml (they are now quadlet units) so podman-compose up can no longer fight them for the netns and port 8081. Add scripts/deploy-searxng-quadlet.sh: an idempotent installer that copies the units to ~/.config/containers/systemd/, daemon-reloads, enables them for boot, and starts them in dependency order. Safe to run on first migration and on every later change. --- dankclaw/compose.yaml | 68 +++------------------- scripts/deploy-searxng-quadlet.sh | 93 +++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 61 deletions(-) create mode 100755 scripts/deploy-searxng-quadlet.sh diff --git a/dankclaw/compose.yaml b/dankclaw/compose.yaml index f92f6fc..cfbc080 100644 --- a/dankclaw/compose.yaml +++ b/dankclaw/compose.yaml @@ -3,67 +3,13 @@ # See ../docs/Dankclaw/ and ../docs/Infrastructure/ for service documentation. services: - # --- VPN tunnel: SearXNG outbound traffic only --------------------------- - gluetun: - image: docker.io/qmcgaw/gluetun:latest - container_name: gluetun - restart: always - cap_add: - - NET_ADMIN - devices: - - /dev/net/tun:/dev/net/tun - environment: - VPN_SERVICE_PROVIDER: "${VPN_SERVICE_PROVIDER}" - VPN_TYPE: "${VPN_TYPE}" - WIREGUARD_PRIVATE_KEY: "${WIREGUARD_PRIVATE_KEY}" - WIREGUARD_ADDRESSES: "${WIREGUARD_ADDRESSES}" - WIREGUARD_PUBLIC_KEY: "${WIREGUARD_PUBLIC_KEY}" - WIREGUARD_ENDPOINT_IP: "${WIREGUARD_ENDPOINT_IP}" - WIREGUARD_ENDPOINT_PORT: "${WIREGUARD_ENDPOINT_PORT}" - WIREGUARD_ALLOWED_IPS: "${WIREGUARD_ALLOWED_IPS}" - WIREGUARD_PERSISTENT_KEEPALIVE_INTERVAL: "${WIREGUARD_PERSISTENT_KEEPALIVE_INTERVAL}" - ports: - # SearXNG's published port lives on gluetun (network_mode: service:gluetun) - - "8081:8080" - healthcheck: - # The gluetun image has no curl, and its :8000 status server 404s on - # every path. Check the WireGuard tunnel interface instead: tun0 exists - # only while the VPN is connected, so this reflects real tunnel state. - test: ["CMD", "sh", "-c", "test -e /sys/class/net/tun0"] - interval: 60s - timeout: 10s - retries: 3 - - searxng: - image: ghcr.io/searxng/searxng:latest - container_name: searxng - restart: unless-stopped - network_mode: "service:gluetun" - depends_on: - - gluetun - - valkey - environment: - SEARXNG_SECRET: "${SEARXNG_SECRET}" - SEARXNG_BASE_URL: "${SEARXNG_BASE_URL}" - volumes: - - /opt/searxng/config:/etc/searxng - healthcheck: - test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8080/healthz')"] - interval: 30s - timeout: 10s - retries: 3 - - valkey: - image: docker.io/valkey/valkey:9-alpine - container_name: searxng-valkey - restart: always - volumes: - - /opt/searxng/valkey:/data - healthcheck: - test: ["CMD", "valkey-cli", "ping"] - interval: 30s - timeout: 10s - retries: 3 + # --- SearXNG stack (gluetun + searxng + valkey) -------------------------- + # These three services are now boot-persistent Quadlet units, not compose + # services. They live in searxng/quadlet/ and install to + # ~/.config/containers/systemd/ on the host. searxng reuses gluetun's netns + # (Network=gluetun.container) so its traffic exits the WireGuard tunnel. + # Deploy with: scripts/deploy-searxng-quadlet.sh dankclaw + # See ../docs/Dankclaw/SearXNG.md, Gluetun.md, Valkey.md. # --- AI image generation (CPU backend; ROCm does not support gfx1151) ---- comfyui: diff --git a/scripts/deploy-searxng-quadlet.sh b/scripts/deploy-searxng-quadlet.sh new file mode 100755 index 0000000..ec5942e --- /dev/null +++ b/scripts/deploy-searxng-quadlet.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env bash +# deploy-searxng-quadlet.sh — Install and (re)start the SearXNG quadlet stack. +# +# The gluetun + searxng + valkey trio is boot-persistent via Quadlet, not +# podman-compose (see AGENTS.md). This script: +# 1. Pushes main to origin +# 2. Pulls the repo on the target +# 3. Copies the quadlet units into ~/.config/containers/systemd/ +# 4. daemon-reloads, enables the units for boot, and starts them in order +# +# It is idempotent: it stops any running units and removes any containers with +# the trio's names (compose leftovers or the previous quadlet run) before +# reinstalling and starting, so it is safe to run on first migration and on +# every later config change. +# +# Usage: +# ./scripts/deploy-searxng-quadlet.sh [--dry-run] +# ./scripts/deploy-searxng-quadlet.sh dankclaw +set -euo pipefail + +REMOTE_USER="dank" +REMOTE_HOST="dankclaw" +REMOTE_DIR="/home/dank/serverAppConfigs" +QDIR="dankclaw/searxng/quadlet" +UNITS="searxng-network.service gluetun.service searxng-valkey.service searxng.service" + +TARGET="${1:-}" +DRY_RUN=0 +if [ "${2:-}" = "--dry-run" ]; then + DRY_RUN=1 +fi + +if [ -z "${TARGET:-}" ]; then + echo "Usage: $0 [--dry-run]" + exit 1 +fi +if [ "${TARGET}" != "dankclaw" ]; then + echo "This stack runs only on dankclaw (got: ${TARGET})" + exit 1 +fi + +# --------------------------------------------------------------------------- +# Local pre-flight +# --------------------------------------------------------------------------- +cd "$(dirname "$0")/.." +if ! git diff --quiet HEAD; then + echo "FAIL: Local working tree has uncommitted changes. Commit first." + exit 1 +fi + +if [ "$DRY_RUN" = "1" ]; then + echo "[dry-run] Would push main, pull on ${REMOTE_HOST}, install quadlet units, and start: ${UNITS}" + exit 0 +fi + +echo "=== Deploying SearXNG quadlet stack to ${REMOTE_HOST} ===" +echo "[1/3] Pushing local main to origin..." +git push origin main + +REMOTE="${REMOTE_USER}@${REMOTE_HOST}" + +echo "[2/3] Installing and starting the quadlet units on ${REMOTE_HOST}..." +ssh "$REMOTE" bash -s </dev/null || true + +echo ' Removing any containers with the trio names (compose leftovers or prior run)...' +podman rm -f searxng searxng-valkey gluetun 2>/dev/null || true + +echo ' Copying quadlet units into ~/.config/containers/systemd/ ...' +mkdir -p ~/.config/containers/systemd +cp ${QDIR}/*.container ${QDIR}/*.network ~/.config/containers/systemd/ + +echo ' daemon-reload + enable for boot...' +systemctl --user daemon-reload +systemctl --user enable searxng-network.service gluetun.service searxng-valkey.service searxng.service + +echo ' Starting in dependency order...' +systemctl --user start searxng-network.service +systemctl --user start gluetun.service searxng-valkey.service +systemctl --user start searxng.service +REMOTE_EOF + +echo "[3/3] Verifying unit state..." +ssh "$REMOTE" 'systemctl --user --no-pager status searxng-network.service gluetun.service searxng-valkey.service searxng.service 2>&1 | grep -E "●|Active:"' || true + +echo "=== SearXNG quadlet stack deployed to ${REMOTE_HOST} ==="