- Create Economist SubmissionTracking package correctly: * mainArticle = full blog post content * coverLetter = 216-word SIR— letter * Links to blog post via blogPostId - Archive 'Letter to The Economist' from blog posts (it's the cover letter) - Fix date display on article cards (use published_at) - Target publication already displaying via blue badge Database changes: - Make blogPostId optional in SubmissionTracking model - Economist package ID: 68fa85ae49d4900e7f2ecd83 - Le Monde package ID: 68fa2abd2e6acd5691932150 Next: Enhanced modal with tabs, validation, export 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1567 lines
34 KiB
Markdown
1567 lines
34 KiB
Markdown
# 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
|
|
|
|
1. [Week 0: Pre-Deployment Preparation](#week-0-pre-deployment-preparation)
|
|
2. [Week 1: Infrastructure Setup](#week-1-infrastructure-setup)
|
|
3. [Week 2: Application Deployment](#week-2-application-deployment)
|
|
4. [Week 3: Security Hardening](#week-3-security-hardening)
|
|
5. [Week 4: Monitoring & Testing](#week-4-monitoring--testing)
|
|
6. [Week 5-8: AI Features](#week-5-8-ai-features)
|
|
7. [Week 9-12: Soft Launch](#week-9-12-soft-launch)
|
|
8. [Emergency Procedures](#emergency-procedures)
|
|
|
|
---
|
|
|
|
## Week 0: Pre-Deployment Preparation
|
|
|
|
### Day 0.1: OVHCloud VPS Assessment
|
|
|
|
**Current VPS**: vps-7f023e40.vps.ovh.net
|
|
|
|
**Tasks**:
|
|
1. [ ] **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)
|
|
|
|
2. [ ] **Verify VPS location**:
|
|
- Confirm datacenter region (Singapore/Australia preferred)
|
|
- Check latency to target users
|
|
|
|
3. [ ] **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):
|
|
```bash
|
|
# 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**:
|
|
1. [ ] **Generate JWT Secret**:
|
|
```bash
|
|
# On your local machine
|
|
openssl rand -base64 48
|
|
```
|
|
- Copy output (64 characters)
|
|
- Store in password manager (1Password, Bitwarden, etc.)
|
|
- Label: "Tractatus JWT_SECRET (Production)"
|
|
|
|
2. [ ] **Generate MongoDB Password**:
|
|
```bash
|
|
openssl rand -base64 32
|
|
```
|
|
- Copy output (44 characters)
|
|
- Store in password manager
|
|
- Label: "Tractatus MongoDB tractatus_user password"
|
|
|
|
3. [ ] **Generate MongoDB Root Password**:
|
|
```bash
|
|
openssl rand -base64 32
|
|
```
|
|
- Store in password manager
|
|
- Label: "Tractatus MongoDB root password"
|
|
|
|
4. [ ] **Generate SSH Key Pair** (for Tractatus deployments):
|
|
```bash
|
|
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**:
|
|
1. [ ] **Access OVHCloud DNS Management**:
|
|
- Navigate to: Domains → agenticgovernance.digital → DNS Zone
|
|
- Familiarize with interface
|
|
|
|
2. [ ] **Get VPS IP Address** from OVHCloud:
|
|
- VPS Dashboard → vps-7f023e40.vps.ovh.net → IP Addresses
|
|
- Note IPv4 address: `___.___.___.___ `
|
|
- Note IPv6 address (if available): `____:____:____:____`
|
|
|
|
3. [ ] **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**:
|
|
1. [ ] **Create production branch**:
|
|
```bash
|
|
cd /home/theflow/projects/tractatus
|
|
git checkout -b production
|
|
git push -u origin production
|
|
git checkout main
|
|
```
|
|
|
|
2. [ ] **Create .env.production template**:
|
|
```bash
|
|
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
|
|
```
|
|
|
|
3. [ ] **Add .env.production to .gitignore**:
|
|
```bash
|
|
echo ".env.production" >> .gitignore
|
|
git add .gitignore
|
|
git commit -m "chore: add .env.production to gitignore"
|
|
```
|
|
|
|
4. [ ] **Test production build locally**:
|
|
```bash
|
|
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**:
|
|
|
|
1. [ ] **Access VPS via SSH** (OVHCloud provides root access):
|
|
```bash
|
|
ssh root@vps-7f023e40.vps.ovh.net
|
|
# Or use IP: ssh root@<VPS_IP>
|
|
```
|
|
|
|
2. [ ] **Update system packages**:
|
|
```bash
|
|
apt update && apt upgrade -y
|
|
```
|
|
|
|
3. [ ] **Create non-root user**:
|
|
```bash
|
|
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
|
|
```
|
|
|
|
4. [ ] **Set up SSH key authentication** for tractatus user:
|
|
```bash
|
|
# 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
|
|
```
|
|
|
|
5. [ ] **Test SSH access** as tractatus user:
|
|
```bash
|
|
# 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:~$
|
|
```
|
|
|
|
6. [ ] **Configure sudo without password** (for deployment automation):
|
|
```bash
|
|
# 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**:
|
|
|
|
1. [ ] **Install UFW (Uncomplicated Firewall)**:
|
|
```bash
|
|
# As tractatus user on VPS:
|
|
sudo apt install ufw -y
|
|
```
|
|
|
|
2. [ ] **Configure UFW rules** (CRITICAL - don't lock yourself out):
|
|
```bash
|
|
# 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
|
|
```
|
|
|
|
3. [ ] **Enable UFW**:
|
|
```bash
|
|
sudo ufw enable
|
|
# Type 'y' to confirm
|
|
|
|
# Verify status
|
|
sudo ufw status verbose
|
|
```
|
|
|
|
4. [ ] **Harden SSH configuration**:
|
|
```bash
|
|
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
|
|
```
|
|
|
|
5. [ ] **Restart SSH service**:
|
|
```bash
|
|
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
|
|
```
|
|
|
|
6. [ ] **Install Fail2ban**:
|
|
```bash
|
|
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
|
|
```
|
|
|
|
7. [ ] **Start Fail2ban**:
|
|
```bash
|
|
sudo systemctl enable fail2ban
|
|
sudo systemctl start fail2ban
|
|
sudo fail2ban-client status sshd
|
|
```
|
|
|
|
---
|
|
|
|
### Day 1.3: Install Node.js & Dependencies
|
|
|
|
**Tasks**:
|
|
|
|
1. [ ] **Install Node.js 18 LTS** (via NodeSource):
|
|
```bash
|
|
# 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
|
|
```
|
|
|
|
2. [ ] **Install build tools** (needed for some npm packages):
|
|
```bash
|
|
sudo apt install build-essential -y
|
|
```
|
|
|
|
3. [ ] **Install Git**:
|
|
```bash
|
|
sudo apt install git -y
|
|
git --version
|
|
```
|
|
|
|
4. [ ] **Install PM2** (process manager for Node.js):
|
|
```bash
|
|
sudo npm install -g pm2
|
|
pm2 --version
|
|
```
|
|
|
|
5. [ ] **Configure PM2 to start on boot**:
|
|
```bash
|
|
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**:
|
|
|
|
1. [ ] **Import MongoDB GPG key**:
|
|
```bash
|
|
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \
|
|
sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
|
|
```
|
|
|
|
2. [ ] **Add MongoDB repository**:
|
|
```bash
|
|
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
|
|
```
|
|
|
|
3. [ ] **Install MongoDB**:
|
|
```bash
|
|
sudo apt update
|
|
sudo apt install mongodb-org -y
|
|
```
|
|
|
|
4. [ ] **Start MongoDB**:
|
|
```bash
|
|
sudo systemctl start mongod
|
|
sudo systemctl enable mongod
|
|
sudo systemctl status mongod
|
|
```
|
|
|
|
5. [ ] **Create MongoDB admin user**:
|
|
```bash
|
|
mongosh
|
|
|
|
# In MongoDB shell:
|
|
use admin
|
|
db.createUser({
|
|
user: "admin",
|
|
pwd: "<MONGODB_ROOT_PASSWORD_FROM_DAY_0.2>",
|
|
roles: ["root"]
|
|
})
|
|
|
|
# Exit MongoDB shell
|
|
exit
|
|
```
|
|
|
|
6. [ ] **Enable MongoDB authentication**:
|
|
```bash
|
|
sudo nano /etc/mongod.conf
|
|
|
|
# Find the security section and modify:
|
|
security:
|
|
authorization: enabled
|
|
|
|
# Save and exit
|
|
```
|
|
|
|
7. [ ] **Restart MongoDB**:
|
|
```bash
|
|
sudo systemctl restart mongod
|
|
```
|
|
|
|
8. [ ] **Create Tractatus database and user**:
|
|
```bash
|
|
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**:
|
|
|
|
1. [ ] **Install Nginx**:
|
|
```bash
|
|
sudo apt install nginx -y
|
|
|
|
# Verify installation
|
|
nginx -v
|
|
sudo systemctl status nginx
|
|
```
|
|
|
|
2. [ ] **Configure Nginx for Tractatus** (HTTP only, SSL in Day 1.6):
|
|
```bash
|
|
sudo nano /etc/nginx/sites-available/tractatus
|
|
|
|
# Paste this configuration:
|
|
```
|
|
```nginx
|
|
# 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;
|
|
}
|
|
}
|
|
```
|
|
|
|
3. [ ] **Enable the site**:
|
|
```bash
|
|
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
|
|
```
|
|
|
|
4. [ ] **Test Nginx** (from your local machine):
|
|
```bash
|
|
# 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**:
|
|
|
|
1. [ ] **Get VPS IP address**:
|
|
```bash
|
|
# On VPS:
|
|
ip addr show | grep 'inet '
|
|
# Note the public IPv4 (not 127.0.0.1)
|
|
```
|
|
|
|
2. [ ] **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
|
|
|
|
3. [ ] **Wait for DNS propagation** (5-30 minutes):
|
|
```bash
|
|
# 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
|
|
```
|
|
|
|
4. [ ] **Test DNS** with browser:
|
|
- Visit: http://agenticgovernance.digital
|
|
- Should see: "Tractatus Framework - Deploying..."
|
|
|
|
---
|
|
|
|
### Day 1.7: Install SSL/TLS with Let's Encrypt
|
|
|
|
**Tasks**:
|
|
|
|
1. [ ] **Install Certbot**:
|
|
```bash
|
|
sudo apt install certbot python3-certbot-nginx -y
|
|
```
|
|
|
|
2. [ ] **Obtain SSL certificate**:
|
|
```bash
|
|
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)
|
|
```
|
|
|
|
3. [ ] **Test SSL certificate**:
|
|
- Visit: https://agenticgovernance.digital
|
|
- Should see: "Tractatus Framework - Deploying..." (now HTTPS)
|
|
- Check for padlock icon in browser
|
|
|
|
4. [ ] **Test auto-renewal**:
|
|
```bash
|
|
sudo certbot renew --dry-run
|
|
# Should complete without errors
|
|
```
|
|
|
|
5. [ ] **Verify Nginx configuration**:
|
|
```bash
|
|
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**:
|
|
|
|
1. [ ] **Create application directory**:
|
|
```bash
|
|
# On VPS as tractatus user:
|
|
sudo mkdir -p /var/www/tractatus
|
|
sudo chown tractatus:tractatus /var/www/tractatus
|
|
cd /var/www/tractatus
|
|
```
|
|
|
|
2. [ ] **Clone repository**:
|
|
```bash
|
|
# 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 .
|
|
```
|
|
|
|
3. [ ] **Checkout production branch**:
|
|
```bash
|
|
git checkout production
|
|
git pull origin production
|
|
```
|
|
|
|
4. [ ] **Install dependencies**:
|
|
```bash
|
|
npm ci --production
|
|
# Use 'ci' instead of 'install' for reproducible builds
|
|
```
|
|
|
|
---
|
|
|
|
### Day 2.2: Configure Environment
|
|
|
|
**Tasks**:
|
|
|
|
1. [ ] **Create production .env file**:
|
|
```bash
|
|
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
|
|
```
|
|
|
|
2. [ ] **Secure .env file**:
|
|
```bash
|
|
chmod 600 /var/www/tractatus/.env
|
|
chown tractatus:tractatus /var/www/tractatus/.env
|
|
```
|
|
|
|
3. [ ] **Initialize MongoDB** (seed collections):
|
|
```bash
|
|
cd /var/www/tractatus
|
|
node scripts/init-db.js
|
|
```
|
|
|
|
4. [ ] **Create admin user**:
|
|
```bash
|
|
node scripts/seed-admin.js
|
|
# Note the admin credentials output
|
|
```
|
|
|
|
---
|
|
|
|
### Day 2.3: Configure Nginx Reverse Proxy
|
|
|
|
**Tasks**:
|
|
|
|
1. [ ] **Update Nginx configuration**:
|
|
```bash
|
|
sudo nano /etc/nginx/sites-available/tractatus
|
|
```
|
|
|
|
Replace with:
|
|
```nginx
|
|
# 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;
|
|
}
|
|
}
|
|
```
|
|
|
|
2. [ ] **Test Nginx configuration**:
|
|
```bash
|
|
sudo nginx -t
|
|
```
|
|
|
|
3. [ ] **Reload Nginx**:
|
|
```bash
|
|
sudo systemctl reload nginx
|
|
```
|
|
|
|
---
|
|
|
|
### Day 2.4: Start Application with PM2
|
|
|
|
**Tasks**:
|
|
|
|
1. [ ] **Create PM2 ecosystem file**:
|
|
```bash
|
|
nano /var/www/tractatus/ecosystem.config.js
|
|
```
|
|
|
|
```javascript
|
|
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
|
|
}]
|
|
};
|
|
```
|
|
|
|
2. [ ] **Create logs directory**:
|
|
```bash
|
|
mkdir -p /var/www/tractatus/logs
|
|
```
|
|
|
|
3. [ ] **Start application**:
|
|
```bash
|
|
cd /var/www/tractatus
|
|
pm2 start ecosystem.config.js
|
|
|
|
# Check status
|
|
pm2 status
|
|
|
|
# View logs
|
|
pm2 logs tractatus --lines 50
|
|
```
|
|
|
|
4. [ ] **Save PM2 configuration**:
|
|
```bash
|
|
pm2 save
|
|
```
|
|
|
|
5. [ ] **Test application**:
|
|
```bash
|
|
# Local test
|
|
curl http://localhost:9000/health
|
|
|
|
# Public test
|
|
curl https://agenticgovernance.digital/health
|
|
```
|
|
|
|
6. [ ] **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**:
|
|
|
|
1. [ ] **Install unattended-upgrades**:
|
|
```bash
|
|
sudo apt install unattended-upgrades -y
|
|
```
|
|
|
|
2. [ ] **Configure automatic updates**:
|
|
```bash
|
|
sudo dpkg-reconfigure -plow unattended-upgrades
|
|
# Select "Yes" to enable
|
|
```
|
|
|
|
3. [ ] **Verify configuration**:
|
|
```bash
|
|
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**:
|
|
|
|
1. [ ] **Configure Nginx rate limiting**:
|
|
```bash
|
|
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 ...
|
|
}
|
|
```
|
|
|
|
2. [ ] **Apply rate limits in site config**:
|
|
```bash
|
|
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 ...
|
|
}
|
|
```
|
|
|
|
3. [ ] **Test and reload**:
|
|
```bash
|
|
sudo nginx -t
|
|
sudo systemctl reload nginx
|
|
```
|
|
|
|
---
|
|
|
|
### Day 3.3: Setup Automated Backups
|
|
|
|
**Tasks**:
|
|
|
|
1. [ ] **Create backup script**:
|
|
```bash
|
|
sudo nano /usr/local/bin/tractatus-backup.sh
|
|
```
|
|
|
|
```bash
|
|
#!/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
|
|
```
|
|
|
|
2. [ ] **Make script executable**:
|
|
```bash
|
|
sudo chmod +x /usr/local/bin/tractatus-backup.sh
|
|
```
|
|
|
|
3. [ ] **Test backup script**:
|
|
```bash
|
|
sudo /usr/local/bin/tractatus-backup.sh
|
|
ls -lh /var/backups/tractatus/
|
|
```
|
|
|
|
4. [ ] **Schedule daily backups with cron**:
|
|
```bash
|
|
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**:
|
|
|
|
1. [ ] **Create Nginx jail**:
|
|
```bash
|
|
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
|
|
```
|
|
|
|
2. [ ] **Restart Fail2ban**:
|
|
```bash
|
|
sudo systemctl restart fail2ban
|
|
sudo fail2ban-client status
|
|
```
|
|
|
|
---
|
|
|
|
## Week 4: Monitoring & Testing
|
|
|
|
### Day 4.1: Setup Error Monitoring (Sentry)
|
|
|
|
**Tasks**:
|
|
|
|
1. [ ] **Create Sentry account** at sentry.io (free tier)
|
|
|
|
2. [ ] **Create new project**:
|
|
- Platform: Node.js
|
|
- Project name: tractatus-production
|
|
|
|
3. [ ] **Get DSN** (Data Source Name) from Sentry dashboard
|
|
|
|
4. [ ] **Install Sentry SDK**:
|
|
```bash
|
|
cd /var/www/tractatus
|
|
npm install @sentry/node --save
|
|
```
|
|
|
|
5. [ ] **Add Sentry DSN to .env**:
|
|
```bash
|
|
nano /var/www/tractatus/.env
|
|
|
|
# Add:
|
|
SENTRY_DSN=<YOUR_SENTRY_DSN>
|
|
```
|
|
|
|
6. [ ] **Initialize Sentry in application**:
|
|
```bash
|
|
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());
|
|
```
|
|
|
|
7. [ ] **Restart application**:
|
|
```bash
|
|
pm2 restart tractatus
|
|
```
|
|
|
|
8. [ ] **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**:
|
|
|
|
1. [ ] **Create UptimeRobot account** at uptimerobot.com (free tier)
|
|
|
|
2. [ ] **Add monitor**:
|
|
- Monitor Type: HTTPS
|
|
- Friendly Name: Tractatus Production
|
|
- URL: https://agenticgovernance.digital/health
|
|
- Monitoring Interval: 5 minutes
|
|
|
|
3. [ ] **Configure alerts**:
|
|
- Email: admin@agenticgovernance.digital
|
|
- Alert when: Down
|
|
- Send notification: Immediately
|
|
|
|
4. [ ] **Test monitor**:
|
|
- Stop PM2: `pm2 stop tractatus`
|
|
- Wait for alert (5 minutes)
|
|
- Restart: `pm2 start tractatus`
|
|
- Verify "UP" notification
|
|
|
|
---
|
|
|
|
### Day 4.3: Performance Testing
|
|
|
|
**Tasks**:
|
|
|
|
1. [ ] **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
|
|
|
|
2. [ ] **Run Lighthouse audit** (Chrome DevTools):
|
|
- Open Chrome DevTools (F12)
|
|
- Lighthouse tab
|
|
- Run audit (Desktop)
|
|
- Check: Performance, Accessibility, Best Practices, SEO
|
|
- Target: All >90
|
|
|
|
3. [ ] **Load testing with Apache Bench**:
|
|
```bash
|
|
# On local machine:
|
|
ab -n 1000 -c 10 https://agenticgovernance.digital/
|
|
|
|
# Should handle 1000 requests with 10 concurrent without errors
|
|
```
|
|
|
|
4. [ ] **Check response times**:
|
|
```bash
|
|
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**:
|
|
|
|
1. [ ] **Run SSL Labs test**:
|
|
- Visit: https://www.ssllabs.com/ssltest/
|
|
- Enter: agenticgovernance.digital
|
|
- Target: A or A+ rating
|
|
|
|
2. [ ] **Check security headers**:
|
|
- Visit: https://securityheaders.com/
|
|
- Enter: https://agenticgovernance.digital
|
|
- Target: A or A+ rating
|
|
|
|
3. [ ] **Scan for vulnerabilities**:
|
|
```bash
|
|
# On VPS:
|
|
sudo apt install lynis -y
|
|
sudo lynis audit system
|
|
|
|
# Review warnings in: /var/log/lynis-report.dat
|
|
```
|
|
|
|
4. [ ] **Check npm dependencies**:
|
|
```bash
|
|
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**:
|
|
|
|
1. [ ] **Create Anthropic account** and obtain production API key
|
|
|
|
2. [ ] **Add Claude API key to .env**:
|
|
```bash
|
|
nano /var/www/tractatus/.env
|
|
|
|
# Add:
|
|
CLAUDE_API_KEY=<YOUR_ANTHROPIC_API_KEY>
|
|
CLAUDE_MODEL=claude-sonnet-4-5-20250929
|
|
CLAUDE_MAX_TOKENS=4096
|
|
```
|
|
|
|
3. [ ] **Install Claude SDK**:
|
|
```bash
|
|
cd /var/www/tractatus
|
|
npm install @anthropic-ai/sdk --save
|
|
```
|
|
|
|
4. [ ] **Deploy updated code**:
|
|
```bash
|
|
git pull origin production
|
|
npm install
|
|
pm2 restart tractatus
|
|
```
|
|
|
|
5. [ ] **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**:
|
|
|
|
1. [ ] **Blog Curation System**:
|
|
- Implement topic suggestion API
|
|
- Implement outline generation API
|
|
- Create human approval workflow
|
|
- Test end-to-end
|
|
|
|
2. [ ] **Media Inquiry Triage**:
|
|
- Implement classification API
|
|
- Implement draft response generator
|
|
- Create moderation queue
|
|
- Test all priority levels
|
|
|
|
3. [ ] **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**:
|
|
|
|
1. [ ] **End-to-end testing** of all features
|
|
2. [ ] **Governance compliance audit** (verify TRA-OPS-* policies)
|
|
3. [ ] **User acceptance testing** (internal)
|
|
4. [ ] **Performance optimization**
|
|
5. [ ] **Final security review**
|
|
|
|
---
|
|
|
|
### Week 10: Soft Launch Preparation
|
|
|
|
**Tasks**:
|
|
|
|
1. [ ] **Finalize invitation list** (20-50 users)
|
|
2. [ ] **Prepare email templates** (use PHASE-2-EMAIL-TEMPLATES.md)
|
|
3. [ ] **Create feedback survey** (Google Form or TypeForm)
|
|
4. [ ] **Set up analytics** (Plausible or privacy-respecting alternative)
|
|
|
|
---
|
|
|
|
### Week 11: Send Invitations
|
|
|
|
**Tasks**:
|
|
|
|
1. [ ] **Send invitations** (personalized, BCC all recipients)
|
|
2. [ ] **Monitor responses** and platform usage
|
|
3. [ ] **Respond to inquiries** within SLAs
|
|
4. [ ] **Collect feedback** via survey
|
|
|
|
---
|
|
|
|
### Week 12: Iteration & Analysis
|
|
|
|
**Tasks**:
|
|
|
|
1. [ ] **Analyze feedback** (quantitative + qualitative)
|
|
2. [ ] **Implement improvements** based on user input
|
|
3. [ ] **Prepare summary report** for Phase 2 completion
|
|
4. [ ] **Decision**: Proceed to Phase 3 (Public Launch) or extend soft launch
|
|
|
|
---
|
|
|
|
## Emergency Procedures
|
|
|
|
### Application Down
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
```bash
|
|
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
|
|
```bash
|
|
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
|
|
```bash
|
|
sudo systemctl status mongod # Check status
|
|
sudo systemctl restart mongod # Restart
|
|
mongosh -u tractatus_user -p --authenticationDatabase tractatus_prod tractatus_prod # Connect
|
|
```
|
|
|
|
### Git
|
|
```bash
|
|
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
|
|
```bash
|
|
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**
|