diff --git a/docs/hosting/hetzner.md b/docs/hosting/hetzner.md new file mode 100644 index 000000000..b9693d635 --- /dev/null +++ b/docs/hosting/hetzner.md @@ -0,0 +1,434 @@ +# Deploying Sure on Hetzner Cloud + +This guide will help you deploy Sure on a Hetzner Cloud server with Docker Compose, including SSL certificates, security hardening, and automated backups. + +## Prerequisites + +Before starting, ensure you have: + +- A Hetzner Cloud server (recommended: 4GB RAM, 2 CPU cores minimum) +- A domain name pointing to your server's IP address +- SSH access to your server +- Basic familiarity with Linux command line + +## Step 1: Server Setup and Security + +Connect to your Hetzner server and set up the basic environment: + +```bash +# Connect to your server (replace with your server's IP) +ssh root@YOUR_SERVER_IP + +# Update the system +apt update && apt upgrade -y + +# Install essential packages +apt install -y curl wget git ufw fail2ban + +# Install Docker +curl -fsSL https://get.docker.com -o get-docker.sh +sh get-docker.sh + +# Install Docker Compose +curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose +chmod +x /usr/local/bin/docker-compose + +# Add your user to docker group (replace 'your_username' with your actual username) +# If you are using root, you can skip this step +if [ "$(whoami)" != "root" ]; then + usermod -aG docker "$(whoami)" +fi + +# Configure firewall +ufw allow ssh +ufw allow 80 +ufw allow 443 +ufw --force enable + +# Configure fail2ban for SSH protection +systemctl enable fail2ban +systemctl start fail2ban +``` + +## Step 2: Create Application Directory + +```bash +# Create directory for the application +mkdir -p /opt/sure +cd /opt/sure + +# Download the Docker Compose configuration +curl -o compose.yml https://raw.githubusercontent.com/we-promise/sure/main/compose.example.yml +``` + +## Step 3: Configure Environment Variables + +Create a secure environment configuration: + +```bash +# Create environment file +nano .env +``` + +Add the following content to the `.env` file (replace the values with your own): + +```bash +# Generate a secure secret key +SECRET_KEY_BASE="$(openssl rand -hex 64)" + +# Database configuration +POSTGRES_USER="sure_user" +POSTGRES_PASSWORD="$(openssl rand -base64 32)" +POSTGRES_DB="sure_production" + +# Optional: OpenAI integration (add your API key if you want AI features) +# OPENAI_ACCESS_TOKEN="your_openai_api_key_here" +``` + +**Important Security Notes:** +- Never use the default values from the example file in production +- Keep your `.env` file secure and never commit it to version control +- The `SECRET_KEY_BASE` is critical for Rails security - keep it secret + +## Step 4: Set Up Reverse Proxy with SSL + +We'll use Nginx as a reverse proxy with Let's Encrypt SSL certificates: + +```bash +# Install Nginx and Certbot +apt install -y nginx certbot python3-certbot-nginx + +# Create Nginx configuration for your domain +nano /etc/nginx/sites-available/sure +``` + +Add this Nginx configuration (replace `yourdomain.com` with your actual domain): + +```nginx +server { + listen 80; + server_name yourdomain.com www.yourdomain.com; + + location / { + proxy_pass http://localhost:3000; + 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_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + } +} +``` + +```bash +# Enable the site +ln -s /etc/nginx/sites-available/sure /etc/nginx/sites-enabled/ +rm /etc/nginx/sites-enabled/default + +# Test Nginx configuration +nginx -t + +# Start Nginx +systemctl enable nginx +systemctl start nginx + +# Get SSL certificate +certbot --nginx -d yourdomain.com -d www.yourdomain.com +``` + +## Step 5: Deploy the Application + +Now let's deploy the Sure application: + +```bash +# Navigate to the application directory +cd /opt/sure + +# Pull the latest Docker images +docker compose pull + +# Start the application +docker compose up -d + +# Check if everything is running +docker compose ps + +# View logs to ensure everything started correctly +docker compose logs -f +``` + +## Step 6: Test the Deployment + +Verify your deployment is working: + +```bash +# Check if the application is accessible +curl -I https://yourdomain.com + +# Check Docker container health +docker compose ps +``` + +Now you can: + +1. **Visit your application**: Go to `https://yourdomain.com` in your browser +2. **Create your admin account**: Click "Create your account" on the login page +3. **Set up your first family**: Follow the onboarding process + +## Step 7: Set Up Automated Backups + +Create a backup script to protect your data: + +```bash +# Create backup script +nano /opt/sure/backup.sh +``` + +Add this backup script: + +```bash +#!/bin/bash +BACKUP_DIR="/opt/sure/backups" +DATE=$(date +%Y%m%d_%H%M%S) + +# Create backup directory +mkdir -p $BACKUP_DIR + +# Backup database +docker compose exec -T db pg_dump -U sure_user sure_production > $BACKUP_DIR/db_backup_$DATE.sql + +# Backup application data +docker compose exec -T web tar -czf - /rails/storage > $BACKUP_DIR/storage_backup_$DATE.tar.gz + +# Keep only last 7 days of backups +find $BACKUP_DIR -name "*.sql" -mtime +7 -delete +find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete + +echo "Backup completed: $DATE" +``` + +```bash +# Make backup script executable +chmod +x /opt/sure/backup.sh + +# Add to crontab for daily backups at 2 AM +crontab -e +``` + +Add this line to crontab: +```bash +0 2 * * * /opt/sure/backup.sh >> /var/log/sure-backup.log 2>&1 +``` + +## Step 8: Set Up Basic Monitoring + +Create a health check script to monitor your application: + +```bash +# Install htop for system monitoring +apt install -y htop + +# Create a simple health check script +nano /opt/sure/health-check.sh +``` + +Add this health check script: + +```bash +#!/bin/bash +# Check if the application is responding +if curl -f -s https://yourdomain.com > /dev/null; then + echo "$(date): Application is healthy" +else + echo "$(date): Application is down - restarting" + cd /opt/sure + docker compose restart web worker +fi +``` + +```bash +# Make health check executable +chmod +x /opt/sure/health-check.sh + +# Add to crontab to run every 5 minutes +crontab -e +``` + +Add this line: +```bash +*/5 * * * * /opt/sure/health-check.sh >> /var/log/sure-health.log 2>&1 +``` + +## Maintenance Commands + +Here are the essential commands for maintaining your deployment: + +### Update the application: +```bash +cd /opt/sure +docker compose pull +docker compose up --no-deps -d web worker +``` + +### View logs: +```bash +# All services +docker compose logs -f + +# Specific service +docker compose logs -f web +docker compose logs -f worker +docker compose logs -f db +``` + +### Restart services: +```bash +# Restart all services +docker compose restart + +# Restart specific service +docker compose restart web +``` + +### Check system resources: +```bash +# Docker resource usage +docker stats + +# System resources +htop +df -h +``` + +### Restore from backup: +```bash +# Restore database +docker compose exec -T db psql -U sure_user sure_production < /opt/sure/backups/db_backup_YYYYMMDD_HHMMSS.sql + +# Restore application data +docker compose exec -T web tar -xzf /opt/sure/backups/storage_backup_YYYYMMDD_HHMMSS.tar.gz -C / +``` + +## Security Features + +Your deployment includes several security measures: + +1. **Firewall**: Only ports 22 (SSH), 80 (HTTP), and 443 (HTTPS) are open +2. **Fail2ban**: Protects against brute force attacks on SSH +3. **SSL/TLS**: Automatic HTTPS with Let's Encrypt certificates +4. **Environment variables**: Sensitive data stored securely in `.env` file +5. **Non-root containers**: Application runs as non-root user +6. **Regular updates**: Keep your system and Docker images updated + +## Troubleshooting + +### Common Issues and Solutions + +**Application won't start:** +```bash +# Check logs for errors +docker compose logs -f + +# Check if ports are available +netstat -tulpn | grep :3000 +``` + +**Database connection issues:** +```bash +# Check database container +docker compose logs db + +# Test database connection +docker compose exec db psql -U sure_user -d sure_production -c "SELECT 1;" +``` + +**SSL certificate issues:** +```bash +# Renew certificates +certbot renew --dry-run + +# Check certificate status +certbot certificates +``` + +**Out of disk space:** +```bash +# Check disk usage +df -h + +# Clean up Docker images +docker system prune -a + +# Clean up old backups +find /opt/sure/backups -name "*.sql" -mtime +7 -delete +``` + +**Application is slow:** +```bash +# Check system resources +htop +docker stats + +# Check if containers are healthy +docker compose ps +``` + +## Performance Optimization + +For better performance on Hetzner Cloud: + +1. **Use SSD storage**: Hetzner Cloud provides NVMe SSD storage by default +2. **Choose appropriate server size**: + - Minimum: CX21 (2 vCPU, 4GB RAM) + - Recommended: CX31 (2 vCPU, 8GB RAM) for multiple users +3. **Enable swap** (if needed): + ```bash + fallocate -l 2G /swapfile + chmod 600 /swapfile + mkswap /swapfile + swapon /swapfile + echo '/swapfile none swap sw 0 0' >> /etc/fstab + ``` + +## Backup Strategy + +Your backup strategy includes: + +1. **Daily automated backups** of database and application data +2. **7-day retention** of backup files +3. **Separate backup directory** at `/opt/sure/backups` +4. **Logging** of backup operations + +Consider additional backup options: +- **Off-site backups**: Copy backups to external storage (AWS S3, Google Cloud, etc.) +- **Database replication**: Set up PostgreSQL streaming replication +- **Snapshot backups**: Use Hetzner Cloud snapshots for full system backups + +## Next Steps + +After successful deployment: + +1. **Create your admin account** at `https://yourdomain.com` +2. **Set up your first family** in the application +3. **Configure bank connections** (if using Plaid integration) +4. **Set up additional users** as needed +5. **Monitor your deployment** using the health check logs + +## Support + +If you encounter issues: + +1. Check the [troubleshooting section](#troubleshooting) above +2. Review the application logs: `docker compose logs -f` +3. Check system resources: `htop` and `df -h` +4. Open a discussion in our [GitHub repository](https://github.com/we-promise/sure/discussions) + +## Security Reminders + +- Keep your server updated: `apt update && apt upgrade` +- Monitor your logs regularly: `/var/log/sure-backup.log` and `/var/log/sure-health.log` +- Use strong passwords for all accounts +- Consider setting up SSH key authentication instead of password authentication +- Regularly review your firewall rules: `ufw status` +- Monitor your SSL certificate expiration: `certbot certificates`