**Newsletter Modal Implementation**: - Added modal subscription forms to blog pages - Improved UX with dedicated modal instead of anchor links - Location: public/blog.html, public/blog-post.html **Blog JavaScript Enhancements**: - Enhanced blog.js and blog-post.js with modal handling - Newsletter form submission logic - Location: public/js/blog.js, public/js/blog-post.js **Deployment Script Improvements**: - Added pre-deployment checks (server running, version parameters) - Enhanced visual feedback with status indicators (✓/✗/⚠) - Version parameter staleness detection - Location: scripts/deploy-full-project-SAFE.sh **Demo Page Cleanup**: - Minor refinements to demo pages - Location: public/demos/*.html **Routes Enhancement**: - Newsletter route additions - Location: src/routes/index.js 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
34 KiB
Phase 2 Deployment Guide - Granular Task Instructions
Project: Tractatus AI Safety Framework Domain: agenticgovernance.digital VPS: vps-7f023e40.vps.ovh.net (OVHCloud) Created: 2025-10-07 Status: ACTIVE DEPLOYMENT
Table of Contents
- Week 0: Pre-Deployment Preparation
- Week 1: Infrastructure Setup
- Week 2: Application Deployment
- Week 3: Security Hardening
- Week 4: Monitoring & Testing
- Week 5-8: AI Features
- Week 9-12: Soft Launch
- Emergency Procedures
Week 0: Pre-Deployment Preparation
Day 0.1: OVHCloud VPS Assessment
Current VPS: vps-7f023e40.vps.ovh.net
Tasks:
-
Check VPS specifications in OVHCloud control panel:
- CPU cores (need 2+)
- RAM (need 4GB+)
- Disk space (need 80GB+)
- Bandwidth allocation
- Current OS (Ubuntu 22.04 LTS preferred)
-
Verify VPS location:
- Confirm datacenter region (Singapore/Australia preferred)
- Check latency to target users
-
Check current VPS state:
- Is it a fresh install or has existing services?
- Any data to backup before proceeding?
- Current SSH access method (password or key?)
Commands to Run (if you have SSH access):
# Check OS version
cat /etc/os-release
# Check system resources
free -h # RAM
df -h # Disk space
nproc # CPU cores
ip addr show # Network interfaces
systemctl list-units # Running services
Decision Points:
- Fresh install or clean existing VPS?
- Keep existing OS or reinstall Ubuntu 22.04 LTS?
Day 0.2: Generate Secrets
Tasks:
- Generate JWT Secret:
# On your local machine
openssl rand -base64 48
- Copy output (64 characters)
- Store in password manager (1Password, Bitwarden, etc.)
- Label: "Tractatus JWT_SECRET (Production)"
- Generate MongoDB Password:
openssl rand -base64 32
- Copy output (44 characters)
- Store in password manager
- Label: "Tractatus MongoDB tractatus_user password"
- Generate MongoDB Root Password:
openssl rand -base64 32
- Store in password manager
- Label: "Tractatus MongoDB root password"
- Generate SSH Key Pair (for Tractatus deployments):
ssh-keygen -t ed25519 -C "tractatus-deploy@agenticgovernance.digital" -f ~/.ssh/tractatus_deploy
- Private key:
~/.ssh/tractatus_deploy(keep secure) - Public key:
~/.ssh/tractatus_deploy.pub(will add to VPS)
Security Checklist:
- All secrets stored in password manager (never in Git)
- SSH private key has passphrase
- Backup of password manager vault
Day 0.3: DNS Preparation
Tasks:
-
Access OVHCloud DNS Management:
- Navigate to: Domains → agenticgovernance.digital → DNS Zone
- Familiarize with interface
-
Get VPS IP Address from OVHCloud:
- VPS Dashboard → vps-7f023e40.vps.ovh.net → IP Addresses
- Note IPv4 address:
___.___.___.___ - Note IPv6 address (if available):
____:____:____:____
-
Prepare DNS Records (don't configure yet, just prepare):
Type | Name | Value | TTL
------|------|-------------------|-----
A | @ | <VPS_IPv4> | 300 (5 min for testing)
A | www | <VPS_IPv4> | 300
AAAA | @ | <VPS_IPv6> | 300 (if available)
AAAA | www | <VPS_IPv6> | 300 (if available)
Note: We'll configure DNS in Week 1 after server is ready.
Day 0.4: Local Repository Preparation
Tasks:
- Create production branch:
cd /home/theflow/projects/tractatus
git checkout -b production
git push -u origin production
git checkout main
- Create .env.production template:
cat > .env.production << 'EOF'
# Tractatus Production Environment
NODE_ENV=production
PORT=9000
# Application
APP_NAME=Tractatus
APP_DOMAIN=agenticgovernance.digital
APP_URL=https://agenticgovernance.digital
# MongoDB
MONGODB_URI=mongodb://tractatus_user:<PASSWORD>@localhost:27017/tractatus_prod?authSource=tractatus_prod
MONGODB_PORT=27017
MONGODB_DATABASE=tractatus_prod
# JWT
JWT_SECRET=<GENERATE_FROM_DAY_0.2>
JWT_EXPIRY=7d
# Claude API (Week 5+)
CLAUDE_API_KEY=<TO_BE_ADDED>
CLAUDE_MODEL=claude-sonnet-4-5-20250929
# Admin
ADMIN_EMAIL=admin@agenticgovernance.digital
# Security
SESSION_SECRET=<GENERATE_ANOTHER_SECRET>
COOKIE_SECURE=true
COOKIE_SAMESITE=strict
EOF
- Add .env.production to .gitignore:
echo ".env.production" >> .gitignore
git add .gitignore
git commit -m "chore: add .env.production to gitignore"
- Test production build locally:
NODE_ENV=production npm start
# Verify app starts without errors
# Ctrl+C to stop
Week 1: Infrastructure Setup
Day 1.1: Initial VPS Access & User Setup
Tasks:
- Access VPS via SSH (OVHCloud provides root access):
ssh root@vps-7f023e40.vps.ovh.net
# Or use IP: ssh root@<VPS_IP>
- Update system packages:
apt update && apt upgrade -y
- Create non-root user:
adduser tractatus
# Set password (use password manager to generate & store)
# Full name: Tractatus Application
# Leave other fields blank (press Enter)
# Add to sudo group
usermod -aG sudo tractatus
- Set up SSH key authentication for tractatus user:
# Still as root
mkdir -p /home/tractatus/.ssh
chmod 700 /home/tractatus/.ssh
# Copy your SSH public key (from Day 0.2)
# On your LOCAL machine, copy the public key:
cat ~/.ssh/tractatus_deploy.pub
# Back on VPS, paste it:
nano /home/tractatus/.ssh/authorized_keys
# Paste the public key, save (Ctrl+O, Enter, Ctrl+X)
chmod 600 /home/tractatus/.ssh/authorized_keys
chown -R tractatus:tractatus /home/tractatus/.ssh
- Test SSH access as tractatus user:
# From your LOCAL machine (new terminal):
ssh -i ~/.ssh/tractatus_deploy tractatus@vps-7f023e04.vps.ovh.net
# If successful, you should see tractatus@vps-7f023e40:~$
- Configure sudo without password (for deployment automation):
# On VPS, as root:
visudo
# Add this line at the end:
tractatus ALL=(ALL) NOPASSWD:ALL
# Save and exit (Ctrl+O, Enter, Ctrl+X if nano, or :wq if vim)
Day 1.2: Firewall & SSH Hardening
Tasks:
- Install UFW (Uncomplicated Firewall):
# As tractatus user on VPS:
sudo apt install ufw -y
- Configure UFW rules (CRITICAL - don't lock yourself out):
# Allow SSH from your current IP (safer)
# Get your IP: curl ifconfig.me
sudo ufw allow from <YOUR_IP> to any port 22
# Or allow SSH from anywhere (less secure but more flexible):
sudo ufw allow 22/tcp
# Allow HTTP and HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Check rules before enabling
sudo ufw show added
- Enable UFW:
sudo ufw enable
# Type 'y' to confirm
# Verify status
sudo ufw status verbose
- Harden SSH configuration:
sudo nano /etc/ssh/sshd_config
# Find and modify these lines:
PermitRootLogin no # Disable root login
PasswordAuthentication no # Disable password auth
PubkeyAuthentication yes # Enable key-based auth
Port 22 # Keep default (or change to custom)
MaxAuthTries 3 # Limit authentication attempts
ClientAliveInterval 300 # Timeout idle sessions (5 min)
ClientAliveCountMax 2 # Max missed keepalives
# Save and exit
- Restart SSH service:
sudo systemctl restart sshd
# Verify SSH is still working (open NEW terminal, don't close current one):
ssh -i ~/.ssh/tractatus_deploy tractatus@vps-7f023e40.vps.ovh.net
- Install Fail2ban:
sudo apt install fail2ban -y
# Create local configuration
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# Edit configuration
sudo nano /etc/fail2ban/jail.local
# Find [sshd] section and modify:
[sshd]
enabled = true
port = 22
maxretry = 3
bantime = 3600
findtime = 600
# Save and exit
- Start Fail2ban:
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
sudo fail2ban-client status sshd
Day 1.3: Install Node.js & Dependencies
Tasks:
- Install Node.js 18 LTS (via NodeSource):
# Download and run NodeSource setup script
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
# Install Node.js
sudo apt install nodejs -y
# Verify installation
node --version # Should show v18.x.x
npm --version # Should show 9.x.x or 10.x.x
- Install build tools (needed for some npm packages):
sudo apt install build-essential -y
- Install Git:
sudo apt install git -y
git --version
- Install PM2 (process manager for Node.js):
sudo npm install -g pm2
pm2 --version
- Configure PM2 to start on boot:
pm2 startup systemd -u tractatus --hp /home/tractatus
# Copy and run the command PM2 outputs (starts with 'sudo env PATH=...')
Day 1.4: Install & Configure MongoDB
Tasks:
- Import MongoDB GPG key:
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \
sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
- Add MongoDB repository:
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | \
sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
- Install MongoDB:
sudo apt update
sudo apt install mongodb-org -y
- Start MongoDB:
sudo systemctl start mongod
sudo systemctl enable mongod
sudo systemctl status mongod
- Create MongoDB admin user:
mongosh
# In MongoDB shell:
use admin
db.createUser({
user: "admin",
pwd: "<MONGODB_ROOT_PASSWORD_FROM_DAY_0.2>",
roles: ["root"]
})
# Exit MongoDB shell
exit
- Enable MongoDB authentication:
sudo nano /etc/mongod.conf
# Find the security section and modify:
security:
authorization: enabled
# Save and exit
- Restart MongoDB:
sudo systemctl restart mongod
- Create Tractatus database and user:
mongosh -u admin -p --authenticationDatabase admin
# In MongoDB shell (enter admin password when prompted):
use tractatus_prod
db.createUser({
user: "tractatus_user",
pwd: "<MONGODB_PASSWORD_FROM_DAY_0.2>",
roles: [
{ role: "readWrite", db: "tractatus_prod" },
{ role: "dbAdmin", db: "tractatus_prod" }
]
})
# Test authentication
exit
mongosh -u tractatus_user -p --authenticationDatabase tractatus_prod tractatus_prod
# Enter tractatus_user password when prompted
# If successful, you'll see tractatus_prod> prompt
exit
Day 1.5: Install & Configure Nginx
Tasks:
- Install Nginx:
sudo apt install nginx -y
# Verify installation
nginx -v
sudo systemctl status nginx
- Configure Nginx for Tractatus (HTTP only, SSL in Day 1.6):
sudo nano /etc/nginx/sites-available/tractatus
# Paste this configuration:
# Tractatus Production - HTTP Only (SSL will be added)
server {
listen 80;
listen [::]:80;
server_name agenticgovernance.digital www.agenticgovernance.digital;
# Temporary: Redirect to show "Coming Soon"
location / {
return 200 'Tractatus Framework - Deploying...';
add_header Content-Type text/plain;
}
}
- Enable the site:
sudo ln -s /etc/nginx/sites-available/tractatus /etc/nginx/sites-enabled/
# Remove default site
sudo rm /etc/nginx/sites-enabled/default
# Test configuration
sudo nginx -t
# Reload Nginx
sudo systemctl reload nginx
- Test Nginx (from your local machine):
# If DNS is configured:
curl http://agenticgovernance.digital
# Or use VPS IP:
curl http://<VPS_IP>
# Should see: "Tractatus Framework - Deploying..."
Day 1.6: Configure DNS
Tasks:
- Get VPS IP address:
# On VPS:
ip addr show | grep 'inet '
# Note the public IPv4 (not 127.0.0.1)
-
Configure DNS in OVHCloud:
- Navigate to: Domains → agenticgovernance.digital → DNS Zone
- Click "Add an entry"
Add A record:
- Type: A
- Subdomain: (leave empty for @)
- Target: <VPS_IPv4>
- TTL: 300 (5 minutes for testing)
Add A record for www:
- Type: A
- Subdomain: www
- Target: <VPS_IPv4>
- TTL: 300
-
Wait for DNS propagation (5-30 minutes):
# From your LOCAL machine:
dig agenticgovernance.digital +short
# Should return VPS IP
dig www.agenticgovernance.digital +short
# Should return VPS IP
# Or use:
nslookup agenticgovernance.digital
- Test DNS with browser:
- Visit: http://agenticgovernance.digital
- Should see: "Tractatus Framework - Deploying..."
Day 1.7: Install SSL/TLS with Let's Encrypt
Tasks:
- Install Certbot:
sudo apt install certbot python3-certbot-nginx -y
- Obtain SSL certificate:
sudo certbot --nginx -d agenticgovernance.digital -d www.agenticgovernance.digital
# Follow prompts:
# - Email: admin@agenticgovernance.digital
# - Agree to Terms of Service: Yes (Y)
# - Share email with EFF: Your choice (Y/N)
# - Redirect HTTP to HTTPS: Yes (2)
-
Test SSL certificate:
- Visit: https://agenticgovernance.digital
- Should see: "Tractatus Framework - Deploying..." (now HTTPS)
- Check for padlock icon in browser
-
Test auto-renewal:
sudo certbot renew --dry-run
# Should complete without errors
- Verify Nginx configuration:
sudo cat /etc/nginx/sites-available/tractatus
# Should now include SSL configuration added by Certbot
Week 2: Application Deployment
Day 2.1: Clone Repository & Setup
Tasks:
- Create application directory:
# On VPS as tractatus user:
sudo mkdir -p /var/www/tractatus
sudo chown tractatus:tractatus /var/www/tractatus
cd /var/www/tractatus
- Clone repository:
# Option A: HTTPS (simpler, but need GitHub token for private repos)
git clone https://github.com/<YOUR_USERNAME>/tractatus.git .
# Option B: SSH (requires SSH key setup on GitHub)
# First, generate SSH key on VPS:
ssh-keygen -t ed25519 -C "vps@agenticgovernance.digital" -f ~/.ssh/github_tractatus
cat ~/.ssh/github_tractatus.pub
# Add public key to GitHub: Settings → SSH Keys → New SSH Key
git clone git@github.com:<YOUR_USERNAME>/tractatus.git .
- Checkout production branch:
git checkout production
git pull origin production
- Install dependencies:
npm ci --production
# Use 'ci' instead of 'install' for reproducible builds
Day 2.2: Configure Environment
Tasks:
- Create production .env file:
nano /var/www/tractatus/.env
# Paste (with secrets from Day 0.2):
NODE_ENV=production
PORT=9000
APP_NAME=Tractatus
APP_DOMAIN=agenticgovernance.digital
APP_URL=https://agenticgovernance.digital
MONGODB_URI=mongodb://tractatus_user:<MONGODB_PASSWORD>@localhost:27017/tractatus_prod?authSource=tractatus_prod
MONGODB_PORT=27017
MONGODB_DATABASE=tractatus_prod
JWT_SECRET=<JWT_SECRET>
JWT_EXPIRY=7d
ADMIN_EMAIL=admin@agenticgovernance.digital
SESSION_SECRET=<ANOTHER_SECRET>
COOKIE_SECURE=true
COOKIE_SAMESITE=strict
# Save and exit
- Secure .env file:
chmod 600 /var/www/tractatus/.env
chown tractatus:tractatus /var/www/tractatus/.env
- Initialize MongoDB (seed collections):
cd /var/www/tractatus
node scripts/init-db.js
- Create admin user:
node scripts/seed-admin.js
# Note the admin credentials output
Day 2.3: Configure Nginx Reverse Proxy
Tasks:
- Update Nginx configuration:
sudo nano /etc/nginx/sites-available/tractatus
Replace with:
# Tractatus Production - Full Configuration
upstream tractatus_backend {
server 127.0.0.1:9000;
keepalive 64;
}
# Redirect www to non-www
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.agenticgovernance.digital;
ssl_certificate /etc/letsencrypt/live/agenticgovernance.digital/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/agenticgovernance.digital/privkey.pem;
return 301 https://agenticgovernance.digital$request_uri;
}
# Main server block
server {
listen 80;
listen [::]:80;
server_name agenticgovernance.digital;
# Redirect HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name agenticgovernance.digital;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/agenticgovernance.digital/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/agenticgovernance.digital/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Security Headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
# Content Security Policy
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none';" always;
# Root and index
root /var/www/tractatus/public;
index index.html;
# Logging
access_log /var/log/nginx/tractatus-access.log;
error_log /var/log/nginx/tractatus-error.log;
# Static files
location /css {
alias /var/www/tractatus/public/css;
expires 1y;
add_header Cache-Control "public, immutable";
}
location /js {
alias /var/www/tractatus/public/js;
expires 1y;
add_header Cache-Control "public, immutable";
}
location /images {
alias /var/www/tractatus/public/images;
expires 1y;
add_header Cache-Control "public, immutable";
}
# Proxy to Node.js application
location / {
try_files $uri $uri/ @proxy;
}
location @proxy {
proxy_pass http://tractatus_backend;
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 90;
}
# Health check endpoint
location /health {
proxy_pass http://tractatus_backend/health;
access_log off;
}
}
- Test Nginx configuration:
sudo nginx -t
- Reload Nginx:
sudo systemctl reload nginx
Day 2.4: Start Application with PM2
Tasks:
- Create PM2 ecosystem file:
nano /var/www/tractatus/ecosystem.config.js
module.exports = {
apps: [{
name: 'tractatus',
script: './src/server.js',
instances: 2,
exec_mode: 'cluster',
env: {
NODE_ENV: 'production'
},
error_file: '/var/www/tractatus/logs/pm2-error.log',
out_file: '/var/www/tractatus/logs/pm2-out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
max_memory_restart: '500M',
autorestart: true,
watch: false
}]
};
- Create logs directory:
mkdir -p /var/www/tractatus/logs
- Start application:
cd /var/www/tractatus
pm2 start ecosystem.config.js
# Check status
pm2 status
# View logs
pm2 logs tractatus --lines 50
- Save PM2 configuration:
pm2 save
- Test application:
# Local test
curl http://localhost:9000/health
# Public test
curl https://agenticgovernance.digital/health
- Open browser and test:
- Visit: https://agenticgovernance.digital
- Should see Tractatus homepage
- Test navigation (Researcher, Implementer, Advocate paths)
- Test demos (27027 incident, classification, boundary)
Week 3: Security Hardening
Day 3.1: Automated Security Updates
Tasks:
- Install unattended-upgrades:
sudo apt install unattended-upgrades -y
- Configure automatic updates:
sudo dpkg-reconfigure -plow unattended-upgrades
# Select "Yes" to enable
- Verify configuration:
sudo cat /etc/apt/apt.conf.d/20auto-upgrades
# Should show:
# APT::Periodic::Update-Package-Lists "1";
# APT::Periodic::Unattended-Upgrade "1";
Day 3.2: Implement Rate Limiting
Tasks:
- Configure Nginx rate limiting:
sudo nano /etc/nginx/nginx.conf
# In http block, add:
http {
# ... existing config ...
# Rate limiting zones
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=api:10m rate=5r/s;
limit_req_zone $binary_remote_addr zone=auth:10m rate=3r/m;
# ... rest of config ...
}
- Apply rate limits in site config:
sudo nano /etc/nginx/sites-available/tractatus
# Add to server block:
# Rate limiting
location /auth {
limit_req zone=auth burst=5;
proxy_pass http://tractatus_backend;
# ... other proxy settings ...
}
location /api {
limit_req zone=api burst=10 nodelay;
proxy_pass http://tractatus_backend;
# ... other proxy settings ...
}
location / {
limit_req zone=general burst=20 nodelay;
# ... existing config ...
}
- Test and reload:
sudo nginx -t
sudo systemctl reload nginx
Day 3.3: Setup Automated Backups
Tasks:
- Create backup script:
sudo nano /usr/local/bin/tractatus-backup.sh
#!/bin/bash
# Tractatus MongoDB Backup Script
BACKUP_DIR="/var/backups/tractatus"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="tractatus_backup_${DATE}.gz"
RETENTION_DAYS=7
# Create backup directory
mkdir -p $BACKUP_DIR
# Dump MongoDB database
mongodump --uri="mongodb://tractatus_user:<PASSWORD>@localhost:27017/tractatus_prod?authSource=tractatus_prod" \
--gzip --archive="${BACKUP_DIR}/${BACKUP_FILE}"
# Remove old backups
find $BACKUP_DIR -name "tractatus_backup_*.gz" -mtime +${RETENTION_DAYS} -delete
# Log result
echo "[$(date)] Backup completed: ${BACKUP_FILE}" >> /var/log/tractatus-backup.log
- Make script executable:
sudo chmod +x /usr/local/bin/tractatus-backup.sh
- Test backup script:
sudo /usr/local/bin/tractatus-backup.sh
ls -lh /var/backups/tractatus/
- Schedule daily backups with cron:
sudo crontab -e
# Add this line (runs daily at 2 AM):
0 2 * * * /usr/local/bin/tractatus-backup.sh
Day 3.4: Configure Fail2ban for Nginx
Tasks:
- Create Nginx jail:
sudo nano /etc/fail2ban/jail.local
# Add:
[nginx-http-auth]
enabled = true
port = http,https
logpath = /var/log/nginx/tractatus-error.log
[nginx-limit-req]
enabled = true
port = http,https
logpath = /var/log/nginx/tractatus-error.log
findtime = 600
maxretry = 10
- Restart Fail2ban:
sudo systemctl restart fail2ban
sudo fail2ban-client status
Week 4: Monitoring & Testing
Day 4.1: Setup Error Monitoring (Sentry)
Tasks:
-
Create Sentry account at sentry.io (free tier)
-
Create new project:
- Platform: Node.js
- Project name: tractatus-production
-
Get DSN (Data Source Name) from Sentry dashboard
-
Install Sentry SDK:
cd /var/www/tractatus
npm install @sentry/node --save
- Add Sentry DSN to .env:
nano /var/www/tractatus/.env
# Add:
SENTRY_DSN=<YOUR_SENTRY_DSN>
- Initialize Sentry in application:
nano /var/www/tractatus/src/server.js
# Add at the top (after require statements):
const Sentry = require('@sentry/node');
if (process.env.SENTRY_DSN) {
Sentry.init({
dsn: process.env.SENTRY_DSN,
environment: process.env.NODE_ENV,
tracesSampleRate: 0.1, // 10% of transactions
});
}
# Add Sentry error handler middleware (before other error handlers):
app.use(Sentry.Handlers.errorHandler());
- Restart application:
pm2 restart tractatus
- Test error tracking:
- Visit Sentry dashboard
- Trigger a test error on the site
- Verify error appears in Sentry
Day 4.2: Setup Uptime Monitoring
Tasks:
-
Create UptimeRobot account at uptimerobot.com (free tier)
-
Add monitor:
- Monitor Type: HTTPS
- Friendly Name: Tractatus Production
- URL: https://agenticgovernance.digital/health
- Monitoring Interval: 5 minutes
-
Configure alerts:
- Email: admin@agenticgovernance.digital
- Alert when: Down
- Send notification: Immediately
-
Test monitor:
- Stop PM2:
pm2 stop tractatus - Wait for alert (5 minutes)
- Restart:
pm2 start tractatus - Verify "UP" notification
- Stop PM2:
Day 4.3: Performance Testing
Tasks:
-
Test Core Web Vitals:
- Visit: https://pagespeed.web.dev/
- Enter: https://agenticgovernance.digital
- Run test for Mobile and Desktop
- Target scores: >90 for all metrics
-
Run Lighthouse audit (Chrome DevTools):
- Open Chrome DevTools (F12)
- Lighthouse tab
- Run audit (Desktop)
- Check: Performance, Accessibility, Best Practices, SEO
- Target: All >90
-
Load testing with Apache Bench:
# On local machine:
ab -n 1000 -c 10 https://agenticgovernance.digital/
# Should handle 1000 requests with 10 concurrent without errors
- Check response times:
curl -w "@-" -o /dev/null -s https://agenticgovernance.digital/ <<'EOF'
time_namelookup: %{time_namelookup}s\n
time_connect: %{time_connect}s\n
time_appconnect: %{time_appconnect}s\n
time_pretransfer: %{time_pretransfer}s\n
time_redirect: %{time_redirect}s\n
time_starttransfer: %{time_starttransfer}s\n
----------\n
time_total: %{time_total}s\n
EOF
# Target: time_total < 2.5s
Day 4.4: Security Audit
Tasks:
-
Run SSL Labs test:
- Visit: https://www.ssllabs.com/ssltest/
- Enter: agenticgovernance.digital
- Target: A or A+ rating
-
Check security headers:
- Visit: https://securityheaders.com/
- Enter: https://agenticgovernance.digital
- Target: A or A+ rating
-
Scan for vulnerabilities:
# On VPS:
sudo apt install lynis -y
sudo lynis audit system
# Review warnings in: /var/log/lynis-report.dat
- Check npm dependencies:
cd /var/www/tractatus
npm audit
# Fix any high/critical vulnerabilities:
npm audit fix
Week 5-8: AI Features
Week 5: Claude API Integration
Tasks:
-
Create Anthropic account and obtain production API key
-
Add Claude API key to .env:
nano /var/www/tractatus/.env
# Add:
CLAUDE_API_KEY=<YOUR_ANTHROPIC_API_KEY>
CLAUDE_MODEL=claude-sonnet-4-5-20250929
CLAUDE_MAX_TOKENS=4096
- Install Claude SDK:
cd /var/www/tractatus
npm install @anthropic-ai/sdk --save
- Deploy updated code:
git pull origin production
npm install
pm2 restart tractatus
- Test Claude integration:
- Test blog topic suggestion endpoint
- Monitor API usage in Anthropic dashboard
- Verify rate limiting is working
Week 6-7: Implement AI Features
Reference: See PHASE-2-ROADMAP.md for detailed AI feature specifications
Tasks:
-
Blog Curation System:
- Implement topic suggestion API
- Implement outline generation API
- Create human approval workflow
- Test end-to-end
-
Media Inquiry Triage:
- Implement classification API
- Implement draft response generator
- Create moderation queue
- Test all priority levels
-
Case Study Portal:
- Implement submission form
- Implement relevance analysis API
- Create moderation workflow
- Test publication pipeline
Week 9-12: Soft Launch
Week 9: Pre-Launch Testing
Tasks:
- End-to-end testing of all features
- Governance compliance audit (verify TRA-OPS-* policies)
- User acceptance testing (internal)
- Performance optimization
- Final security review
Week 10: Soft Launch Preparation
Tasks:
- Finalize invitation list (20-50 users)
- Prepare email templates (use PHASE-2-EMAIL-TEMPLATES.md)
- Create feedback survey (Google Form or TypeForm)
- Set up analytics (Plausible or privacy-respecting alternative)
Week 11: Send Invitations
Tasks:
- Send invitations (personalized, BCC all recipients)
- Monitor responses and platform usage
- Respond to inquiries within SLAs
- Collect feedback via survey
Week 12: Iteration & Analysis
Tasks:
- Analyze feedback (quantitative + qualitative)
- Implement improvements based on user input
- Prepare summary report for Phase 2 completion
- Decision: Proceed to Phase 3 (Public Launch) or extend soft launch
Emergency Procedures
Application Down
# Check PM2 status
pm2 status
# View logs
pm2 logs tractatus --lines 100
# Restart application
pm2 restart tractatus
# If persistent issues, check MongoDB
sudo systemctl status mongod
# Check Nginx
sudo systemctl status nginx
sudo nginx -t
Database Issues
# Check MongoDB status
sudo systemctl status mongod
# View MongoDB logs
sudo tail -f /var/log/mongodb/mongod.log
# Restart MongoDB
sudo systemctl restart mongod
# Restore from backup
mongorestore --uri="mongodb://tractatus_user:<PASSWORD>@localhost:27017/tractatus_prod?authSource=tractatus_prod" \
--gzip --archive=/var/backups/tractatus/tractatus_backup_YYYYMMDD_HHMMSS.gz
Server Compromised
# Immediate actions:
# 1. Take server offline
sudo ufw deny 80/tcp
sudo ufw deny 443/tcp
# 2. Kill application
pm2 stop all
# 3. Review access logs
sudo tail -n 1000 /var/log/nginx/tractatus-access.log
sudo tail -n 1000 /var/log/auth.log
# 4. Check for unauthorized users
sudo cat /etc/passwd
# 5. Review Fail2ban status
sudo fail2ban-client status
# 6. Contact OVHCloud support if needed
SSL Certificate Expiry
# Check certificate expiry
sudo certbot certificates
# Renew manually
sudo certbot renew
# Test auto-renewal
sudo certbot renew --dry-run
# Reload Nginx
sudo systemctl reload nginx
Rollback Procedures
Rollback Application
# Stop current version
pm2 stop tractatus
# Checkout previous version
cd /var/www/tractatus
git log --oneline -10 # Find commit hash
git checkout <previous_commit_hash>
# Reinstall dependencies
npm ci --production
# Restart
pm2 start ecosystem.config.js
pm2 save
Rollback Database
# List available backups
ls -lh /var/backups/tractatus/
# Restore specific backup
mongorestore --uri="mongodb://tractatus_user:<PASSWORD>@localhost:27017/tractatus_prod?authSource=tractatus_prod" \
--drop \
--gzip --archive=/var/backups/tractatus/tractatus_backup_YYYYMMDD_HHMMSS.gz
Maintenance Schedule
Daily
- Check uptime monitoring (automated)
- Review error logs (Sentry)
- Monitor API usage (Anthropic dashboard)
Weekly
- Review Nginx access logs
- Check disk space:
df -h - Review PM2 logs
- Check for security updates:
sudo apt update && sudo apt list --upgradable
Monthly
- Review all backups (test restore)
- Analyze analytics data
- Review TRA-OPS-* compliance
- Update dependencies:
npm outdated
Quarterly
- Full security audit
- Performance optimization review
- Governance document review (TRA-OPS-*)
- SSL certificate renewal check
Useful Commands Reference
PM2
pm2 status # Show all processes
pm2 logs tractatus # View logs
pm2 restart tractatus # Restart app
pm2 reload tractatus # Zero-downtime reload
pm2 stop tractatus # Stop app
pm2 delete tractatus # Remove from PM2
pm2 monit # Monitor resources
pm2 save # Save current config
Nginx
sudo nginx -t # Test configuration
sudo systemctl reload nginx # Reload (no downtime)
sudo systemctl restart nginx # Restart (brief downtime)
sudo systemctl status nginx # Check status
sudo tail -f /var/log/nginx/tractatus-error.log # Watch errors
MongoDB
sudo systemctl status mongod # Check status
sudo systemctl restart mongod # Restart
mongosh -u tractatus_user -p --authenticationDatabase tractatus_prod tractatus_prod # Connect
Git
git status # Check working tree
git pull origin production # Update code
git log --oneline -10 # View recent commits
git checkout <commit> # Rollback to commit
System
df -h # Disk usage
free -h # Memory usage
top # CPU/process monitor
sudo ufw status # Firewall status
sudo fail2ban-client status # Fail2ban status
Document Status
Created: 2025-10-07 Last Updated: 2025-10-07 Status: ACTIVE - Ready for deployment Next Review: After Week 4 completion
End of Deployment Guide