spark-server/deploy/website/deploy.sh
DESKTOP-L8OUL9F\gfl0034 94dd2d819c Add mainland China geo gate (allow Shanghai/overseas).
Nginx auth_request plus MaxMind City lookup blocks non-Shanghai mainland CN with a fixed notice page for sparkmessenger/sparkmsg (and deploy helpers for the shared Singapore host).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-22 15:28:04 +08:00

144 lines
4.3 KiB
Bash

#!/usr/bin/env bash
# Deploy Spark Messenger website to the Singapore ECS host.
# Layout on host:
# /var/www/sparkmessenger.wyrs365.com static site
# /etc/nginx/conf.d/sparkmessenger.conf TLS vhost (loopback :8443)
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
HOST="${SPARK_SSH_HOST:-root@47.236.66.9}"
KEY="${SPARK_SSH_KEY:-$HOME/.ssh/wyrs_shanghai_deploy.pem}"
SITE_SRC="$ROOT/website"
SITE_DST="/var/www/sparkmessenger.wyrs365.com"
DOMAINS=(sparkmessenger.wyrs365.com sparkmsg.wyrs365.com)
PRIMARY="${DOMAINS[0]}"
SSH=(ssh -i "$KEY" -o BatchMode=yes -o StrictHostKeyChecking=accept-new "$HOST")
SCP=(scp -i "$KEY" -o BatchMode=yes -o StrictHostKeyChecking=accept-new)
need() {
command -v "$1" >/dev/null || {
echo "need $1 on this machine" >&2
exit 1
}
}
need ssh
need scp
need rsync
if [[ ! -f "$KEY" ]]; then
echo "missing SSH key: $KEY" >&2
exit 1
fi
if [[ ! -f "$SITE_SRC/index.html" ]]; then
echo "missing $SITE_SRC/index.html" >&2
exit 1
fi
echo "==> upload site + nginx conf + geo-guard"
"${SSH[@]}" "mkdir -p '$SITE_DST' /var/www/certbot /tmp/spark-nginx-host /tmp/spark-geo-guard"
rsync -az --delete -e "ssh -i $KEY -o BatchMode=yes -o StrictHostKeyChecking=accept-new" \
"$SITE_SRC/" "$HOST:$SITE_DST/"
"${SCP[@]}" "$ROOT/deploy/nginx/host/sparkmessenger.conf" "$HOST:/tmp/spark-nginx-host/sparkmessenger.conf"
"${SCP[@]}" \
"$ROOT/deploy/geo-guard/wyrs_geo_guard.py" \
"$ROOT/deploy/geo-guard/wyrs-geo-guard.service" \
"$ROOT/deploy/geo-guard/install-host.sh" \
"$ROOT/deploy/nginx/snippets/wyrs-cn-geo-access.conf" \
"$ROOT/deploy/nginx/static/cn-mainland-denied.html" \
"$HOST:/tmp/spark-geo-guard/"
"${SSH[@]}" bash -s <<'GEO'
set -euo pipefail
mkdir -p /opt/wyrs-geo-guard /etc/nginx/snippets /var/www/wyrs-geo-deny
# install-host.sh expects repo-relative paths; invoke pieces here
if ! rpm -q python3-geoip2 >/dev/null 2>&1; then
dnf install -y python3-geoip2
fi
install -m 0755 /tmp/spark-geo-guard/wyrs_geo_guard.py /opt/wyrs-geo-guard/wyrs_geo_guard.py
install -m 0644 /tmp/spark-geo-guard/wyrs-geo-guard.service /etc/systemd/system/wyrs-geo-guard.service
install -m 0644 /tmp/spark-geo-guard/wyrs-cn-geo-access.conf /etc/nginx/snippets/wyrs-cn-geo-access.conf
install -m 0644 /tmp/spark-geo-guard/cn-mainland-denied.html /var/www/wyrs-geo-deny/index.html
systemctl daemon-reload
systemctl enable --now wyrs-geo-guard.service
systemctl restart wyrs-geo-guard.service
curl -fsS http://127.0.0.1:18099/healthz >/dev/null
GEO
echo "==> ensure TLS certificates"
"${SSH[@]}" bash -s -- "$PRIMARY" "${DOMAINS[@]}" <<'REMOTE'
set -euo pipefail
PRIMARY=$1
shift
DOMAINS=("$@")
cert_ok() {
[[ -f "/etc/letsencrypt/live/$1/fullchain.pem" ]]
}
need_issue=0
if ! cert_ok "$PRIMARY"; then
need_issue=1
else
# Ensure SAN covers all website domains; re-issue if missing.
for d in "${DOMAINS[@]}"; do
if ! openssl x509 -in "/etc/letsencrypt/live/$PRIMARY/fullchain.pem" -noout -text 2>/dev/null | grep -q "$d"; then
need_issue=1
break
fi
done
fi
if [[ "$need_issue" -eq 1 ]]; then
mkdir -p /var/www/certbot
cat > /etc/nginx/conf.d/sparkmessenger-acme.conf <<EOF
server {
listen 80;
listen [::]:80;
server_name ${DOMAINS[*]};
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 404;
}
}
EOF
nginx -t
systemctl reload nginx
certbot_args=(certonly --webroot -w /var/www/certbot --non-interactive --agree-tos --keep-until-expiring --cert-name "$PRIMARY")
# Use a placeholder email if register is needed; prefer existing account.
if [[ -n "${CERTBOT_EMAIL:-}" ]]; then
certbot_args+=(--email "$CERTBOT_EMAIL")
else
certbot_args+=(--register-unsafely-without-email)
fi
for d in "${DOMAINS[@]}"; do
certbot_args+=(-d "$d")
done
certbot "${certbot_args[@]}"
rm -f /etc/nginx/conf.d/sparkmessenger-acme.conf
fi
if ! cert_ok "$PRIMARY"; then
echo "certificate missing for $PRIMARY" >&2
exit 1
fi
cp /tmp/spark-nginx-host/sparkmessenger.conf /etc/nginx/conf.d/sparkmessenger.conf
nginx -t
systemctl reload nginx
echo "website nginx ready"
REMOTE
echo "==> verify"
for d in "${DOMAINS[@]}"; do
code=$("${SSH[@]}" "curl -fsS -o /dev/null -w '%{http_code}' --resolve ${d}:443:127.0.0.1 https://${d}/" || true)
echo "$d -> HTTP $code"
done
echo "done"