* 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
10 KiB
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:
# 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
# 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:
# Create environment file
nano .env
Add the following content to the .env file (replace the values with your own):
# 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
.envfile secure and never commit it to version control - The
SECRET_KEY_BASEis 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:
# 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):
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;
}
}
# 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:
# 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:
# Check if the application is accessible
curl -I https://yourdomain.com
# Check Docker container health
docker compose ps
Now you can:
- Visit your application: Go to
https://yourdomain.comin your browser - Create your admin account: Click "Create your account" on the login page
- Set up your first family: Follow the onboarding process
Step 7: Set Up Automated Backups
Create a backup script to protect your data:
# Create backup script
nano /opt/sure/backup.sh
Add this backup script:
#!/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"
# 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:
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:
# 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:
#!/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
# Make health check executable
chmod +x /opt/sure/health-check.sh
# Add to crontab to run every 5 minutes
crontab -e
Add this line:
*/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:
cd /opt/sure
docker compose pull
docker compose up --no-deps -d web worker
View logs:
# 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:
# Restart all services
docker compose restart
# Restart specific service
docker compose restart web
Check system resources:
# Docker resource usage
docker stats
# System resources
htop
df -h
Restore from backup:
# 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:
- Firewall: Only ports 22 (SSH), 80 (HTTP), and 443 (HTTPS) are open
- Fail2ban: Protects against brute force attacks on SSH
- SSL/TLS: Automatic HTTPS with Let's Encrypt certificates
- Environment variables: Sensitive data stored securely in
.envfile - Non-root containers: Application runs as non-root user
- Regular updates: Keep your system and Docker images updated
Troubleshooting
Common Issues and Solutions
Application won't start:
# Check logs for errors
docker compose logs -f
# Check if ports are available
netstat -tulpn | grep :3000
Database connection issues:
# 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:
# Renew certificates
certbot renew --dry-run
# Check certificate status
certbot certificates
Out of disk space:
# 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:
# Check system resources
htop
docker stats
# Check if containers are healthy
docker compose ps
Performance Optimization
For better performance on Hetzner Cloud:
- Use SSD storage: Hetzner Cloud provides NVMe SSD storage by default
- Choose appropriate server size:
- Minimum: CX21 (2 vCPU, 4GB RAM)
- Recommended: CX31 (2 vCPU, 8GB RAM) for multiple users
- Enable swap (if needed):
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:
- Daily automated backups of database and application data
- 7-day retention of backup files
- Separate backup directory at
/opt/sure/backups - 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:
- Create your admin account at
https://yourdomain.com - Set up your first family in the application
- Configure bank connections (if using Plaid integration)
- Set up additional users as needed
- Monitor your deployment using the health check logs
Support
If you encounter issues:
- Check the troubleshooting section above
- Review the application logs:
docker compose logs -f - Check system resources:
htopanddf -h - Open a discussion in our GitHub repository
Security Reminders
- Keep your server updated:
apt update && apt upgrade - Monitor your logs regularly:
/var/log/sure-backup.logand/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