From 5244585ae031c91da83ff8c260b90190d507dba9 Mon Sep 17 00:00:00 2001 From: rob thijssen Date: Mon, 31 Aug 2026 13:46:06 +0300 Subject: [PATCH] ci(deploy): read the nginx logs without sudo The nginx log capture ran `sudo tail`, which is not in the proxy's scoped sudoers, so deploy-web failed on its very last step -- after the frontend had shipped, nginx had reloaded and every health check had passed. The deployment was complete and the job still reported failure. nginx's logs are 0644 and /var/log/nginx is traversable, so the deploy account reads them as itself; verified with `sudo -u gitea_ci tail`. Dropping the sudo is the fix, rather than widening the whitelist for something that never needed it. Also captures the public vhost's error log alongside the mesh one, since there are now two. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01XZG2i4AmfSqE97EJGBVb64 --- .gitea/workflows/deploy.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index df4be2b..ca3eecd 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -360,6 +360,14 @@ jobs: fi' echo "frontend and API both answering through rf.internal" + # No sudo: nginx's logs are world-readable and /var/log/nginx is + # traversable, so the deploy account can read them as itself. Reaching + # for sudo here would have meant widening the scoped whitelist for + # something it does not need. - name: nginx log if: always() && steps.auth.outcome == 'success' - run: ssh "$PROXY_HOST" 'sudo tail -n 50 /var/log/nginx/rf.internal.error.log' + run: | + for log in rf.internal rustingface.com; do + echo "--- /var/log/nginx/$log.error.log" + ssh "$PROXY_HOST" "tail -n 30 /var/log/nginx/$log.error.log" + done