nginx-conf/deploy-nginx.sh

232 lines
5.0 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
# ---------------------------
# Config
# ---------------------------
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
NGINX_ETC="/etc/nginx"
SITES_AVAIL="$NGINX_ETC/sites-available"
SITES_ENABLED="$NGINX_ETC/sites-enabled"
SNIPPETS="$NGINX_ETC/snippets"
CONFD="$NGINX_ETC/conf.d"
# Static file deploy targets (match your current layout)
WEB_HTML="/var/www/html"
WEB_ERRORS="/var/www/errors"
ENABLE_SITES=(
"default"
"nik4nao.home.arpa"
"nik4nao.xyz"
"prv-api.nik4nao.xyz"
)
BACKUP_BASE="/var/backups/nginx-conf-deploy"
# ---------------------------
# Helpers
# ---------------------------
usage() {
cat <<'EOF'
Usage:
sudo ./deploy-nginx.sh [--dry-run]
EOF
}
log() { echo "==> $*"; }
need_root() {
if [[ "${EUID}" -ne 0 ]]; then
echo "ERROR: run as root (use sudo)." >&2
exit 1
fi
}
DRY_RUN=0
if [[ "${1:-}" == "--dry-run" ]]; then
DRY_RUN=1
elif [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
usage
exit 0
elif [[ -n "${1:-}" ]]; then
echo "Unknown option: $1" >&2
usage
exit 1
fi
need_root
timestamp="$(date +%Y%m%d-%H%M%S)"
backup_dir="${BACKUP_BASE}/${timestamp}"
backup_tar="${backup_dir}/backup.tar.gz"
mkdir_p() {
if (( DRY_RUN )); then
log "[dry-run] mkdir -p $*"
else
mkdir -p "$@"
fi
}
copy_file() {
local src="$1"
local dst="$2"
if [[ ! -f "$src" ]]; then
echo "ERROR: missing source file: $src" >&2
exit 1
fi
if (( DRY_RUN )); then
log "[dry-run] install -m 0644 $src -> $dst"
else
install -m 0644 -D "$src" "$dst"
fi
}
make_symlink() {
local target="$1"
local linkpath="$2"
if (( DRY_RUN )); then
log "[dry-run] ln -sfn $target $linkpath"
else
ln -sfn "$target" "$linkpath"
fi
}
sync_selected_http_files() {
# Copy only the files you actually use, into the two target dirs
local src_dir="$REPO_DIR/http"
# /var/www/html
for f in index.html index.nginx-debian.html nik4nao-xyz-landing.html; do
if [[ -f "$src_dir/$f" ]]; then
copy_file "$src_dir/$f" "$WEB_HTML/$f"
fi
done
# /var/www/errors
for f in 404.html 50x.html; do
if [[ -f "$src_dir/$f" ]]; then
copy_file "$src_dir/$f" "$WEB_ERRORS/$f"
fi
done
}
backup_paths=()
add_backup_path() {
local p="$1"
if [[ -e "$p" || -L "$p" ]]; then
backup_paths+=("$p")
fi
}
do_backup() {
mkdir_p "$backup_dir"
# nginx files we touch
add_backup_path "$NGINX_ETC/nginx.conf"
add_backup_path "$CONFD/upstreams.conf"
add_backup_path "$SNIPPETS/proxy-common.conf"
for s in "${ENABLE_SITES[@]}"; do
add_backup_path "$SITES_AVAIL/$s"
add_backup_path "$SITES_ENABLED/$s"
done
# static files we touch (only the known ones)
for f in index.html index.nginx-debian.html nik4nao-xyz-landing.html robots.txt; do
add_backup_path "$WEB_HTML/$f"
done
for f in 404.html 50x.html; do
add_backup_path "$WEB_ERRORS/$f"
done
if (( DRY_RUN )); then
log "[dry-run] tar -czf $backup_tar -P ${backup_paths[*]:-}"
return
fi
if ((${#backup_paths[@]} == 0)); then
log "No existing paths found to backup (first deploy?)."
return
fi
log "Creating backup: $backup_tar"
tar -czf "$backup_tar" -P "${backup_paths[@]}"
}
restore_backup() {
if (( DRY_RUN )); then
log "[dry-run] restore from $backup_tar"
return
fi
if [[ -f "$backup_tar" ]]; then
log "Restoring from backup..."
tar -xzf "$backup_tar" -P
else
log "No backup tar found to restore: $backup_tar"
fi
}
nginx_test() {
if (( DRY_RUN )); then
log "[dry-run] nginx -t"
return 0
fi
nginx -t
}
nginx_reload() {
if (( DRY_RUN )); then
log "[dry-run] systemctl reload nginx"
return 0
fi
systemctl reload nginx
}
# ---------------------------
# Deploy
# ---------------------------
log "Repo: $REPO_DIR"
do_backup
mkdir_p "$SITES_AVAIL" "$SITES_ENABLED" "$SNIPPETS" "$CONFD" "$WEB_HTML" "$WEB_ERRORS"
# Copy core config/snippets
copy_file "$REPO_DIR/nginx.conf" "$NGINX_ETC/nginx.conf"
copy_file "$REPO_DIR/upstreams.conf" "$CONFD/upstreams.conf"
copy_file "$REPO_DIR/proxy-common.conf" "$SNIPPETS/proxy-common.conf"
# Copy site configs (repo *.conf -> /etc/nginx/sites-available/<name>)
copy_file "$REPO_DIR/default.conf" "$SITES_AVAIL/default"
copy_file "$REPO_DIR/nik4nao.home.arpa.conf" "$SITES_AVAIL/nik4nao.home.arpa"
copy_file "$REPO_DIR/nik4nao.xyz.conf" "$SITES_AVAIL/nik4nao.xyz"
copy_file "$REPO_DIR/prv-api.nik4nao.xyz.conf" "$SITES_AVAIL/prv-api.nik4nao.xyz"
# Enable sites
for s in "${ENABLE_SITES[@]}"; do
make_symlink "$SITES_AVAIL/$s" "$SITES_ENABLED/$s"
done
# Static files
sync_selected_http_files
if [[ -f "$REPO_DIR/robots.txt" ]]; then
copy_file "$REPO_DIR/robots.txt" "$WEB_HTML/robots.txt"
fi
# Test + reload (rollback on failure)
log "Testing nginx config..."
if nginx_test; then
log "Reloading nginx..."
nginx_reload
log "Done ✅"
else
log "nginx -t failed ❌"
log "Rolling back..."
restore_backup
log "Re-testing after rollback..."
nginx_test || true
exit 2
fi