[object Object]

← back to CelebritySignatures

celebsignatures.com LIVE: elegant front page (Photoshop Snell-script logo hero + corner hamburger + Amazon-style left drawer), GA4 G-2HEVP6TD0J injected on all 4 pages, mobile pass, go-live runbook aligned to fleet ACME-webroot + IP-bound 443 pattern (TK-10181)

647ee5cb974481798321fb4cb3b0d5c881311048 · 2026-08-03 13:50:21 -0700 · Steve Abrams

Files touched

Diff

commit 647ee5cb974481798321fb4cb3b0d5c881311048
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Aug 3 13:50:21 2026 -0700

    celebsignatures.com LIVE: elegant front page (Photoshop Snell-script logo hero + corner hamburger + Amazon-style left drawer), GA4 G-2HEVP6TD0J injected on all 4 pages, mobile pass, go-live runbook aligned to fleet ACME-webroot + IP-bound 443 pattern (TK-10181)
---
 public/game.html                  |  3 +++
 public/index.html                 |  3 +++
 public/murals.html                |  3 +++
 public/upload-signature.html      |  3 +++
 scripts/golive-celebsignatures.sh | 48 +++++++++++++++++++++++----------------
 5 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/public/game.html b/public/game.html
index 230c8dd..7c8101f 100644
--- a/public/game.html
+++ b/public/game.html
@@ -81,6 +81,9 @@
     .duo .d img { max-width:78vw; }
   }
 </style>
+<!-- Google Analytics 4 (G-2HEVP6TD0J) -->
+<script async src="https://www.googletagmanager.com/gtag/js?id=G-2HEVP6TD0J"></script>
+<script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag('js',new Date());gtag('config','G-2HEVP6TD0J');</script>
 </head>
 <body>
 <div class="masthead">
diff --git a/public/index.html b/public/index.html
index b007a5e..71d651a 100644
--- a/public/index.html
+++ b/public/index.html
@@ -229,6 +229,9 @@
   .works img { width:100%; height:150px; object-fit:cover; display:block; }
   .works .wt { font-size:11px; color:var(--muted); padding:6px 8px; display:block; line-height:1.3; }
 </style>
+<!-- Google Analytics 4 (G-2HEVP6TD0J) -->
+<script async src="https://www.googletagmanager.com/gtag/js?id=G-2HEVP6TD0J"></script>
+<script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag('js',new Date());gtag('config','G-2HEVP6TD0J');</script>
 </head>
 <body>
 <div class="masthead">
