diff options
| author | Void Agent <void@jayrup.hermes> | 2026-10-22 23:11:10 +0100 |
|---|---|---|
| committer | Void Agent <void@jayrup.hermes> | 2026-10-22 23:11:10 +0100 |
| commit | 70dffce202a8cc1d15473bbc2750bdf29a54b0fb (patch) | |
| tree | 8383299dd8a49f7805f64d57415975cf9fd9410b /deploy-docker.sh | |
| parent | b81fa0b2040e5b1b97806ffbf242948e74c4ef88 (diff) | |
nginx: serve public_key to curl cleanly, restore lost security headers
`curl https://jayrup.me/public_key` is the documented way to get this key
onto a VPS, so both the file and the config serving it need to be exact.
Key file: drop the trailing space, one trailing newline. A key with no
trailing newline makes `curl ... >> ~/.ssh/authorized_keys` glue itself onto
the previous line and silently break every later key in the file.
nginx:
- `/assets/public_key` ignored $final_suffix, so curl got 404 while browsers
got 200. Route both through the suffix-aware try_files.
- add_header does not merge across levels: the asset, PDF and .txt locations
each declared one, so they inherited none of the security headers. The
asset location now repeats them; the PDF and .txt locations no longer
declare any (default_type / mime.types + charset do the job), so they
inherit again.
- `add_header Content-Type application/pdf` appended a second Content-Type
instead of setting it. Use default_type.
- `expires 30d` plus an explicit Cache-Control emitted two Cache-Control
headers. Use one explicit header.
- add `charset utf-8` so text/plain (what curl gets) is not served
charset-less while the content contains non-ASCII.
deploy: ship nginx.conf alongside public/. It is bind-mounted into the
container, so it never travelled with the rsync'd tree — the live config was
from May and predated the hardening committed in 0ee667a. Test with
`nginx -t` before reloading and restore the previous config on failure.
Diffstat (limited to 'deploy-docker.sh')
| -rwxr-xr-x | deploy-docker.sh | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/deploy-docker.sh b/deploy-docker.sh index 2e72954..716bb8d 100755 --- a/deploy-docker.sh +++ b/deploy-docker.sh @@ -57,14 +57,32 @@ cp cv/index.txt public/cv.txt cp -r assets/* public/ cp -r assets/* public/assets/ -# nginx maps curl/wget UAs to .txt, so `curl https://jayrup.me/public_key` -# resolves to /public_key.txt. Single source of truth stays assets/public_key; -# browsers keep getting the suffixless /public_key. -cp assets/public_key public/public_key.txt +# .txt twin for curl/wget: normalize to exactly one line ending in a newline, +# so `curl https://jayrup.me/public_key >> ~/.ssh/authorized_keys` appends a +# clean key instead of gluing itself onto the previous line. +KEY="$(tr -d '\r' < assets/public_key | sed -e 's/[[:space:]]*$//' | tr -d '\n')" +[ -n "$KEY" ] || { echo "assets/public_key is empty" >&2; exit 1; } +printf '%s\n' "$KEY" > public/public_key.txt # Deploy status marker — site-visible proof of the last successful deploy printf 'deployed %s commit %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$SHORT_SHA" > public/last-deploy.txt echo ">> pushing to $DEPLOY_HOST" rsync -avz --delete public/ "$DEPLOY_HOST":~/homepage/public/ + +# nginx config is bind-mounted into the container, so it does not travel with +# public/. Test before reloading: a bad file must not take down the running +# workers, so restore the previous one and fail loudly instead. +echo ">> pushing nginx.conf" +ssh "$DEPLOY_HOST" 'cp -a ~/homepage/nginx.conf ~/homepage/nginx.conf.prev' +rsync -avz nginx.conf "$DEPLOY_HOST":~/homepage/nginx.conf +if ssh "$DEPLOY_HOST" 'docker exec homepage nginx -t'; then + ssh "$DEPLOY_HOST" 'docker exec homepage nginx -s reload' + echo ">> nginx reloaded" +else + echo "!! nginx config failed its test - restoring previous config" >&2 + ssh "$DEPLOY_HOST" 'mv ~/homepage/nginx.conf.prev ~/homepage/nginx.conf' + exit 1 +fi + echo ">> deploy OK ($SHORT_SHA)" |
