diff --git a/.gitea/workflows/deploy-caddy.yml b/.gitea/workflows/deploy-caddy.yml index a5f6c9c..aa790c4 100644 --- a/.gitea/workflows/deploy-caddy.yml +++ b/.gitea/workflows/deploy-caddy.yml @@ -17,15 +17,37 @@ jobs: - name: Push Caddyfile and reload Caddy run: | - # Job containers do NOT inherit the runner's /config/caddy bind. - # Docker-from-Docker with a host bind is the reliable path: the - # volume source is resolved on valhalla, not inside the job container. - # (Direct `cp /config/caddy/...` only works on the runner container - # itself, which is not where this step runs.) - apt-get update -qq && apt-get install -y -qq docker.io - docker run --rm \ - -v /config/caddy:/dest \ - -v "$PWD/Caddyfile:/src/Caddyfile:ro" \ - alpine:3.20 \ - cp /src/Caddyfile /dest/Caddyfile - docker exec caddy caddy reload --config /etc/caddy/Caddyfile + set -euo pipefail + + # The runner (act_runner config.yaml `container.options`) binds + # /config/caddy and /var/run/docker.sock into every job container, + # so both are already here -- no docker-from-docker, no docker CLI. + # + # Do NOT bind $PWD into a `docker run`: the workspace is a Docker + # volume, so the daemon resolves the source on the HOST, finds + # nothing, and creates an empty directory there instead. That is + # what broke runs 137-139. + # + # cp (not mv/install): /config/caddy/Caddyfile is bind-mounted into + # the caddy container as a single FILE, so the bind follows the + # inode. Replacing the inode would silently detach caddy from it. + cp Caddyfile /config/caddy/Caddyfile + + # Reload via the Docker Engine API over the mounted socket. + SOCK=/var/run/docker.sock + api() { curl -sS --unix-socket "$SOCK" "$@"; } + json() { node -e 'let d="";process.stdin.on("data",c=>d+=c).on("end",()=>console.log(JSON.parse(d)[process.argv[1]]))' "$1"; } + + EXEC_ID=$(api -X POST -H 'Content-Type: application/json' \ + -d '{"AttachStdout":true,"AttachStderr":true,"Cmd":["caddy","reload","--config","/etc/caddy/Caddyfile"]}' \ + "http://localhost/containers/caddy/exec" | json Id) + + # Strip the stream-multiplexing frame headers from the output. + api -X POST -H 'Content-Type: application/json' -d '{"Detach":false,"Tty":false}' \ + "http://localhost/exec/$EXEC_ID/start" | tr -d '\000-\010\013\014\016-\037' + echo + + # caddy reload validates before applying; a bad Caddyfile fails here. + CODE=$(api "http://localhost/exec/$EXEC_ID/json" | json ExitCode) + echo "caddy reload exit code: $CODE" + exit "$CODE"