Initial commit

This commit is contained in:
KS Jannette
2026-07-28 02:45:22 -04:00
commit ef664ee8fb
3 changed files with 581 additions and 0 deletions

110
nginx-config.txt Normal file
View File

@@ -0,0 +1,110 @@
root@ip-172-31-3-64:/etc/nginx/sites-available# pwd
/etc/nginx/sites-available
root@ip-172-31-3-64:/etc/nginx/sites-available# cat sjdev.co
# NGINX Configuration for sjdev.co
# HTTP only - SSL will be added once certbot is resolved
server {
server_name sjdev.co www.sjdev.co;
# Allow Let's Encrypt verification
location /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
# Root directory for demo apps
set $apps_root /var/www/sjdev-demo-apps;
# ============================================
# DEMO APPS - Static React Builds
# ============================================
location /demos/salesflow {
alias /var/salesflow/build/;
try_files $uri $uri/ /demos/salesflow/index.html;
}
location /demos/bookbrowser {
alias /var/reactnd-project-bookbrowser/build/;
try_files $uri $uri/ /demos/bookbrowser/index.html;
}
location /demos/budgetize {
alias /var/www/sjdev-demo-apps/budgetize;
try_files $uri $uri/ /demos/budgetize/index.html;
}
# ============================================
# BACKEND API PROXY
# ============================================
location /v1/ {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 300;
proxy_connect_timeout 300;
}
# ============================================
# NEXT.JS APPLICATION
# ============================================
location /_next/static {
proxy_pass http://localhost:3000;
proxy_cache_valid 200 60m;
add_header Cache-Control "public, max-age=3600, immutable";
}
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 300;
proxy_connect_timeout 300;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/sjdev.co/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/sjdev.co/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.sjdev.co) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = sjdev.co) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name sjdev.co www.sjdev.co;
return 404; # managed by Certbot
}

View File

@@ -0,0 +1,36 @@
PROMPT INSTRUCTIONS FOR SETTING UP SJDEV.CO
You will set up my personal consultancy/portfolio site: https://www.sjdev.co on an AWS EC2 sentence server. The server is already running Ubuntu 24.04.3 LTS at the associated Elastic IP address: 18.119.237.252.
Read this document in its entirety before beginning to take any actions.
To the extent that you can execute all the steps described in this document without asking for approval or permission from me, do so. To the extent that you can ask only once for global/blanket permission (if needed) as opposed to making ad-hoc requests, proceed in that fashion.
Do the following:
1. SSH into the server with command:
ssh -i /Users/kjannette/.ssh/sjdev_forever.pem ubuntu@18.119.237.252
1. Run sudo apt update
2. Install: nodejs, node version manager, npm, NGINX, fail2ban
3. Run sudo apt install cmake (this will be needed because a dependency of the sjdev.co backend is FAISS)
4. Execute command sudo su root (so you can clone into the /var directory)
5. Configure NGINX sites-available/sjdev.co according to the separately-attached configuration specification.
6. Symlink the /etc/nginx/sites-avalable/sjdev.co file to sites-enabled/sjdev.co
7. Install certbot. Obtain SSL for https
8. Create and configure fail2ban file: etc/fail2ban/jail.local with standard config settings
9. The git PAT token is: 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. Configure it as a permanent env variable on the server.
10. cd /var
4. git clone https://github.com/kjannette/sjdevnext15Backend.git
5. git clone https://github.com/kjannette/sjdevnext15.git
6. cd sjdevnext15. Run: npm i
7. cd /var/sjdevnext15Backend. Run: npm i
8. Install any other dependencies and/or aproprately respond to any system messages regarding the installations
9. Install PM2. Configure pm2 to run the from and backends (consult the respective package.json) files in each repository for scripts. Save the Pm2 start configuration and also configure it to relaunch either the front or backend end int he event of a crash or a system reboot, etc
10. Disable password authentication for SSH
11. Check the browser to ensure that https://www.sjdev.co is running, reachable and is configured for https.
12. Report on the results

435
setup-sjdev.sh Normal file
View File

