# Deployment Guide - AI Tools Suite (Privacy Scanner) This guide covers deploying the Privacy Scanner for public testing and validation. ## Quick Start Options | Option | Time | Cost | Best For | |--------|------|------|----------| | **Hetzner VPS** | 30 min | ~€4/month | Production, EU data residency | | **Railway** | 10 min | Free tier available | Quick demos | | **Render** | 15 min | Free tier available | Simplicity | | **Local + Tunnel** | 5 min | Free | Quick testing | --- ## Option 1: Hetzner Cloud (Recommended) Hetzner offers excellent value with EU data centers (good for GDPR compliance). ### Step 1: Create a Hetzner VPS 1. Sign up at [hetzner.com/cloud](https://www.hetzner.com/cloud) 2. Create a new project 3. Add a server: - **Location**: Falkenstein or Nuremberg (Germany) for EU - **Image**: Ubuntu 24.04 - **Type**: CX22 (2 vCPU, 4GB RAM) - €4.51/month - **SSH Key**: Add your public key ### Step 2: Initial Server Setup ```bash # SSH into your server ssh root@YOUR_SERVER_IP # Update system apt update && apt upgrade -y # Install Docker curl -fsSL https://get.docker.com | sh # Install Docker Compose apt install docker-compose-plugin -y # Create app user useradd -m -s /bin/bash appuser usermod -aG docker appuser # Setup firewall ufw allow 22/tcp ufw allow 80/tcp ufw allow 443/tcp ufw enable ``` ### Step 3: Deploy the Application ```bash # Switch to app user su - appuser # Clone your repository (or copy files) git clone YOUR_REPO_URL ai_tools_suite cd ai_tools_suite # Create production .env file cat > .env << 'EOF' # Backend DATABASE_URL=sqlite:///./ai_tools.db SECRET_KEY=$(openssl rand -hex 32) CORS_ORIGINS=https://your-domain.com # Frontend PUBLIC_API_URL=https://your-domain.com ORIGIN=https://your-domain.com EOF # Build and start docker compose up -d --build # Check status docker compose ps docker compose logs -f ``` ### Step 4: Setup Reverse Proxy (Caddy) Caddy provides automatic HTTPS with Let's Encrypt. ```bash # As root apt install -y debian-keyring debian-archive-keyring apt-transport-https curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list apt update apt install caddy # Configure Caddy cat > /etc/caddy/Caddyfile << 'EOF' your-domain.com { # Frontend reverse_proxy localhost:3000 # API routes handle /api/* { reverse_proxy localhost:8000 } # API docs handle /docs { reverse_proxy localhost:8000 } handle /redoc { reverse_proxy localhost:8000 } handle /openapi.json { reverse_proxy localhost:8000 } } EOF # Restart Caddy systemctl restart caddy systemctl enable caddy ``` ### Step 5: Point Your Domain 1. In your DNS provider, add an A record: - **Type**: A - **Name**: @ (or subdomain like `privacy-scanner`) - **Value**: YOUR_SERVER_IP - **TTL**: 300 2. Wait 5-10 minutes for DNS propagation 3. Visit https://your-domain.com - Caddy will automatically get SSL certificates --- ## Option 2: Railway (Quick Deploy) Railway offers a simple deployment experience with a generous free tier. ### Step 1: Setup 1. Go to [railway.app](https://railway.app) and sign in with GitHub 2. Click "New Project" → "Deploy from GitHub repo" 3. Select your repository ### Step 2: Configure Backend 1. Add a new service from your repo 2. Set the root directory to `backend` 3. Add environment variables: ``` PORT=8000 DATABASE_URL=sqlite:///./ai_tools.db CORS_ORIGINS=https://YOUR_FRONTEND_URL ``` ### Step 3: Configure Frontend 1. Add another service from the same repo 2. Set root directory to `frontend` 3. Add environment variables: ``` PUBLIC_API_URL=https://YOUR_BACKEND_URL ORIGIN=https://YOUR_FRONTEND_URL ``` Railway will automatically deploy on every push. --- ## Option 3: Render Render offers easy deployment with free tier. ### render.yaml (add to repo root) ```yaml services: - type: web name: privacy-scanner-api env: docker dockerfilePath: ./backend/Dockerfile dockerContext: ./backend healthCheckPath: /api/v1/health envVars: - key: CORS_ORIGINS sync: false - type: web name: privacy-scanner-frontend env: docker dockerfilePath: ./frontend/Dockerfile dockerContext: ./frontend buildArgs: PUBLIC_API_URL: https://privacy-scanner-api.onrender.com envVars: - key: ORIGIN sync: false ``` 1. Push render.yaml to your repo 2. Go to [render.com](https://render.com) → New Blueprint 3. Connect your repository --- ## Option 4: Local + Tunnel (Quick Testing) For quick demos without deployment: ```bash # Terminal 1: Start the application docker compose up # Terminal 2: Create public tunnel (choose one) # Using cloudflared (recommended) brew install cloudflare/cloudflare/cloudflared cloudflared tunnel --url http://localhost:3000 # OR using localtunnel npx localtunnel --port 3000 # OR using ngrok ngrok http 3000 ``` Share the generated URL with testers. --- ## Testing Your Deployment ### Health Check ```bash # Backend health curl https://your-domain.com/api/v1/health # Expected response: # {"status": "healthy", "version": "0.1.0"} ``` ### Privacy Scanner Test ```bash # Test PII detection curl -X POST https://your-domain.com/api/v1/privacy/scan-text \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "text=Contact john.doe@example.com or call 555-123-4567" ``` ### API Documentation - Swagger UI: https://your-domain.com/docs - ReDoc: https://your-domain.com/redoc --- ## Monitoring & Maintenance ### View Logs ```bash # On Hetzner/VPS docker compose logs -f # Specific service docker compose logs -f backend docker compose logs -f frontend ``` ### Update Deployment ```bash cd ai_tools_suite git pull docker compose down docker compose up -d --build ``` ### Backup Database ```bash docker compose exec backend cp /app/ai_tools.db /app/data/backup_$(date +%Y%m%d).db ``` --- ## Security Checklist - [ ] Change default SECRET_KEY in .env - [ ] Set specific CORS_ORIGINS (not *) - [ ] Enable firewall (ufw) - [ ] Use HTTPS (automatic with Caddy) - [ ] Keep Docker images updated - [ ] Review logs regularly --- ## Troubleshooting ### Container won't start ```bash # Check logs docker compose logs backend # Common issues: # - Port already in use: change ports in docker-compose.yml # - Missing dependencies: rebuild with --no-cache docker compose build --no-cache ``` ### CORS errors 1. Check CORS_ORIGINS includes your frontend URL 2. Include protocol: `https://your-domain.com` not just `your-domain.com` 3. Restart backend after changing env vars ### SSL certificate issues ```bash # Check Caddy status systemctl status caddy journalctl -u caddy -f # Ensure DNS is pointing to server dig your-domain.com ``` --- ## Cost Comparison | Provider | Specs | Monthly Cost | |----------|-------|--------------| | Hetzner CX22 | 2 vCPU, 4GB RAM, 40GB | €4.51 | | Hetzner CX32 | 4 vCPU, 8GB RAM, 80GB | €8.98 | | Railway | Shared, usage-based | $5-20 | | Render | Shared (free tier) | $0-7 | | DigitalOcean | 2 vCPU, 2GB RAM | $18 | **Recommendation**: Start with Hetzner CX22 for production, or Railway/Render free tier for demos.