← back to All Designerwallcoverings
staged one-shot go-live script (rsync + pm2 + nginx public-IP bind + CF DNS + certbot)
9e20e28ad885c281ccabbcd4f240d128ab97f648 · 2026-07-02 12:13:01 -0700 · Steve Abrams
Files touched
Diff
commit 9e20e28ad885c281ccabbcd4f240d128ab97f648
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Jul 2 12:13:01 2026 -0700
staged one-shot go-live script (rsync + pm2 + nginx public-IP bind + CF DNS + certbot)
---
scripts/deploy-live.sh | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/scripts/deploy-live.sh b/scripts/deploy-live.sh
new file mode 100755
index 0000000..30db743
--- /dev/null
+++ b/scripts/deploy-live.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# One-shot go-live for all.designerwallcoverings.com — run after Steve approves.
+# Steps: rsync -> pm2 :9958 -> nginx vhost (PUBLIC-IP bind per standing rule)
+# -> Cloudflare A record (DNS-only) -> certbot -> flip CF proxy on.
+set -euo pipefail
+HOST=my-server
+IP=45.61.58.125
+DOMAIN=all.designerwallcoverings.com
+PORT=9958
+DIR=/root/Projects/all-designerwallcoverings
+
+cd "$(dirname "$0")/.."
+
+echo "== 1/5 rsync =="
+rsync -az --exclude node_modules --exclude .git --exclude '.env*' ./ $HOST:$DIR/
+
+echo "== 2/5 pm2 =="
+ssh $HOST "cd $DIR && (pm2 restart all-designerwallcoverings --update-env 2>/dev/null || PORT=$PORT pm2 start server.js --name all-designerwallcoverings) && pm2 save && sleep 1 && curl -sf http://127.0.0.1:$PORT/healthz"
+
+echo "== 3/5 Cloudflare A record (DNS-only for certbot) =="
+export $(grep -E '^CLOUDFLARE_API_TOKEN=' ~/Projects/secrets-manager/.env)
+ZONE=e4b88c70e4c949f4556cc693133c2f42
+curl -s -X POST -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" -H 'Content-Type: application/json' \
+ "https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records" \
+ -d "{\"type\":\"A\",\"name\":\"all\",\"content\":\"$IP\",\"proxied\":false,\"ttl\":120}" | python3 -c "import sys,json; d=json.load(sys.stdin); print('record:', d['success'] or d['errors'])"
+
+echo "== 4/5 nginx + certbot =="
+ssh $HOST "cat > /etc/nginx/sites-available/$DOMAIN <<'NGINX'
+server {
+ listen $IP:80;
+ server_name $DOMAIN;
+ location / { proxy_pass http://127.0.0.1:$PORT; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; }
+}
+NGINX
+ln -sf /etc/nginx/sites-available/$DOMAIN /etc/nginx/sites-enabled/$DOMAIN
+nginx -t && systemctl reload nginx
+# wait for DNS then issue cert
+for i in \$(seq 1 20); do dig +short $DOMAIN @1.1.1.1 | grep -q . && break; sleep 6; done
+certbot --nginx -d $DOMAIN --non-interactive --agree-tos -m steve@designerwallcoverings.com
+# STANDING RULE: rebind certbot's 443 block to the public IP so a specific-IP
+# vhost (e.g. 1800swallpaper) can't shadow it
+sed -i 's/listen 443 ssl/listen $IP:443 ssl/; s/listen \[::\]:443 ssl.*//' /etc/nginx/sites-available/$DOMAIN
+nginx -t && systemctl reload nginx"
+
+echo "== 5/5 flip Cloudflare proxy ON + verify =="
+REC=$(curl -s -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" "https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records?name=$DOMAIN" | python3 -c "import sys,json; print(json.load(sys.stdin)['result'][0]['id'])")
+curl -s -X PATCH -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" -H 'Content-Type: application/json' \
+ "https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records/$REC" -d '{"proxied":true}' >/dev/null
+sleep 5
+curl -sS -o /dev/null -w "LIVE: HTTP %{http_code} in %{time_total}s\n" https://$DOMAIN/
+curl -s https://$DOMAIN/api/vendors | python3 -c "import sys,json; print('vendors live:', len(json.load(sys.stdin)['vendors']))"
← cc3b3f5 initial scaffold: front-facing vendor directory (all dw_unif
·
back to All Designerwallcoverings
·
snapshot before full-catalog rebuild (vendor directory prese 455cb72 →