@@ -0,0 +1,435 @@
#!/bin/bash
# =============================================================================
# SJDEV.CO SERVER SETUP SCRIPT
# =============================================================================
# Target: Ubuntu 24.04.3 LTS on AWS EC2 (18.119.237.252)
#
# USAGE:
# 1. SSH into your server:
# ssh -i /Users/kjannette/.ssh/sjdev_forever.pem ubuntu@18.119.237.252
# 2. Upload this script:
# scp -i /Users/kjannette/.ssh/sjdev_forever.pem setup-sjdev.sh ubuntu@18.119.237.252:~/
# 3. Run it:
# chmod +x ~/setup-sjdev.sh && sudo ~/setup-sjdev.sh
#
# The script will pause at key checkpoints and print status updates.
# =============================================================================
set -e # Exit on error
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
log_step() {
echo -e "\n${GREEN}[STEP]${NC} $1"
echo "================================================================"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_ok() {
echo -e "${GREEN}[OK]${NC} $1"
}
# =============================================================================
# STEP 1: System Update
# =============================================================================
log_step "1/15 - Updating system packages"
apt update && apt upgrade -y
log_ok "System updated"
# =============================================================================
# STEP 2: Install core packages (NGINX, fail2ban, cmake, build tools)
# =============================================================================
log_step "2/15 - Installing core packages"
apt install -y nginx fail2ban cmake build-essential git curl wget software-properties-common
# Enable and start nginx
systemctl enable nginx
systemctl start nginx
log_ok "Core packages installed"
# =============================================================================
# STEP 3: Install Node.js via NVM (for ubuntu user)
# =============================================================================
log_step "3/15 - Installing NVM and Node.js"
# Install NVM for the ubuntu user
export NVM_DIR="/home/ubuntu/.nvm"
if [ ! -d "$NVM_DIR" ]; then
sudo -u ubuntu bash -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash'
fi
# Source NVM and install Node LTS
export NVM_DIR="/home/ubuntu/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# If running as root, also install node globally accessible
if ! command -v node &> /dev/null; then
# Install via NodeSource as fallback for root access
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt install -y nodejs
fi
# Verify
node --version && log_ok "Node.js installed: $(node --version)"
npm --version && log_ok "npm installed: $(npm --version)"
# =============================================================================
# STEP 4: Install cmake (already done in step 2, verify)
# =============================================================================
log_step "4/15 - Verifying cmake (needed for FAISS)"
cmake --version && log_ok "cmake installed: $(cmake --version | head -1)"
# =============================================================================
# STEP 5: Configure GitHub PAT as environment variable
# =============================================================================
log_step "5/15 - Configuring GitHub PAT environment variable"
# Add to /etc/environment for system-wide persistence
if ! grep -q "GH_PAT" /etc/environment 2>/dev/null; then
echo 'GH_PAT=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' >> /etc/environment
log_ok "GitHub PAT added to /etc/environment"
else
log_warn "GH_PAT already exists in /etc/environment"
fi
# Also add to ubuntu user's bashrc
if ! grep -q "GH_PAT" /home/ubuntu/.bashrc 2>/dev/null; then
echo 'export GH_PAT=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' >> /home/ubuntu/.bashrc
log_ok "GitHub PAT added to ubuntu user's .bashrc"
fi
# Export for current session
export GH_PAT=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
# =============================================================================
# STEP 6: Clone repositories into /var
# =============================================================================
log_step "6/15 - Cloning repositories into /var"
cd /var
if [ ! -d "/var/sjdevnext15Backend" ]; then
git clone https://kjannette:${GH_PAT}@github.com/kjannette/sjdevnext15Backend.git
log_ok "Backend repo cloned"
else
log_warn "Backend repo already exists, pulling latest"
cd /var/sjdevnext15Backend && git pull
fi
cd /var
if [ ! -d "/var/sjdevnext15" ]; then
git clone https://kjannette:${GH_PAT}@github.com/kjannette/sjdevnext15.git
log_ok "Frontend repo cloned"
else
log_warn "Frontend repo already exists, pulling latest"
cd /var/sjdevnext15 && git pull
fi
# =============================================================================
# STEP 7: Install frontend dependencies
# =============================================================================
log_step "7/15 - Installing frontend dependencies (sjdevnext15)"
cd /var/sjdevnext15
npm install
log_ok "Frontend dependencies installed"
# =============================================================================
# STEP 8: Install backend dependencies
# =============================================================================
log_step "8/15 - Installing backend dependencies (sjdevnext15Backend)"
cd /var/sjdevnext15Backend
npm install
log_ok "Backend dependencies installed"
# =============================================================================
# STEP 9: Configure NGINX
# =============================================================================
log_step "9/15 - Configuring NGINX for sjdev.co"
# Remove default site if it exists
rm -f /etc/nginx/sites-enabled/default
# Write the NGINX config (HTTP-only first; certbot will add SSL)
cat > /etc/nginx/sites-available/sjdev.co << 'NGINX_EOF'
# NGINX Configuration for sjdev.co
# HTTP only initially - certbot will add SSL
server {
listen 80;
listen [::]:80;
server_name sjdev.co www.sjdev.co;
# Allow Let's Encrypt verification
location /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
# Root directory for demo apps
set $apps_root /var/www/sjdev-demo-apps;
# ============================================
# DEMO APPS - Static React Builds
# ============================================
location /demos/salesflow {
alias /var/salesflow/build/;
try_files $uri $uri/ /demos/salesflow/index.html;
}
location /demos/bookbrowser {
alias /var/reactnd-project-bookbrowser/build/;
try_files $uri $uri/ /demos/bookbrowser/index.html;
}
location /demos/budgetize {
alias /var/www/sjdev-demo-apps/budgetize;
try_files $uri $uri/ /demos/budgetize/index.html;
}
# ============================================
# BACKEND API PROXY
# ============================================
location /v1/ {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 300;
proxy_connect_timeout 300;
}
# ============================================
# NEXT.JS APPLICATION
# ============================================
location /_next/static {
proxy_pass http://localhost:3000;
proxy_cache_valid 200 60m;
add_header Cache-Control "public, max-age=3600, immutable";
}
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 300;
proxy_connect_timeout 300;
}
}
NGINX_EOF
# Create symlink to sites-enabled
ln -sf /etc/nginx/sites-available/sjdev.co /etc/nginx/sites-enabled/sjdev.co
# Test NGINX config
nginx -t && log_ok "NGINX configuration valid"
# Reload NGINX
systemctl reload nginx
log_ok "NGINX configured and reloaded"
# =============================================================================
# STEP 10: Install Certbot and obtain SSL
# =============================================================================
log_step "10/15 - Installing Certbot and obtaining SSL certificate"
# Install certbot
apt install -y certbot python3-certbot-nginx
# Obtain SSL certificate (will modify NGINX config automatically)
certbot --nginx -d sjdev.co -d www.sjdev.co --non-interactive --agree-tos --email admin@sjdev.co --redirect
log_ok "SSL certificate obtained and NGINX updated"
# =============================================================================
# STEP 11: Configure fail2ban
# =============================================================================
log_step "11/15 - Configuring fail2ban"
cat > /etc/fail2ban/jail.local << 'F2B_EOF'
[DEFAULT]
# Ban hosts for 1 hour
bantime = 3600
# Find failures within 10 minutes
findtime = 600
# Allow 5 retries before ban
maxretry = 5
# Use systemd backend
backend = systemd
# Action: ban via iptables and send no email
action = %(action_)s
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 7200
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5
[nginx-limit-req]
enabled = true
port = http,https
filter = nginx-limit-req
logpath = /var/log/nginx/error.log
maxretry = 10
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 2
F2B_EOF
systemctl enable fail2ban
systemctl restart fail2ban
log_ok "fail2ban configured and running"
# =============================================================================
# STEP 12: Install PM2 and configure processes
# =============================================================================
log_step "12/15 - Installing and configuring PM2"
npm install -g pm2
# Read package.json files to determine start scripts
# Frontend (Next.js) typically uses 'npm start' or 'next start' on port 3000
# Backend typically uses 'npm start' or 'node server.js' on port 3001
# Start the backend
cd /var/sjdevnext15Backend
echo "Starting backend..."
pm2 start npm --name "sjdev-backend" -- start
log_ok "Backend started with PM2"
# Build the frontend first (Next.js needs a build step)
cd /var/sjdevnext15
echo "Building frontend (this may take a few minutes)..."
npm run build 2>&1 || log_warn "Frontend build had warnings - check output above"
# Start the frontend
pm2 start npm --name "sjdev-frontend" -- start
log_ok "Frontend started with PM2"
# Save PM2 process list so it restores after reboot
pm2 save
log_ok "PM2 process list saved"
# Configure PM2 startup script (runs on system boot)
pm2 startup systemd -u ubuntu --hp /home/ubuntu
# The above command outputs a command to run - we execute it automatically
env PATH=$PATH:/usr/bin pm2 startup systemd -u ubuntu --hp /home/ubuntu
log_ok "PM2 startup configured for system reboot"
# =============================================================================
# STEP 13: Disable password authentication for SSH
# =============================================================================
log_step "13/15 - Disabling SSH password authentication"
# Backup sshd_config
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
# Disable password authentication
sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/^#*ChallengeResponseAuthentication.*/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config
sed -i 's/^#*KbdInteractiveAuthentication.*/KbdInteractiveAuthentication no/' /etc/ssh/sshd_config
# Also check sshd_config.d/ directory for overrides
if [ -d /etc/ssh/sshd_config.d ]; then
for f in /etc/ssh/sshd_config.d/*.conf; do
if [ -f "$f" ]; then
sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' "$f"
fi
done
fi
# Validate and restart SSH
sshd -t && systemctl restart sshd
log_ok "SSH password authentication disabled"
# =============================================================================
# STEP 14: Verify everything is running
# =============================================================================
log_step "14/15 - Verification checks"
echo ""
echo "--- NGINX Status ---"
systemctl is-active nginx && log_ok "NGINX is running" || log_error "NGINX is NOT running"
echo ""
echo "--- fail2ban Status ---"
systemctl is-active fail2ban && log_ok "fail2ban is running" || log_error "fail2ban is NOT running"
echo ""
echo "--- PM2 Process List ---"
pm2 list
echo ""
echo "--- SSL Certificate Status ---"
certbot certificates 2>/dev/null || log_warn "Could not check certbot certificates"
echo ""
echo "--- Testing local connectivity ---"
curl -s -o /dev/null -w "Frontend (port 3000): HTTP %{http_code}\n" http://localhost:3000 || log_warn "Frontend not responding on port 3000"
curl -s -o /dev/null -w "Backend (port 3001): HTTP %{http_code}\n" http://localhost:3001 || log_warn "Backend not responding on port 3001"
echo ""
echo "--- Testing external HTTPS ---"
curl -s -o /dev/null -w "https://www.sjdev.co: HTTP %{http_code}\n" https://www.sjdev.co || log_warn "HTTPS site not responding externally"
# =============================================================================
# STEP 15: Final Report
# =============================================================================
log_step "15/15 - SETUP COMPLETE"
echo ""
echo "=============================================="
echo " SJDEV.CO SERVER SETUP - FINAL REPORT"
echo "=============================================="
echo ""
echo " Server: 18.119.237.252 (Ubuntu 24.04)"
echo " Domain: https://www.sjdev.co"
echo " Frontend: Next.js on port 3000 (PM2: sjdev-frontend)"
echo " Backend: Express on port 3001 (PM2: sjdev-backend)"
echo " SSL: Let's Encrypt via Certbot"
echo " Firewall: fail2ban enabled (SSH, NGINX)"
echo " SSH: Key-only authentication"
echo " PM2: Auto-restart on crash + system reboot"
echo ""
echo " IMPORTANT REMINDERS:"
echo " 1. REVOKE your GitHub PAT and generate a new one"
echo " (it was exposed in the setup conversation)"
echo " 2. Check PM2 logs: pm2 logs"
echo " 3. Monitor: pm2 monit"
echo " 4. Check fail2ban: sudo fail2ban-client status"
echo ""
echo "=============================================="