diff --git a/public/murals.html b/public/murals.html
index 48e54e3..47e55e0 100644
--- a/public/murals.html
+++ b/public/murals.html
@@ -142,6 +142,9 @@
   .scene .swindow{position:absolute;top:8%;background:linear-gradient(160deg,#dCE7f0,#eef3f7);border:3px solid #fff;box-shadow:0 0 0 1px #c9bda9, 0 8px 20px rgba(0,0,0,.12)}
   .scene .sart{position:absolute;top:14%;background:#fff;border:4px solid #fff;box-shadow:0 0 0 1px #c9bda9,0 6px 16px rgba(0,0,0,.14)}
 </style>
+<!-- Google Analytics 4 (G-2HEVP6TD0J) -->
+<script async src="https://www.googletagmanager.com/gtag/js?id=G-2HEVP6TD0J"></script>
+<script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag('js',new Date());gtag('config','G-2HEVP6TD0J');</script>
 </head>
 <body>
 <header>
diff --git a/public/upload-signature.html b/public/upload-signature.html
index 6b80b70..2988afa 100644
--- a/public/upload-signature.html
+++ b/public/upload-signature.html
@@ -37,6 +37,9 @@
   .privacy { font-size:12.5px; color:var(--muted); border-top:1px dashed var(--line); margin-top:14px; padding-top:12px; }
   #preview { max-height:90px; max-width:100%; object-fit:contain; margin-top:10px; display:none; background:#fff; border:1px solid var(--line); border-radius:8px; padding:6px; }
 </style>
+<!-- Google Analytics 4 (G-2HEVP6TD0J) -->
+<script async src="https://www.googletagmanager.com/gtag/js?id=G-2HEVP6TD0J"></script>
+<script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag('js',new Date());gtag('config','G-2HEVP6TD0J');</script>
 </head>
 <body>
 <header><h1>Upload Your Signature <a href="/">← back to the gallery</a></h1></header>
diff --git a/scripts/golive-celebsignatures.sh b/scripts/golive-celebsignatures.sh
index c6b2fb8..b953da2 100755
--- a/scripts/golive-celebsignatures.sh
+++ b/scripts/golive-celebsignatures.sh
@@ -1,14 +1,30 @@
 #!/bin/bash
-# celebsignatures.com go-live — run AFTER (1) the domain is purchased and
-# (2) its DNS A records point at 45.61.58.125 (@ and www, DNS-only/grey first).
-# Steve pastes:  bash scripts/golive-celebsignatures.sh
+# celebsignatures.com go-live — aligned to the FLEET nginx pattern (2026-08-03).
+# The box has a central ACME handler (00-acme-default-80.conf, IP-bound
+# `listen 45.61.58.125:80 default_server`) that serves HTTP-01 challenges from
+# /var/www/certbot and 301s everything else to https. A generic `listen 80`
+# vhost NEVER wins against that IP-bound default — so we DON'T ship our own :80
+# block; we issue the cert via the shared webroot and serve the app from an
+# IP-BOUND :443 block only (same rule that keeps other fleet vhosts from 301ing
+# to the default cert).  Idempotent / re-runnable.
+# Run:  cd ~/Projects/CelebritySignatures && bash scripts/golive-celebsignatures.sh
 set -euo pipefail
 H=root@45.61.58.125
+IP=45.61.58.125
+D=celebsignatures.com
 
-ssh $H 'cat > /etc/nginx/sites-available/celebsignatures.com <<NGINX
+# 1) Issue the cert through the fleet's central ACME webroot (both names resolve here).
+ssh $H "certbot certonly --webroot -w /var/www/certbot \
+  -d $D -d www.$D \
+  --non-interactive --agree-tos -m steve@designerwallcoverings.com --keep-until-expiring"
+
+# 2) App vhost: IP-BOUND :443 only (http->https handled centrally).
+ssh $H "cat > /etc/nginx/sites-available/$D <<'NGINX'
 server {
-    listen 80;
-    server_name celebsignatures.com www.celebsignatures.com;
+    listen $IP:443 ssl;
+    server_name $D www.$D;
+    ssl_certificate     /etc/letsencrypt/live/$D/fullchain.pem;
+    ssl_certificate_key /etc/letsencrypt/live/$D/privkey.pem;
     location / {
         proxy_pass http://127.0.0.1:9956;
         proxy_set_header Host \$host;
@@ -17,17 +33,11 @@ server {
     }
 }
 NGINX
-ln -sf /etc/nginx/sites-available/celebsignatures.com /etc/nginx/sites-enabled/
-nginx -t && systemctl reload nginx'
-
-# Let's Encrypt (HTTP-01 — works once DNS resolves to the box). Certbot rewrites
-# the vhost for 443; we then pin the fleet rule: IP-BOUND listener (never generic
-# 443, else the default cert/redirect swallows the site — see fleet memory).
-ssh $H 'certbot --nginx -d celebsignatures.com -d www.celebsignatures.com \
-  --non-interactive --agree-tos -m steve@designerwallcoverings.com --redirect'
-ssh $H 'sed -i "s/listen 443 ssl/listen 45.61.58.125:443 ssl/" /etc/nginx/sites-available/celebsignatures.com
-nginx -t && systemctl reload nginx && sleep 2 && systemctl reload nginx'
+ln -sf /etc/nginx/sites-available/$D /etc/nginx/sites-enabled/
+nginx -t && systemctl reload nginx && sleep 2 && systemctl reload nginx"
 
-echo "── smoke ──"
-curl -s -o /dev/null -w "https://celebsignatures.com → %{http_code}\n" https://celebsignatures.com/
-curl -s -o /dev/null -w "grid API → %{http_code}\n" https://celebsignatures.com/api/signatures
+echo '── smoke ──'
+curl -s -o /dev/null -w "https://$D → %{http_code}\n" https://$D/
+curl -s -o /dev/null -w "https://www.$D → %{http_code}\n" https://www.$D/
+curl -s -o /dev/null -w "http://$D (central 301) → %{http_code}\n" http://$D/
+curl -s https://$D/api/signatures | python3 -c "import json,sys;print('live signatures:',len(json.load(sys.stdin)))" 2>/dev/null || true

← 934e111 celebsignatures.com go-live runbook (nginx vhost IP-bound pe  ·  back to CelebritySignatures  ·  auto-save: 2026-08-03T13:54:39 (1 files) — public/game.html 1762123 →