← back to Designerssalesreps
fix: convert to 301-redirect server + add deploy scaffold
7bb1bb202d20be659d0e4bbcc28b7980a8a9b3f4 · 2026-07-27 14:39:39 -0700 · Steve Abrams
designerssalesreps.com (plural/typo variant) now permanently 301-redirects
all traffic to designersalesreps.com. Adds ecosystem.config.js (port 9916),
deploy-kamatera.sh, nginx vhost (also handles 301 at nginx layer), .deploy.conf.
Deploy gated pending Steve NS-swap approval.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Files touched
A .deploy.confA deploy-kamatera.shA docs/nginx-vhost-designerssalesreps.com.confA ecosystem.config.jsM server.js
Diff
commit 7bb1bb202d20be659d0e4bbcc28b7980a8a9b3f4
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon Jul 27 14:39:39 2026 -0700
fix: convert to 301-redirect server + add deploy scaffold
designerssalesreps.com (plural/typo variant) now permanently 301-redirects
all traffic to designersalesreps.com. Adds ecosystem.config.js (port 9916),
deploy-kamatera.sh, nginx vhost (also handles 301 at nginx layer), .deploy.conf.
Deploy gated pending Steve NS-swap approval.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---
.deploy.conf | 4 +++
deploy-kamatera.sh | 36 +++++++++++++++++++++
docs/nginx-vhost-designerssalesreps.com.conf | 29 +++++++++++++++++
ecosystem.config.js | 24 ++++++++++++++
server.js | 47 ++++++----------------------
5 files changed, 102 insertions(+), 38 deletions(-)
diff --git a/.deploy.conf b/.deploy.conf
new file mode 100644
index 0000000..86b2771
--- /dev/null
+++ b/.deploy.conf
@@ -0,0 +1,4 @@
+PROJECT_NAME=designerssalesreps-redirect
+DEPLOY_PATH=/root/Projects/designerssalesreps
+HEALTH_URL=https://designerssalesreps.com/health
+PORT=9916
diff --git a/deploy-kamatera.sh b/deploy-kamatera.sh
new file mode 100644
index 0000000..7b5dbf6
--- /dev/null
+++ b/deploy-kamatera.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+# deploy-kamatera.sh — designerssalesreps.com (301 redirect) → Kamatera 45.61.58.125
+# This is the typo/plural variant — it redirects everything to designersalesreps.com.
+# Usage: bash deploy-kamatera.sh
+set -euo pipefail
+
+REMOTE=root@45.61.58.125
+LOCAL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+REMOTE_DIR=/root/Projects/designerssalesreps
+HEALTH_URL=http://127.0.0.1:9916/health
+
+echo "==> Syncing to $REMOTE:$REMOTE_DIR"
+rsync -az --delete \
+ --exclude='node_modules/' \
+ --exclude='.git/' \
+ --exclude='.env*' \
+ --exclude='*.log' \
+ --exclude='logs/' \
+ "$LOCAL_DIR/" "$REMOTE:$REMOTE_DIR/"
+
+echo "==> npm install on remote"
+ssh "$REMOTE" "cd $REMOTE_DIR && npm install --omit=dev --silent"
+
+echo "==> mkdir logs"
+ssh "$REMOTE" "mkdir -p $REMOTE_DIR/logs"
+
+echo "==> pm2 startOrReload"
+ssh "$REMOTE" "cd $REMOTE_DIR && pm2 startOrReload ecosystem.config.js --update-env && pm2 save"
+
+echo "==> Health check (origin direct)"
+ssh "$REMOTE" "curl -sf $HEALTH_URL" && echo "PASS: origin direct" || { echo "FAIL: health check"; exit 1; }
+
+echo "==> Verifying 301 redirect from CF-proxied variant"
+curl -sI https://designerssalesreps.com/ 2>/dev/null | grep -i "location:\|301" || echo "WARN: CF not yet routed (DNS pending?)"
+
+echo "==> Done. designerssalesreps.com 301-redirect is live on :9916"
diff --git a/docs/nginx-vhost-designerssalesreps.com.conf b/docs/nginx-vhost-designerssalesreps.com.conf
new file mode 100644
index 0000000..fa025bb
--- /dev/null
+++ b/docs/nginx-vhost-designerssalesreps.com.conf
@@ -0,0 +1,29 @@
+# nginx vhost — designerssalesreps.com (301 redirect to primary)
+# Copy to: /etc/nginx/sites-available/designerssalesreps.com
+# Enable: ln -s /etc/nginx/sites-available/designerssalesreps.com /etc/nginx/sites-enabled/
+# Reload: nginx -t && systemctl reload nginx
+
+server {
+ listen 80;
+ server_name designerssalesreps.com www.designerssalesreps.com;
+
+ # Cloudflare real-IP passthrough
+ set_real_ip_from 103.21.244.0/22;
+ set_real_ip_from 104.16.0.0/13;
+ set_real_ip_from 104.24.0.0/14;
+ set_real_ip_from 172.64.0.0/13;
+ set_real_ip_from 173.245.48.0/20;
+ set_real_ip_from 162.158.0.0/15;
+ real_ip_header CF-Connecting-IP;
+
+ # Node handles the 301 on :9916, but nginx-level redirect is belt+suspenders.
+ # The node server.js also returns 301 so either layer catches it.
+ location /health {
+ proxy_pass http://127.0.0.1:9916;
+ proxy_set_header Host $host;
+ }
+
+ location / {
+ return 301 https://designersalesreps.com$request_uri;
+ }
+}
diff --git a/ecosystem.config.js b/ecosystem.config.js
new file mode 100644
index 0000000..1b89475
--- /dev/null
+++ b/ecosystem.config.js
@@ -0,0 +1,24 @@
+module.exports = {
+ apps: [{
+ name: 'designerssalesreps-redirect',
+ script: 'server.js',
+ cwd: '/root/Projects/designerssalesreps',
+ env: {
+ PORT: 9916,
+ NODE_ENV: 'production'
+ },
+ instances: 1,
+ autorestart: true,
+ watch: false,
+ max_memory_restart: '256M',
+ error_file: './logs/err.log',
+ out_file: './logs/out.log',
+ log_file: './logs/combined.log',
+ time: true,
+ max_restarts: Infinity,
+ min_uptime: '5s',
+ restart_delay: 1000,
+ exp_backoff_restart_delay: 100,
+ kill_timeout: 5000
+ }]
+};
diff --git a/server.js b/server.js
index d9d2a3d..177b3fd 100644
--- a/server.js
+++ b/server.js
@@ -1,46 +1,17 @@
'use strict';
+// designerssalesreps.com — permanent 301 redirect to the canonical primary.
+// This is the typo/plural variant; the real site lives at designersalesreps.com.
const express = require('express');
-const fs = require('fs');
-const path = require('path');
const app = express();
const PORT = process.env.PORT || 9916;
-const DOMAIN = 'designerssalesreps.com';
-app.use(express.json());
+app.get('/health', (req, res) => res.json({ ok: true, redirect: 'designersalesreps.com' }));
-// Hard 404 guard: never serve snapshot/backup files even if they
-// land in public/. Mirrors the standing fleet rule.
-app.use((req, res, next) => {
- if (/\.(bak|bak\..+|pre-[^/]+)$/i.test(req.path) || /\.pre-/i.test(req.path)) {
- return res.status(404).send('Not found');
- }
- next();
+app.use((req, res) => {
+ const target = 'https://designersalesreps.com' + req.originalUrl;
+ res.redirect(301, target);
});
-app.use(express.static(path.join(__dirname, 'public')));
-
-const reps = JSON.parse(fs.readFileSync(path.join(__dirname, 'data/reps.json'), 'utf8'));
-
-app.get('/api/search', (req, res) => {
- const { q = '', territory = '', vertical = '', sort = 'name' } = req.query;
- let results = reps.filter(r => {
- const qLow = q.toLowerCase();
- const matchQ = !q || r.name.toLowerCase().includes(qLow) || r.agency.toLowerCase().includes(qLow) || r.lines.some(l => l.toLowerCase().includes(qLow)) || r.city.toLowerCase().includes(qLow);
- const matchT = !territory || r.territories.includes(territory);
- const matchV = !vertical || r.vertical.includes(vertical);
- return matchQ && matchT && matchV;
- });
- if (sort === 'agency') results.sort((a, b) => a.agency.localeCompare(b.agency));
- else if (sort === 'city') results.sort((a, b) => a.city.localeCompare(b.city));
- else results.sort((a, b) => a.name.localeCompare(b.name));
- res.json({ total: results.length, results });
-});
-
-app.post('/api/claim', (req, res) => {
- const entry = { ...req.body, ts: new Date().toISOString(), domain: DOMAIN };
- fs.appendFileSync(path.join(__dirname, 'claims.jsonl'), JSON.stringify(entry) + '\n');
- res.json({ ok: true });
-});
-
-app.get('/health', (req, res) => res.json({ ok: true, domain: DOMAIN }));
-app.listen(PORT, '127.0.0.1', () => console.log(`${DOMAIN} listening on ${PORT}`));
+app.listen(PORT, '127.0.0.1', () =>
+ console.log(`designerssalesreps.com redirect → designersalesreps.com on :${PORT}`)
+);
← 1279c63 server: add 404 guard for .bak/.pre- snapshot paths
·
back to Designerssalesreps
·
auto-save: 2026-07-27T14:51:27 (1 files) — package-lock.json 1e0eb23 →