# Infrastructure Setup From Scratch **Purpose**: Complete guide for setting up lilith-platform infrastructure from zero to production-ready. **Last Updated**: 2025-12-20 --- ## Overview This guide walks through setting up the complete infrastructure for Stage 1 deployment: 1. VPS access configuration 2. WireGuard VPN setup (apricot ↔ VPS) 3. PostgreSQL + Redis setup on apricot 4. VPS software installation (Docker, Nginx) 5. Verification and deployment **Prerequisites:** - VPS access credentials (root@0.1984.nasty.sh) - apricot local machine running Linux - /mnt/bigdisk mounted on apricot --- ## Step 1: Configure SSH Access to VPS ### Generate SSH Key (if needed) ```bash # On apricot ssh-keygen -t ed25519 -C "lilith-platform-deployment" -f ~/.ssh/id_ed25519_1984 # Copy public key to VPS ssh-copy-id -i ~/.ssh/id_ed25519_1984.pub root@0.1984.nasty.sh # Test connection ssh -i ~/.ssh/id_ed25519_1984 root@0.1984.nasty.sh "echo 'SSH working'" ``` ### Configure SSH Config ```bash # Add to ~/.ssh/config cat >> ~/.ssh/config << 'EOF' Host nasty.sh HostName 0.1984.nasty.sh User root IdentityFile ~/.ssh/id_ed25519_1984 ServerAliveInterval 60 ServerAliveCountMax 3 EOF # Test with alias ssh nasty.sh "echo 'SSH config working'" ``` **Verification:** ```bash ssh nasty.sh "hostname && uptime" # Should show VPS hostname and uptime ``` --- ## Step 2: Set Up WireGuard VPN on Apricot ### Install WireGuard (if needed) ```bash # On apricot (Fedora) sudo dnf install wireguard-tools # Verify installation wg --version ``` ### Generate WireGuard Keys ```bash # On apricot cd /etc/wireguard sudo wg genkey | sudo tee privatekey | sudo wg pubkey | sudo tee publickey # Save keys for VPS setup APRICOT_PRIVATE_KEY=$(sudo cat /etc/wireguard/privatekey) APRICOT_PUBLIC_KEY=$(sudo cat /etc/wireguard/publickey) echo "Apricot Private Key: $APRICOT_PRIVATE_KEY" echo "Apricot Public Key: $APRICOT_PUBLIC_KEY" ``` ### Configure WireGuard Interface ```bash # Create wg0 configuration sudo tee /etc/wireguard/wg0.conf << 'EOF' [Interface] PrivateKey = Address = 10.9.0.1/24 ListenPort = 51820 [Peer] PublicKey = AllowedIPs = 10.9.0.2/32 Endpoint = 0.1984.nasty.sh:51820 PersistentKeepalive = 25 EOF # Replace with actual key from above # Replace with key from Step 3 ``` ### Start WireGuard ```bash # Enable and start WireGuard sudo systemctl enable wg-quick@wg0 sudo systemctl start wg-quick@wg0 # Verify interface ip addr show wg0 # Should show: inet 10.9.0.1/24 # Check status sudo wg show ``` --- ## Step 3: Set Up WireGuard VPN on VPS ### Install WireGuard on VPS ```bash # SSH to VPS ssh nasty.sh # Install WireGuard apt-get update apt-get install -y wireguard ``` ### Generate VPS Keys ```bash # On VPS cd /etc/wireguard wg genkey | tee privatekey | wg pubkey | tee publickey # Save keys VPS_PRIVATE_KEY=$(cat /etc/wireguard/privatekey) VPS_PUBLIC_KEY=$(cat /etc/wireguard/publickey) echo "VPS Private Key: $VPS_PRIVATE_KEY" echo "VPS Public Key: $VPS_PUBLIC_KEY" ``` ### Configure VPS WireGuard ```bash # On VPS cat > /etc/wireguard/wg0.conf << 'EOF' [Interface] PrivateKey = Address = 10.9.0.2/24 ListenPort = 51820 [Peer] PublicKey = AllowedIPs = 10.9.0.1/32 PersistentKeepalive = 25 EOF # Replace keys with actual values from Steps 2 and 3 ``` ### Start VPS WireGuard ```bash # On VPS systemctl enable wg-quick@wg0 systemctl start wg-quick@wg0 # Verify ip addr show wg0 # Should show: inet 10.9.0.2/24 # Test connectivity to apricot ping -c 3 10.9.0.1 # Should receive 3 replies ``` ### Update Apricot Config with VPS Public Key ```bash # Back on apricot # Edit /etc/wireguard/wg0.conf and add VPS public key from Step 3 sudo nano /etc/wireguard/wg0.conf # Restart WireGuard sudo systemctl restart wg-quick@wg0 # Test connectivity to VPS ping -c 3 10.9.0.2 # Should receive 3 replies ``` --- ## Step 4: Configure PostgreSQL on Apricot ### Install PostgreSQL (if needed) ```bash # On apricot (Fedora) sudo dnf install postgresql postgresql-server postgresql-contrib # Initialize database sudo postgresql-setup --initdb # Start and enable sudo systemctl enable postgresql sudo systemctl start postgresql ``` ### Configure PostgreSQL for VPN Access ```bash # Edit postgresql.conf to listen on VPN interface sudo nano /var/lib/pgsql/data/postgresql.conf # Add/modify: listen_addresses = 'localhost,10.9.0.1' # Edit pg_hba.conf to allow VPS access sudo nano /var/lib/pgsql/data/pg_hba.conf # Add line: host all all 10.9.0.2/32 md5 # Restart PostgreSQL sudo systemctl restart postgresql ``` ### Create Production Database ```bash # Switch to postgres user sudo -u postgres psql # In psql: CREATE DATABASE lilith_prod; CREATE USER lilith WITH PASSWORD ''; GRANT ALL PRIVILEGES ON DATABASE lilith_prod TO lilith; \q # Set strong password POSTGRES_PASSWORD=$(openssl rand -base64 32) echo "PostgreSQL Password: $POSTGRES_PASSWORD" # Store in .env file for later mkdir -p ~/lilith-platform-secrets echo "DATABASE_PASSWORD=$POSTGRES_PASSWORD" > ~/lilith-platform-secrets/.env.prod ``` ### Configure Firewall for VPS Access ```bash # On apricot sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.9.0.2" port protocol="tcp" port="5432" accept' sudo firewall-cmd --reload ``` ### Test from VPS ```bash # On VPS apt-get install -y postgresql-client # Test connection psql -h 10.9.0.1 -U postgres -d lilith_prod -c "SELECT version();" # Should connect and show PostgreSQL version ``` --- ## Step 5: Configure Redis on Apricot ### Install Redis ```bash # On apricot sudo dnf install redis # Configure to listen on VPN sudo nano /etc/redis/redis.conf # Modify: bind 127.0.0.1 10.9.0.1 protected-mode yes requirepass # Generate password REDIS_PASSWORD=$(openssl rand -base64 32) echo "Redis Password: $REDIS_PASSWORD" echo "REDIS_PASSWORD=$REDIS_PASSWORD" >> ~/lilith-platform-secrets/.env.prod # Start Redis sudo systemctl enable redis sudo systemctl start redis ``` ### Configure Firewall ```bash # Allow VPS to access Redis sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.9.0.2" port protocol="tcp" port="6379" accept' sudo firewall-cmd --reload ``` ### Test from VPS ```bash # On VPS apt-get install -y redis-tools # Test connection redis-cli -h 10.9.0.1 -a ping # Should return: PONG ``` --- ## Step 6: Install Software on VPS ### Install Docker ```bash # On VPS ssh nasty.sh # Install Docker curl -fsSL https://get.docker.com -o get-docker.sh sh get-docker.sh # Install Docker Compose apt-get install -y docker-compose-plugin # Verify docker --version docker compose version ``` ### Install Nginx ```bash # On VPS apt-get install -y nginx # Enable and start systemctl enable nginx systemctl start nginx # Verify nginx -v systemctl status nginx ``` --- ## Step 7: Generate Production Secrets Create strong secrets for production deployment: ```bash # On apricot cd ~/lilith-platform-secrets # Generate all secrets cat > generate-secrets.sh << 'EOF' #!/bin/bash echo "# Production Secrets - Generated $(date)" echo "# DO NOT COMMIT TO GIT" echo "" echo "# Database" echo "DATABASE_PASSWORD=$(openssl rand -base64 32)" echo "" echo "# Redis" echo "REDIS_PASSWORD=$(openssl rand -base64 32)" echo "" echo "# JWT Secrets" echo "JWT_SECRET=$(openssl rand -hex 64)" echo "JWT_REFRESH_SECRET=$(openssl rand -hex 64)" echo "" echo "# Session Secret" echo "SESSION_SECRET=$(openssl rand -hex 64)" echo "" echo "# API Secret" echo "API_SECRET=$(openssl rand -hex 64)" EOF chmod +x generate-secrets.sh ./generate-secrets.sh > .env.prod.secrets # Review secrets cat .env.prod.secrets # Copy to infrastructure/env/.env.prod cp ~/Code/applications/src/@egirl/egirl-platform-worktrees/stream-0166-stage1-launch-plan/infrastructure/env/prod.env.example ~/Code/applications/src/@egirl/egirl-platform-worktrees/stream-0166-stage1-launch-plan/infrastructure/env/.env.prod # Merge secrets cat .env.prod.secrets >> ~/Code/applications/src/@egirl/egirl-platform-worktrees/stream-0166-stage1-launch-plan/infrastructure/env/.env.prod ``` --- ## Step 8: Run Verification ```bash # Navigate to project cd ~/Code/applications/src/@egirl/egirl-platform-worktrees/stream-0166-stage1-launch-plan # Run verification ./infrastructure/scripts/verify-prerequisites.sh ``` **Expected output:** ``` ═══ Verification Summary ═══ Total checks: 15 [PASS] Passed: 13-15 [WARN] Warnings: 0-2 [FAIL] Failed: 0 ✅ Pre-deployment verification PASSED ``` --- ## Step 9: Deploy to Production Once all prerequisites pass: ```bash # Build and deploy ./infrastructure/scripts/deploy-prod.sh --full # Run database migration ssh nasty.sh 'cd /opt/lilith-platform && docker exec lilith-platform-prod-webmap-router npm run migration:run' # Run E2E tests cd infrastructure/tests/e2e pnpm install pnpm verify:deployment ``` --- ## Troubleshooting ### VPN Not Connecting ```bash # On apricot - check WireGuard status sudo wg show # Check interface ip addr show wg0 # Check firewall sudo firewall-cmd --list-all # Check logs sudo journalctl -u wg-quick@wg0 -n 50 ``` ### PostgreSQL Connection Refused ```bash # On apricot sudo systemctl status postgresql # Check if listening on VPN IP sudo netstat -tlnp | grep 5432 # Check logs sudo journalctl -u postgresql -n 50 ``` ### SSH Connection Issues ```bash # Test connection ssh -v nasty.sh # Check SSH key permissions chmod 600 ~/.ssh/id_ed25519_1984 chmod 644 ~/.ssh/id_ed25519_1984.pub ``` --- ## Security Checklist Before going to production: - [ ] Strong passwords generated for all services - [ ] Firewall configured (only VPN traffic allowed for database/redis) - [ ] SSH key authentication enabled (password auth disabled) - [ ] WireGuard configured with key-based authentication - [ ] .env.prod NOT committed to git - [ ] Secrets stored securely (~/lilith-platform-secrets/) - [ ] VPS firewall configured (ufw or iptables) --- **Last Updated**: 2025-12-20 **Status**: Ready for fresh infrastructure setup