fix: harden nginx template reload and remove stale generated configs

This commit is contained in:
lingkai5wu committed 2026-08-20 23:08:06 +08:00
1 parent 4be085d9d3
commit 44ef585ee3
1 file changed
+95 -4
+95 -4
View File
@@ -1,11 +1,102 @@
#!/usr/bin/env bash
set -euo pipefail
set -Eeuo pipefail
cd -- "$(dirname -- "${BASH_SOURCE[0]}")"
docker compose exec -T nginx /docker-entrypoint.d/20-envsubst-on-templates.sh
docker compose exec -T nginx nginx -t
docker compose exec -T nginx nginx -s reload
readonly SERVICE="nginx"
if ! docker compose exec -T "$SERVICE" true >/dev/null 2>&1; then
echo "Error: nginx container is not running." >&2
exit 1
fi
docker compose exec -T "$SERVICE" sh <<'EOF'
set -eu
TEMPLATE_DIR="/etc/nginx/templates"
OUTPUT_DIR="/etc/nginx"
ENVSUBST_SCRIPT="/docker-entrypoint.d/20-envsubst-on-templates.sh"
MANAGED_DIRS="conf.d snippets"
if [ ! -d "$TEMPLATE_DIR" ]; then
echo "Error: template directory does not exist: $TEMPLATE_DIR" >&2
exit 1
fi
if [ ! -x "$ENVSUBST_SCRIPT" ]; then
echo "Error: envsubst script is not executable: $ENVSUBST_SCRIPT" >&2
exit 1
fi
# Only allow templates in directories managed by this script.
find "$TEMPLATE_DIR" -type f -name '*.template' -print | while IFS= read -r template; do
relative="${template#"$TEMPLATE_DIR"/}"
case "$relative" in
conf.d/* | snippets/*)
;;
*)
echo "Error: unmanaged template path: $relative" >&2
exit 1
;;
esac
done
backup_dir="$(mktemp -d /tmp/nginx-reload.XXXXXX)"
committed=0
rollback() {
status=$?
if [ "$committed" -eq 0 ]; then
echo "Reload failed. Restoring previous generated configuration." >&2
for dir in $MANAGED_DIRS; do
rm -rf "$OUTPUT_DIR/$dir"
if [ -d "$backup_dir/$dir" ]; then
cp -a "$backup_dir/$dir" "$OUTPUT_DIR/$dir"
fi
done
fi
rm -rf "$backup_dir"
exit "$status"
}
trap rollback EXIT HUP INT TERM
for dir in $MANAGED_DIRS; do
if [ -d "$OUTPUT_DIR/$dir" ]; then
cp -a "$OUTPUT_DIR/$dir" "$backup_dir/$dir"
fi
done
for dir in $MANAGED_DIRS; do
if [ -d "$OUTPUT_DIR/$dir" ]; then
find "$OUTPUT_DIR/$dir" -type f -print | while IFS= read -r output; do
relative="${output#"$OUTPUT_DIR"/}"
if [ ! -f "$TEMPLATE_DIR/$relative.template" ]; then
echo "Removing stale generated file: $relative"
fi
done
fi
rm -rf "$OUTPUT_DIR/$dir"
mkdir -p "$OUTPUT_DIR/$dir"
done
"$ENVSUBST_SCRIPT"
nginx -t
committed=1
trap - EXIT HUP INT TERM
rm -rf "$backup_dir"
EOF
docker compose exec -T "$SERVICE" nginx -s reload
echo "Nginx configuration reloaded successfully."