# Static MUSL Binary Deployment Plan ## Overview This document outlines the deployment architecture for ginxsom using static MUSL binaries. The new approach eliminates remote compilation and simplifies deployment to a single binary upload. ## Architecture Changes ### Current Deployment (Old) ``` Local Machine: - Build dynamic binary with make - Upload entire project via rsync - Remote server compiles from source - Install dependencies (libsqlite3-dev, libfcgi-dev, etc.) - Build nostr_core_lib submodules remotely - Binary location: /home/ubuntu/ginxsom/ginxsom.fcgi - Database: /home/ubuntu/ginxsom/db/ginxsom.db - Blobs: /var/www/html/blossom/ ``` ### New Deployment (Static MUSL) ``` Local Machine: - Build static MUSL binary with Docker (build_static.sh) - Upload only the binary (no source code needed) - No remote compilation required - Minimal dependencies (only spawn-fcgi) - Binary location: /usr/local/bin/ginxsom/ginxsom-fcgi - Database: /var/lib/ginxsom/ginxsom.db - Blobs: /var/www/blobs/ ``` ## Directory Structure ### Production Server Layout ``` /usr/local/bin/ginxsom/ ├── ginxsom-fcgi # Static binary (executable) └── README.md # Version info and deployment notes /var/lib/ginxsom/ ├── ginxsom.db # SQLite database └── backups/ # Database backups /var/www/blobs/ ├── .jpg # Blob files ├── .png └── ... /tmp/ └── ginxsom-fcgi.sock # FastCGI socket ``` ## Deployment Process ### Phase 1: Build Static Binary (Local) ```bash # Build the static binary ./build_static.sh # Output: build/ginxsom-fcgi_static_x86_64 # Size: ~7-10 MB # Dependencies: NONE (fully static) ``` ### Phase 2: Upload Binary ```bash # Upload to server scp build/ginxsom-fcgi_static_x86_64 ubuntu@laantungir.net:/tmp/ # Install to /usr/local/bin/ginxsom/ ssh ubuntu@laantungir.net << 'EOF' sudo mkdir -p /usr/local/bin/ginxsom sudo mv /tmp/ginxsom-fcgi_static_x86_64 /usr/local/bin/ginxsom/ginxsom-fcgi sudo chmod +x /usr/local/bin/ginxsom/ginxsom-fcgi sudo chown root:root /usr/local/bin/ginxsom/ginxsom-fcgi EOF ``` ### Phase 3: Setup Data Directories ```bash ssh ubuntu@laantungir.net << 'EOF' # Create database directory sudo mkdir -p /var/lib/ginxsom/backups sudo chown www-data:www-data /var/lib/ginxsom sudo chmod 755 /var/lib/ginxsom # Create blob storage directory sudo mkdir -p /var/www/blobs sudo chown www-data:www-data /var/www/blobs sudo chmod 755 /var/www/blobs # Migrate existing data if needed if [ -f /var/www/html/blossom/ginxsom.db ]; then sudo cp /var/www/html/blossom/ginxsom.db /var/lib/ginxsom/ sudo chown www-data:www-data /var/lib/ginxsom/ginxsom.db fi if [ -d /var/www/html/blossom ]; then sudo cp -r /var/www/html/blossom/* /var/www/blobs/ 2>/dev/null || true sudo chown -R www-data:www-data /var/www/blobs fi EOF ``` ### Phase 4: Install Minimal Dependencies ```bash ssh ubuntu@laantungir.net << 'EOF' # Only spawn-fcgi is needed (no build tools!) sudo apt-get update sudo apt-get install -y spawn-fcgi EOF ``` ### Phase 5: Start Service ```bash ssh ubuntu@laantungir.net << 'EOF' # Stop existing process sudo pkill -f ginxsom-fcgi || true sudo rm -f /tmp/ginxsom-fcgi.sock # Start with spawn-fcgi sudo spawn-fcgi \ -M 666 \ -u www-data \ -g www-data \ -s /tmp/ginxsom-fcgi.sock \ -U www-data \ -G www-data \ -d /var/lib/ginxsom \ -- /usr/local/bin/ginxsom/ginxsom-fcgi \ --db-path /var/lib/ginxsom/ginxsom.db \ --storage-dir /var/www/blobs EOF ``` ## Nginx Configuration Updates ### Required Changes to `/etc/nginx/conf.d/default.conf` ```nginx # Blossom subdomains HTTPS - ginxsom FastCGI server { listen 443 ssl; server_name blossom.laantungir.net; ssl_certificate /etc/letsencrypt/live/git.laantungir.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/git.laantungir.net/privkey.pem; # Security headers add_header X-Content-Type-Options nosniff always; add_header X-Frame-Options DENY always; add_header X-XSS-Protection "1; mode=block" always; # CORS for Blossom protocol add_header Access-Control-Allow-Origin * always; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, HEAD, OPTIONS, PATCH" always; add_header Access-Control-Allow-Headers "Authorization, Content-Type, Content-Length, Accept, Origin, User-Agent, DNT, Cache-Control, X-Mx-ReqToken, Keep-Alive, X-Requested-With, If-Modified-Since, *" always; add_header Access-Control-Max-Age 86400 always; # CHANGED: Root directory for blob storage root /var/www/blobs; # Was: /var/www/html/blossom # Maximum upload size client_max_body_size 100M; # ... rest of configuration remains the same ... # CHANGED: Update SCRIPT_FILENAME references location = /upload { if ($request_method !~ ^(PUT|HEAD)$) { return 405; } fastcgi_pass ginxsom_backend; include fastcgi_params; fastcgi_param SCRIPT_FILENAME /usr/local/bin/ginxsom/ginxsom-fcgi; # Was: $document_root/ginxsom.fcgi } # Apply same change to all other FastCGI locations... } ``` ## Benefits of New Architecture ### 1. Simplified Deployment - **Before**: Upload source → Install deps → Build submodules → Compile → Deploy - **After**: Upload binary → Start service ### 2. Reduced Dependencies - **Before**: gcc, make, git, libsqlite3-dev, libfcgi-dev, libcurl4-openssl-dev, etc. - **After**: spawn-fcgi only ### 3. Better Security - No build tools on production server - No source code on production server - Smaller attack surface ### 4. Faster Deployments - **Before**: ~5-10 minutes (build time) - **After**: ~30 seconds (upload + restart) ### 5. Consistent Binaries - Same binary works on any Linux distribution - No "works on my machine" issues - Reproducible builds via Docker ### 6. Cleaner Organization - Binary in standard location (`/usr/local/bin/`) - Data in standard location (`/var/lib/`) - Blobs separate from web root (`/var/www/blobs/`) ## Migration Strategy ### Option 1: In-Place Migration (Recommended) 1. Build static binary locally 2. Upload to `/tmp/` 3. Stop current service 4. Create new directories 5. Migrate data 6. Update nginx config 7. Start new service 8. Verify functionality 9. Clean up old files ### Option 2: Blue-Green Deployment 1. Setup new directories alongside old 2. Deploy static binary 3. Test on different port 4. Switch nginx config 5. Remove old deployment ### Option 3: Fresh Install 1. Backup database and blobs 2. Remove old installation 3. Deploy static binary 4. Restore data 5. Configure nginx 6. Start service ## Rollback Plan If issues occur, rollback is simple: ```bash # Stop new service sudo pkill -f ginxsom-fcgi # Restore old binary location sudo spawn-fcgi \ -M 666 \ -u www-data \ -g www-data \ -s /tmp/ginxsom-fcgi.sock \ -U www-data \ -G www-data \ -d /home/ubuntu/ginxsom \ -- /home/ubuntu/ginxsom/ginxsom.fcgi \ --db-path /home/ubuntu/ginxsom/db/ginxsom.db \ --storage-dir /var/www/html/blossom # Revert nginx config sudo cp /etc/nginx/conf.d/default.conf.backup /etc/nginx/conf.d/default.conf sudo nginx -s reload ``` ## SystemD Service (Future Enhancement) Create `/etc/systemd/system/ginxsom.service`: ```ini [Unit] Description=Ginxsom Blossom Server After=network.target [Service] Type=forking User=www-data Group=www-data WorkingDirectory=/var/lib/ginxsom ExecStart=/usr/bin/spawn-fcgi \ -M 666 \ -u www-data \ -g www-data \ -s /tmp/ginxsom-fcgi.sock \ -U www-data \ -G www-data \ -d /var/lib/ginxsom \ -- /usr/local/bin/ginxsom/ginxsom-fcgi \ --db-path /var/lib/ginxsom/ginxsom.db \ --storage-dir /var/www/blobs ExecStop=/usr/bin/pkill -f ginxsom-fcgi Restart=always RestartSec=5 [Install] WantedBy=multi-user.target ``` Enable and start: ```bash sudo systemctl daemon-reload sudo systemctl enable ginxsom sudo systemctl start ginxsom sudo systemctl status ginxsom ``` ## Verification Steps After deployment, verify: 1. **Binary is static**: ```bash ldd /usr/local/bin/ginxsom/ginxsom-fcgi # Should show: "not a dynamic executable" ``` 2. **Service is running**: ```bash ps aux | grep ginxsom-fcgi ls -la /tmp/ginxsom-fcgi.sock ``` 3. **Health endpoint**: ```bash curl -k https://blossom.laantungir.net/health # Should return: OK ``` 4. **Upload test**: ```bash # Use existing test scripts ./tests/file_put_bud02.sh ``` 5. **Database access**: ```bash sudo -u www-data sqlite3 /var/lib/ginxsom/ginxsom.db "SELECT COUNT(*) FROM blobs;" ``` 6. **Blob storage**: ```bash ls -la /var/www/blobs/ | head ``` ## Monitoring Key metrics to monitor: - Binary size: `du -h /usr/local/bin/ginxsom/ginxsom-fcgi` - Database size: `du -h /var/lib/ginxsom/ginxsom.db` - Blob storage: `du -sh /var/www/blobs/` - Process status: `systemctl status ginxsom` (if using systemd) - Socket status: `ls -la /tmp/ginxsom-fcgi.sock` ## Backup Strategy ### Database Backups ```bash # Daily backup sudo -u www-data sqlite3 /var/lib/ginxsom/ginxsom.db ".backup /var/lib/ginxsom/backups/ginxsom-$(date +%Y%m%d).db" # Keep last 7 days find /var/lib/ginxsom/backups/ -name "ginxsom-*.db" -mtime +7 -delete ``` ### Blob Backups ```bash # Sync to backup location rsync -av /var/www/blobs/ /backup/ginxsom-blobs/ ``` ## Conclusion The static MUSL binary deployment provides: - ✅ Simpler deployment process - ✅ Fewer dependencies - ✅ Better security - ✅ Faster updates - ✅ Universal compatibility - ✅ Cleaner organization This architecture follows Linux FHS (Filesystem Hierarchy Standard) best practices and provides a solid foundation for production deployment.