Migrate Gitea proxy to canonical Caddy
This commit is contained in:
@@ -1,31 +0,0 @@
|
|||||||
# Quadlet unit: Gitea Caddy reverse proxy (rootless, boot-persistent).
|
|
||||||
#
|
|
||||||
# Install path on dankclaw: ~/.config/containers/systemd/gitea-caddy.container
|
|
||||||
# Unit name: gitea-caddy.service (podman 5.x drops the container- prefix)
|
|
||||||
#
|
|
||||||
# Serves gitea.franksdank.cloud (public domain, DNS pending). The LAN
|
|
||||||
# reaches Gitea directly on port 3000. This file holds no secrets.
|
|
||||||
# See docs/Dankclaw/Gitea.md.
|
|
||||||
|
|
||||||
[Unit]
|
|
||||||
Description=Gitea Caddy reverse proxy container
|
|
||||||
Wants=gitea-server.service
|
|
||||||
After=gitea-server.service network.target
|
|
||||||
|
|
||||||
[Container]
|
|
||||||
ContainerName=gitea-caddy
|
|
||||||
Network=gitea.network
|
|
||||||
Image=docker.io/library/caddy:latest
|
|
||||||
PublishPort=80:80
|
|
||||||
PublishPort=443:443
|
|
||||||
Volume=/opt/gitea/data/caddy/Caddyfile:/etc/caddy/Caddyfile
|
|
||||||
Volume=/opt/gitea/data/caddy/site:/srv
|
|
||||||
Volume=/opt/gitea/data/caddy/config:/config
|
|
||||||
Volume=/opt/gitea/data/caddy/data:/root/.local/share/caddy
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
TimeoutStartSec=900
|
|
||||||
Restart=always
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=default.target
|
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
# Unit name: gitea-network.service (podman network name: systemd-gitea)
|
# Unit name: gitea-network.service (podman network name: systemd-gitea)
|
||||||
#
|
#
|
||||||
# DNS is enabled by default for quadlet networks. This matters: the
|
# DNS is enabled by default for quadlet networks. This matters: the
|
||||||
# automatic "podman" default network has dns_enabled=false, so container
|
# automatic "podman" default network has dns_enabled=false, so the
|
||||||
# names (gitea-postgres, gitea-server, gitea-caddy) would not resolve.
|
# gitea-postgres and gitea-server container names would not resolve.
|
||||||
|
|
||||||
[Network]
|
[Network]
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ SERVICE_ORDER = (
|
|||||||
"open-webui",
|
"open-webui",
|
||||||
"gitea-postgres",
|
"gitea-postgres",
|
||||||
"gitea-server",
|
"gitea-server",
|
||||||
"gitea-caddy",
|
|
||||||
"comfyui",
|
"comfyui",
|
||||||
"hermes",
|
"hermes",
|
||||||
"hermes-dashboard",
|
"hermes-dashboard",
|
||||||
@@ -66,7 +65,6 @@ DANKCLAW_SERVICES = {
|
|||||||
"open-webui",
|
"open-webui",
|
||||||
"gitea-postgres",
|
"gitea-postgres",
|
||||||
"gitea-server",
|
"gitea-server",
|
||||||
"gitea-caddy",
|
|
||||||
"comfyui",
|
"comfyui",
|
||||||
"hermes",
|
"hermes",
|
||||||
"hermes-dashboard",
|
"hermes-dashboard",
|
||||||
@@ -276,9 +274,12 @@ def services_for_path(path: str, target: str) -> set[str]:
|
|||||||
elif name == "gitea-server.container":
|
elif name == "gitea-server.container":
|
||||||
_add(services, "gitea-server")
|
_add(services, "gitea-server")
|
||||||
elif name == "gitea-caddy.container":
|
elif name == "gitea-caddy.container":
|
||||||
_add(services, "gitea-caddy")
|
# Removing the old split proxy requires the canonical
|
||||||
|
# Caddy handler to retire its installed unit/container
|
||||||
|
# before it claims ports 80/443.
|
||||||
|
_add(services, "caddy")
|
||||||
elif name == "gitea.network":
|
elif name == "gitea.network":
|
||||||
_add(services, "gitea-postgres", "gitea-server", "gitea-caddy")
|
_add(services, "gitea-postgres", "gitea-server")
|
||||||
return services
|
return services
|
||||||
return services
|
return services
|
||||||
|
|
||||||
|
|||||||
+31
-18
@@ -84,7 +84,7 @@ service_is_allowed() {
|
|||||||
case "$TARGET:$service" in
|
case "$TARGET:$service" in
|
||||||
dankclaw:gluetun|dankclaw:searxng-valkey|dankclaw:searxng|dankclaw:pihole|\
|
dankclaw:gluetun|dankclaw:searxng-valkey|dankclaw:searxng|dankclaw:pihole|\
|
||||||
dankclaw:open-webui|dankclaw:gitea-postgres|dankclaw:gitea-server|\
|
dankclaw:open-webui|dankclaw:gitea-postgres|dankclaw:gitea-server|\
|
||||||
dankclaw:gitea-caddy|dankclaw:comfyui|dankclaw:hermes|\
|
dankclaw:comfyui|dankclaw:hermes|\
|
||||||
dankclaw:hermes-dashboard|dankclaw:prometheus|dankclaw:grafana|\
|
dankclaw:hermes-dashboard|dankclaw:prometheus|dankclaw:grafana|\
|
||||||
dankclaw:loki|dankclaw:alloy|dankclaw:node-exporter|\
|
dankclaw:loki|dankclaw:alloy|dankclaw:node-exporter|\
|
||||||
dankclaw:authentik-postgres|dankclaw:authentik-server|\
|
dankclaw:authentik-postgres|dankclaw:authentik-server|\
|
||||||
@@ -248,6 +248,33 @@ deploy_homepage() {
|
|||||||
run_privileged python3 /usr/local/bin/homepage-status.py /srv/homepage/services.json /srv/homepage/status.json
|
run_privileged python3 /usr/local/bin/homepage-status.py /srv/homepage/services.json /srv/homepage/status.json
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retire_legacy_gitea_caddy() {
|
||||||
|
# The old split proxy owns ports 80/443 on hosts upgraded in place. Stop
|
||||||
|
# and disable its generated unit before the canonical Caddy is started.
|
||||||
|
if systemctl --user is-active --quiet gitea-caddy.service 2>/dev/null; then
|
||||||
|
systemctl --user stop gitea-caddy.service
|
||||||
|
fi
|
||||||
|
if systemctl --user is-enabled --quiet gitea-caddy.service 2>/dev/null; then
|
||||||
|
systemctl --user disable gitea-caddy.service
|
||||||
|
fi
|
||||||
|
local unit_dir="$HOME/.config/containers/systemd"
|
||||||
|
local legacy_trash="$HOME/.AGENTTRASH/$(date +%Y%m%d)-gitea-caddy"
|
||||||
|
# Podman generators scan the unit directory recursively on this host, so
|
||||||
|
# leaving the retired file in systemd/.AGENTTRASH would regenerate it.
|
||||||
|
# Stage it outside the unit tree in the dated home trash instead.
|
||||||
|
for unit_file in "$unit_dir/gitea-caddy.container" \
|
||||||
|
"$unit_dir/.AGENTTRASH/gitea-caddy.container"; do
|
||||||
|
if [[ -e "$unit_file" ]]; then
|
||||||
|
mkdir -p "$legacy_trash"
|
||||||
|
mv -- "$unit_file" "$legacy_trash/"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
systemctl --user daemon-reload
|
||||||
|
if podman container exists gitea-caddy; then
|
||||||
|
podman rm --force gitea-caddy
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
deploy_caddy() {
|
deploy_caddy() {
|
||||||
if [[ "$TARGET" != dankclaw ]]; then
|
if [[ "$TARGET" != dankclaw ]]; then
|
||||||
echo "caddy is owned by dankclaw; refusing to deploy it on $TARGET" >&2
|
echo "caddy is owned by dankclaw; refusing to deploy it on $TARGET" >&2
|
||||||
@@ -263,22 +290,9 @@ deploy_caddy() {
|
|||||||
podman build --no-cache --label "cfhash=$cfhash" -t "$image:latest" \
|
podman build --no-cache --label "cfhash=$cfhash" -t "$image:latest" \
|
||||||
-f dankclaw/caddy/Containerfile .
|
-f dankclaw/caddy/Containerfile .
|
||||||
fi
|
fi
|
||||||
# The canonical reverse proxy may be gitea-caddy on a host with the old
|
# Retire the old split proxy before claiming ports 80/443. This is
|
||||||
# split deployment. Never stop or replace it implicitly. Refuse the Caddy
|
# idempotent and leaves the old unit recoverable in the target trash.
|
||||||
# deployment until the operator has explicitly migrated port ownership.
|
retire_legacy_gitea_caddy
|
||||||
if podman container exists gitea-caddy && ! podman container exists caddy; then
|
|
||||||
echo "FAIL: gitea-caddy owns the reverse-proxy deployment; refusing to replace it with caddy." >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
if podman container exists gitea-caddy && podman container exists caddy; then
|
|
||||||
local gitea_state caddy_state
|
|
||||||
gitea_state="$(podman inspect gitea-caddy --format '{{.State.Status}}' 2>/dev/null || true)"
|
|
||||||
caddy_state="$(podman inspect caddy --format '{{.State.Status}}' 2>/dev/null || true)"
|
|
||||||
if [[ "$gitea_state" == running && "$caddy_state" != running ]]; then
|
|
||||||
echo "FAIL: gitea-caddy currently owns ports 80/443; refusing to start caddy." >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if podman container exists caddy; then
|
if podman container exists caddy; then
|
||||||
podman-compose -f dankclaw/compose.yaml up -d --no-deps caddy
|
podman-compose -f dankclaw/compose.yaml up -d --no-deps caddy
|
||||||
local reloaded=0
|
local reloaded=0
|
||||||
@@ -482,7 +496,6 @@ deploy_service() {
|
|||||||
pihole) deploy_pihole ;;
|
pihole) deploy_pihole ;;
|
||||||
gitea-postgres) deploy_gitea_unit gitea-postgres gitea-postgres ;;
|
gitea-postgres) deploy_gitea_unit gitea-postgres gitea-postgres ;;
|
||||||
gitea-server) deploy_gitea_unit gitea-server gitea-server ;;
|
gitea-server) deploy_gitea_unit gitea-server gitea-server ;;
|
||||||
gitea-caddy) deploy_gitea_unit gitea-caddy gitea-caddy ;;
|
|
||||||
frank-default-large) deploy_llm_large ;;
|
frank-default-large) deploy_llm_large ;;
|
||||||
frank-default-small) deploy_llm_small ;;
|
frank-default-small) deploy_llm_small ;;
|
||||||
frank-default-npu) deploy_llm_npu ;;
|
frank-default-npu) deploy_llm_npu ;;
|
||||||
|
|||||||
+1
-1
@@ -115,7 +115,7 @@ valid_service() {
|
|||||||
case "$TARGET:$service" in
|
case "$TARGET:$service" in
|
||||||
dankclaw:gluetun|dankclaw:searxng-network|dankclaw:searxng-valkey|dankclaw:searxng|\
|
dankclaw:gluetun|dankclaw:searxng-network|dankclaw:searxng-valkey|dankclaw:searxng|\
|
||||||
dankclaw:pihole|dankclaw:open-webui|dankclaw:gitea-postgres|dankclaw:gitea-server|\
|
dankclaw:pihole|dankclaw:open-webui|dankclaw:gitea-postgres|dankclaw:gitea-server|\
|
||||||
dankclaw:gitea-caddy|dankclaw:comfyui|dankclaw:hermes|dankclaw:hermes-dashboard|\
|
dankclaw:comfyui|dankclaw:hermes|dankclaw:hermes-dashboard|\
|
||||||
dankclaw:prometheus|dankclaw:grafana|dankclaw:loki|dankclaw:alloy|\
|
dankclaw:prometheus|dankclaw:grafana|dankclaw:loki|dankclaw:alloy|\
|
||||||
dankclaw:node-exporter|dankclaw:authentik-postgres|dankclaw:authentik-server|\
|
dankclaw:node-exporter|dankclaw:authentik-postgres|dankclaw:authentik-server|\
|
||||||
dankclaw:authentik-worker|dankclaw:caddy|dankclaw:homepage|\
|
dankclaw:authentik-worker|dankclaw:caddy|dankclaw:homepage|\
|
||||||
|
|||||||
@@ -85,6 +85,15 @@ CADDYFILE="$REPO_ROOT/dankclaw/Caddyfile"
|
|||||||
grep -q 'curl.*-sf.*http://localhost:80/' "$REPO_ROOT/dankclaw/compose.yaml"
|
grep -q 'curl.*-sf.*http://localhost:80/' "$REPO_ROOT/dankclaw/compose.yaml"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "Gitea has no standalone reverse-proxy Quadlet" {
|
||||||
|
[ ! -e "$REPO_ROOT/dankclaw/gitea/quadlet/gitea-caddy.container" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "the canonical Caddy owns the Gitea route" {
|
||||||
|
grep -qF 'gitea.franksdank.cloud {' "$CADDYFILE"
|
||||||
|
grep -qF 'reverse_proxy 192.168.0.143:3000' "$CADDYFILE"
|
||||||
|
}
|
||||||
|
|
||||||
# --- Phase 2: real TLS via DNS-01 (Porkbun wildcard cert) ---
|
# --- Phase 2: real TLS via DNS-01 (Porkbun wildcard cert) ---
|
||||||
|
|
||||||
@test "all vhosts use TLS except the legacy .casa name" {
|
@test "all vhosts use TLS except the legacy .casa name" {
|
||||||
|
|||||||
@@ -47,6 +47,13 @@ load helpers
|
|||||||
! grep -qE 'podman-compose.*(up|restart).*\$\(' "$REPO_ROOT/scripts/deploy-remote.sh"
|
! grep -qE 'podman-compose.*(up|restart).*\$\(' "$REPO_ROOT/scripts/deploy-remote.sh"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "Caddy migration retires the standalone Gitea proxy" {
|
||||||
|
grep -q 'retire_legacy_gitea_caddy' "$REPO_ROOT/scripts/deploy-remote.sh"
|
||||||
|
grep -q 'systemctl --user stop gitea-caddy.service' "$REPO_ROOT/scripts/deploy-remote.sh"
|
||||||
|
grep -q 'systemctl --user disable gitea-caddy.service' "$REPO_ROOT/scripts/deploy-remote.sh"
|
||||||
|
! grep -q 'deploy_gitea_unit gitea-caddy' "$REPO_ROOT/scripts/deploy-remote.sh"
|
||||||
|
}
|
||||||
|
|
||||||
@test "remote runner has separate handlers for both inference services" {
|
@test "remote runner has separate handlers for both inference services" {
|
||||||
grep -q 'deploy_llm_large' "$REPO_ROOT/scripts/deploy-remote.sh"
|
grep -q 'deploy_llm_large' "$REPO_ROOT/scripts/deploy-remote.sh"
|
||||||
grep -q 'deploy_llm_small' "$REPO_ROOT/scripts/deploy-remote.sh"
|
grep -q 'deploy_llm_small' "$REPO_ROOT/scripts/deploy-remote.sh"
|
||||||
|
|||||||
@@ -97,6 +97,38 @@ REMOTE_DEPLOY="$REPO_ROOT/scripts/deploy-remote.sh"
|
|||||||
[ "$output" = $'gluetun\nsearxng' ]
|
[ "$output" = $'gluetun\nsearxng' ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "retiring the standalone Gitea proxy deploys the canonical Caddy" {
|
||||||
|
run python3 "$PLANNER" --target dankclaw --paths \
|
||||||
|
dankclaw/gitea/quadlet/gitea-caddy.container
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[ "$output" = "caddy" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Gitea network changes exclude the retired standalone proxy" {
|
||||||
|
run python3 "$PLANNER" --target dankclaw --paths \
|
||||||
|
dankclaw/gitea/quadlet/gitea.network
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[ "$output" = $'gitea-postgres\ngitea-server' ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "remote Caddy deployment no longer blocks on the retired Gitea proxy" {
|
||||||
|
! grep -q 'refusing to replace it with caddy' "$REMOTE_DEPLOY"
|
||||||
|
! grep -q 'podman container exists gitea-caddy &&' "$REMOTE_DEPLOY"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "remote Caddy deployment retires the installed Gitea proxy" {
|
||||||
|
grep -q 'retire_legacy_gitea_caddy' "$REMOTE_DEPLOY"
|
||||||
|
grep -q 'systemctl --user stop gitea-caddy.service' "$REMOTE_DEPLOY"
|
||||||
|
grep -q 'systemctl --user disable gitea-caddy.service' "$REMOTE_DEPLOY"
|
||||||
|
grep -q 'gitea-caddy.container' "$REMOTE_DEPLOY"
|
||||||
|
grep -q 'HOME/.AGENTTRASH' "$REMOTE_DEPLOY"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "remote deployment inventory no longer accepts gitea-caddy as a service" {
|
||||||
|
! grep -qE 'dankclaw:gitea-caddy|gitea-caddy\) deploy' "$REPO_ROOT/scripts/deploy.sh" "$REPO_ROOT/scripts/deploy-remote.sh"
|
||||||
|
! grep -q '"gitea-caddy"' "$REPO_ROOT/scripts/deploy-plan.py"
|
||||||
|
}
|
||||||
|
|
||||||
@test "remote deployer carries per-service deployment state" {
|
@test "remote deployer carries per-service deployment state" {
|
||||||
[ -x "$REMOTE_DEPLOY" ]
|
[ -x "$REMOTE_DEPLOY" ]
|
||||||
grep -q 'deploy-state' "$REMOTE_DEPLOY"
|
grep -q 'deploy-state' "$REMOTE_DEPLOY"
|
||||||
|
|||||||
Reference in New Issue
Block a user