Files
sure/docs/hosting/hetzner.md
Pedro Camara Junior 3aea1513d1 Add comprehensive Hetzner Cloud deployment guide (#211)
* Add comprehensive Hetzner Cloud deployment guide

* Fix markdown linting issues and backup retention policy

- Add missing language identifiers to fenced code blocks (bash)
- Fix inconsistent backup retention policy (standardize to 7 days)
- Address CodeRabbit review feedback for PR #211
2025-10-21 15:34:44 +02:00

435 lines
10 KiB
Markdown

# 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`