Initial commit
This commit is contained in:
435
setup-sjdev.sh
Normal file
435
setup-sjdev.sh
Normal 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 "=============================================="
|
||||
Reference in New Issue
Block a user