docs refactor
All checks were successful
All checks were successful
This commit is contained in:
810
docs/content/deployment/production.md
Normal file
810
docs/content/deployment/production.md
Normal file
@ -0,0 +1,810 @@
|
||||
---
|
||||
version: "1.0"
|
||||
date: "2025-01-15"
|
||||
author: "DWS Foldsite Team"
|
||||
title: "Production Deployment"
|
||||
description: "Deploying Foldsite for production use"
|
||||
summary: "Complete guide to deploying Foldsite in production - from VPS servers to static hosting, with security, performance, and reliability best practices."
|
||||
quick_tips:
|
||||
- "Use Gunicorn with multiple workers for dynamic deployments"
|
||||
- "Static export is fastest and cheapest for sites that don't change frequently"
|
||||
- "Always use HTTPS in production with proper SSL certificates"
|
||||
---
|
||||
|
||||
# Production Deployment
|
||||
|
||||
Deploy Foldsite to serve real traffic with reliability, security, and performance.
|
||||
|
||||
## Deployment Options
|
||||
|
||||
### Option 1: Dynamic Server (Python)
|
||||
|
||||
**Best for:**
|
||||
- Frequently updated content
|
||||
- Sites needing template helpers in real-time
|
||||
- Admin file browser interface
|
||||
- Dynamic content generation
|
||||
|
||||
**Characteristics:**
|
||||
- Runs Python/Gunicorn server
|
||||
- Content updates appear immediately
|
||||
- Template helpers work dynamically
|
||||
- Requires server with Python
|
||||
|
||||
**Hosting:** VPS, dedicated server, PaaS platforms
|
||||
|
||||
### Option 2: Static Export
|
||||
|
||||
**Best for:**
|
||||
- Infrequently updated sites
|
||||
- Maximum performance
|
||||
- Minimal cost
|
||||
- CDN delivery
|
||||
|
||||
**Characteristics:**
|
||||
- Pre-rendered HTML files
|
||||
- Blazing fast delivery
|
||||
- Can host anywhere (GitHub Pages, Netlify, S3)
|
||||
- Rebuild required for updates
|
||||
|
||||
**Hosting:** Static hosts, CDN, object storage
|
||||
|
||||
## Dynamic Server Deployment
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Linux server (Ubuntu 20.04+ recommended)
|
||||
- Python 3.10+
|
||||
- Domain name
|
||||
- SSH access
|
||||
|
||||
### Step 1: Server Setup
|
||||
|
||||
**Update system:**
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt upgrade -y
|
||||
```
|
||||
|
||||
**Install dependencies:**
|
||||
```bash
|
||||
# Python and pip
|
||||
sudo apt install -y python3.10 python3-pip python3-venv
|
||||
|
||||
# Build tools
|
||||
sudo apt install -y build-essential python3-dev
|
||||
|
||||
# Nginx
|
||||
sudo apt install -y nginx
|
||||
|
||||
# Certbot for SSL
|
||||
sudo apt install -y certbot python3-certbot-nginx
|
||||
```
|
||||
|
||||
### Step 2: Deploy Foldsite
|
||||
|
||||
**Create user:**
|
||||
```bash
|
||||
sudo useradd -m -s /bin/bash foldsite
|
||||
sudo su - foldsite
|
||||
```
|
||||
|
||||
**Clone and setup:**
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone https://github.com/DWSresearch/foldsite.git
|
||||
cd foldsite
|
||||
|
||||
# Create virtual environment
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
# Install dependencies
|
||||
pip install -r requirements.txt
|
||||
pip install gunicorn # Production WSGI server
|
||||
```
|
||||
|
||||
**Setup your content:**
|
||||
```bash
|
||||
# Create site structure
|
||||
mkdir -p ~/site/content
|
||||
mkdir -p ~/site/templates
|
||||
mkdir -p ~/site/styles
|
||||
|
||||
# Copy your content
|
||||
# (upload via SCP, rsync, or git)
|
||||
```
|
||||
|
||||
**Create production config:**
|
||||
```bash
|
||||
vim ~/foldsite/production-config.toml
|
||||
```
|
||||
|
||||
```toml
|
||||
[paths]
|
||||
content_dir = "/home/foldsite/site/content"
|
||||
templates_dir = "/home/foldsite/site/templates"
|
||||
styles_dir = "/home/foldsite/site/styles"
|
||||
|
||||
[server]
|
||||
listen_address = "127.0.0.1" # Only accept local connections
|
||||
listen_port = 8081
|
||||
admin_browser = false # Disable for security
|
||||
max_threads = 8 # Adjust based on server
|
||||
debug = false # Never enable in production
|
||||
access_log = true
|
||||
```
|
||||
|
||||
### Step 3: Systemd Service
|
||||
|
||||
Create service file:
|
||||
|
||||
```bash
|
||||
sudo vim /etc/systemd/system/foldsite.service
|
||||
```
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Foldsite Web Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=foldsite
|
||||
Group=foldsite
|
||||
WorkingDirectory=/home/foldsite/foldsite
|
||||
Environment="PATH=/home/foldsite/foldsite/venv/bin"
|
||||
ExecStart=/home/foldsite/foldsite/venv/bin/gunicorn \
|
||||
--workers 4 \
|
||||
--bind 127.0.0.1:8081 \
|
||||
--access-logfile /var/log/foldsite/access.log \
|
||||
--error-logfile /var/log/foldsite/error.log \
|
||||
--config /home/foldsite/foldsite/production-config.toml \
|
||||
main:app
|
||||
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
**Create log directory:**
|
||||
```bash
|
||||
sudo mkdir -p /var/log/foldsite
|
||||
sudo chown foldsite:foldsite /var/log/foldsite
|
||||
```
|
||||
|
||||
**Enable and start service:**
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable foldsite
|
||||
sudo systemctl start foldsite
|
||||
|
||||
# Check status
|
||||
sudo systemctl status foldsite
|
||||
```
|
||||
|
||||
### Step 4: Nginx Reverse Proxy
|
||||
|
||||
**Create Nginx config:**
|
||||
```bash
|
||||
sudo vim /etc/nginx/sites-available/foldsite
|
||||
```
|
||||
|
||||
```nginx
|
||||
upstream foldsite {
|
||||
server 127.0.0.1:8081;
|
||||
keepalive 32;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name your-domain.com www.your-domain.com;
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "no-referrer-when-downgrade" always;
|
||||
|
||||
# Logs
|
||||
access_log /var/log/nginx/foldsite-access.log;
|
||||
error_log /var/log/nginx/foldsite-error.log;
|
||||
|
||||
# Max upload size
|
||||
client_max_body_size 10M;
|
||||
|
||||
# Proxy to Foldsite
|
||||
location / {
|
||||
proxy_pass http://foldsite;
|
||||
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;
|
||||
|
||||
# Timeouts
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
# Cache static assets
|
||||
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
|
||||
proxy_pass http://foldsite;
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, immutable";
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# Security: deny access to hidden files
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Enable site:**
|
||||
```bash
|
||||
sudo ln -s /etc/nginx/sites-available/foldsite /etc/nginx/sites-enabled/
|
||||
sudo nginx -t # Test configuration
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
### Step 5: SSL Certificate
|
||||
|
||||
**Get certificate with Certbot:**
|
||||
```bash
|
||||
sudo certbot --nginx -d your-domain.com -d www.your-domain.com
|
||||
```
|
||||
|
||||
Follow prompts. Certbot will:
|
||||
- Obtain certificate from Let's Encrypt
|
||||
- Modify Nginx config for HTTPS
|
||||
- Setup auto-renewal
|
||||
|
||||
**Verify auto-renewal:**
|
||||
```bash
|
||||
sudo certbot renew --dry-run
|
||||
```
|
||||
|
||||
**Final Nginx config (with SSL):**
|
||||
Certbot updates your config to include:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name your-domain.com www.your-domain.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
||||
# ... rest of config
|
||||
}
|
||||
|
||||
# Redirect HTTP to HTTPS
|
||||
server {
|
||||
listen 80;
|
||||
server_name your-domain.com www.your-domain.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
```
|
||||
|
||||
### Step 6: Firewall
|
||||
|
||||
**Configure UFW:**
|
||||
```bash
|
||||
sudo ufw allow OpenSSH
|
||||
sudo ufw allow 'Nginx Full'
|
||||
sudo ufw enable
|
||||
sudo ufw status
|
||||
```
|
||||
|
||||
### Verification
|
||||
|
||||
Visit your domain:
|
||||
```
|
||||
https://your-domain.com
|
||||
```
|
||||
|
||||
Should see your Foldsite with valid SSL!
|
||||
|
||||
## Static Export Deployment
|
||||
|
||||
### Generate Static Files
|
||||
|
||||
*Note: Static export functionality may need to be implemented or use a static site generator mode*
|
||||
|
||||
**Conceptual approach:**
|
||||
|
||||
```python
|
||||
# export.py
|
||||
import os
|
||||
from pathlib import Path
|
||||
from src.rendering.renderer import render_page
|
||||
from src.config.config import Configuration
|
||||
|
||||
def export_static(config_path, output_dir):
|
||||
"""Export all pages to static HTML"""
|
||||
config = Configuration(config_path)
|
||||
config.load_config()
|
||||
|
||||
output = Path(output_dir)
|
||||
output.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Walk content directory
|
||||
for content_file in config.content_dir.rglob('*'):
|
||||
if content_file.is_file() and not content_file.name.startswith('___'):
|
||||
# Generate output path
|
||||
rel_path = content_file.relative_to(config.content_dir)
|
||||
out_path = output / rel_path.with_suffix('.html')
|
||||
out_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Render and save
|
||||
html = render_page(
|
||||
content_file,
|
||||
base_path=config.content_dir,
|
||||
template_path=config.templates_dir,
|
||||
style_path=config.styles_dir
|
||||
)
|
||||
|
||||
with open(out_path, 'w') as f:
|
||||
f.write(html)
|
||||
|
||||
# Copy styles
|
||||
import shutil
|
||||
shutil.copytree(config.styles_dir, output / 'styles')
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
export_static(sys.argv[1], sys.argv[2])
|
||||
```
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
python export.py config.toml ./dist
|
||||
```
|
||||
|
||||
### Deploy Static Files
|
||||
|
||||
#### GitHub Pages
|
||||
|
||||
```bash
|
||||
# Export to docs/
|
||||
python export.py config.toml ./docs
|
||||
|
||||
# Commit and push
|
||||
git add docs/
|
||||
git commit -m "Update site"
|
||||
git push
|
||||
|
||||
# Enable Pages in GitHub repo settings
|
||||
# Source: docs/ folder
|
||||
```
|
||||
|
||||
#### Netlify
|
||||
|
||||
```bash
|
||||
# Export
|
||||
python export.py config.toml ./dist
|
||||
|
||||
# Install Netlify CLI
|
||||
npm install -g netlify-cli
|
||||
|
||||
# Deploy
|
||||
netlify deploy --prod --dir=dist
|
||||
```
|
||||
|
||||
**Or use continuous deployment:**
|
||||
|
||||
```yaml
|
||||
# netlify.toml
|
||||
[build]
|
||||
command = "pip install -r requirements.txt && python export.py config.toml dist"
|
||||
publish = "dist"
|
||||
```
|
||||
|
||||
#### AWS S3 + CloudFront
|
||||
|
||||
```bash
|
||||
# Export
|
||||
python export.py config.toml ./dist
|
||||
|
||||
# Sync to S3
|
||||
aws s3 sync ./dist s3://your-bucket-name --delete
|
||||
|
||||
# Invalidate CloudFront cache
|
||||
aws cloudfront create-invalidation --distribution-id YOUR_DIST_ID --paths "/*"
|
||||
```
|
||||
|
||||
#### Vercel
|
||||
|
||||
```bash
|
||||
# Export
|
||||
python export.py config.toml ./dist
|
||||
|
||||
# Deploy
|
||||
vercel --prod ./dist
|
||||
```
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### Nginx Caching
|
||||
|
||||
Add to Nginx config:
|
||||
|
||||
```nginx
|
||||
# Define cache path
|
||||
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=foldsite_cache:10m max_size=1g inactive=60m use_temp_path=off;
|
||||
|
||||
server {
|
||||
# ...
|
||||
|
||||
location / {
|
||||
proxy_cache foldsite_cache;
|
||||
proxy_cache_valid 200 10m;
|
||||
proxy_cache_valid 404 1m;
|
||||
proxy_cache_bypass $cookie_session;
|
||||
proxy_no_cache $cookie_session;
|
||||
add_header X-Cache-Status $upstream_cache_status;
|
||||
|
||||
proxy_pass http://foldsite;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Gzip Compression
|
||||
|
||||
```nginx
|
||||
# In /etc/nginx/nginx.conf
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json;
|
||||
```
|
||||
|
||||
### Image Optimization
|
||||
|
||||
Foldsite automatically generates thumbnails, but optimize source images:
|
||||
|
||||
```bash
|
||||
# Install optimization tools
|
||||
sudo apt install jpegoptim optipng
|
||||
|
||||
# Optimize JPEGs
|
||||
find content/ -name "*.jpg" -exec jpegoptim --strip-all {} \;
|
||||
|
||||
# Optimize PNGs
|
||||
find content/ -name "*.png" -exec optipng -o2 {} \;
|
||||
```
|
||||
|
||||
### CDN Integration
|
||||
|
||||
Use CDN for static assets:
|
||||
|
||||
```nginx
|
||||
# Separate static assets
|
||||
location /styles/ {
|
||||
alias /home/foldsite/site/styles/;
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
location /download/ {
|
||||
# Proxy to Foldsite for thumbnails
|
||||
proxy_pass http://foldsite;
|
||||
expires 30d;
|
||||
}
|
||||
```
|
||||
|
||||
Then point DNS for `static.yourdomain.com` to CDN origin.
|
||||
|
||||
## Monitoring & Logging
|
||||
|
||||
### Application Logs
|
||||
|
||||
**View logs:**
|
||||
```bash
|
||||
# Systemd logs
|
||||
sudo journalctl -u foldsite -f
|
||||
|
||||
# Application logs
|
||||
tail -f /var/log/foldsite/error.log
|
||||
tail -f /var/log/foldsite/access.log
|
||||
```
|
||||
|
||||
### Nginx Logs
|
||||
|
||||
```bash
|
||||
tail -f /var/log/nginx/foldsite-access.log
|
||||
tail -f /var/log/nginx/foldsite-error.log
|
||||
```
|
||||
|
||||
### Log Rotation
|
||||
|
||||
Create `/etc/logrotate.d/foldsite`:
|
||||
|
||||
```
|
||||
/var/log/foldsite/*.log {
|
||||
daily
|
||||
missingok
|
||||
rotate 14
|
||||
compress
|
||||
delaycompress
|
||||
notifempty
|
||||
create 0640 foldsite foldsite
|
||||
sharedscripts
|
||||
postrotate
|
||||
systemctl reload foldsite
|
||||
endscript
|
||||
}
|
||||
```
|
||||
|
||||
### Monitoring Tools
|
||||
|
||||
**Install basic monitoring:**
|
||||
```bash
|
||||
# Netdata (system monitoring)
|
||||
bash <(curl -Ss https://my-netdata.io/kickstart.sh)
|
||||
|
||||
# Access at http://your-server:19999
|
||||
```
|
||||
|
||||
**Check application health:**
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# health-check.sh
|
||||
response=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8081/)
|
||||
|
||||
if [ $response -eq 200 ]; then
|
||||
echo "Foldsite is healthy"
|
||||
exit 0
|
||||
else
|
||||
echo "Foldsite is down (HTTP $response)"
|
||||
systemctl restart foldsite
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
Run via cron:
|
||||
```bash
|
||||
*/5 * * * * /usr/local/bin/health-check.sh >> /var/log/foldsite/health.log 2>&1
|
||||
```
|
||||
|
||||
## Backup Strategy
|
||||
|
||||
### Content Backup
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# backup.sh
|
||||
BACKUP_DIR="/backups/foldsite"
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
|
||||
mkdir -p $BACKUP_DIR
|
||||
|
||||
# Backup content, templates, styles
|
||||
tar czf $BACKUP_DIR/site-$DATE.tar.gz \
|
||||
/home/foldsite/site/
|
||||
|
||||
# Keep only last 30 days
|
||||
find $BACKUP_DIR -name "site-*.tar.gz" -mtime +30 -delete
|
||||
|
||||
echo "Backup completed: site-$DATE.tar.gz"
|
||||
```
|
||||
|
||||
**Run daily via cron:**
|
||||
```bash
|
||||
0 2 * * * /usr/local/bin/backup.sh
|
||||
```
|
||||
|
||||
### Remote Backup
|
||||
|
||||
```bash
|
||||
# Sync to remote server
|
||||
rsync -avz /home/foldsite/site/ user@backup-server:/backups/foldsite/
|
||||
|
||||
# Or sync to S3
|
||||
aws s3 sync /home/foldsite/site/ s3://your-backup-bucket/foldsite/
|
||||
```
|
||||
|
||||
## Updating Foldsite
|
||||
|
||||
### Update Process
|
||||
|
||||
```bash
|
||||
# As foldsite user
|
||||
cd ~/foldsite
|
||||
|
||||
# Pull latest code
|
||||
git pull
|
||||
|
||||
# Activate venv
|
||||
source venv/bin/activate
|
||||
|
||||
# Update dependencies
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Restart service
|
||||
sudo systemctl restart foldsite
|
||||
|
||||
# Check logs
|
||||
sudo journalctl -u foldsite -n 50
|
||||
```
|
||||
|
||||
### Zero-Downtime Updates
|
||||
|
||||
Use multiple Gunicorn workers and graceful reloading:
|
||||
|
||||
```bash
|
||||
# Graceful reload (workers restart one by one)
|
||||
sudo systemctl reload foldsite
|
||||
|
||||
# Or send HUP signal to Gunicorn
|
||||
sudo pkill -HUP gunicorn
|
||||
```
|
||||
|
||||
## Security Hardening
|
||||
|
||||
### Disable Directory Listing
|
||||
|
||||
Nginx automatically prevents this, but verify:
|
||||
|
||||
```nginx
|
||||
autoindex off;
|
||||
```
|
||||
|
||||
### Rate Limiting
|
||||
|
||||
Add to Nginx config:
|
||||
|
||||
```nginx
|
||||
limit_req_zone $binary_remote_addr zone=foldsite_limit:10m rate=10r/s;
|
||||
|
||||
server {
|
||||
location / {
|
||||
limit_req zone=foldsite_limit burst=20 nodelay;
|
||||
# ... rest of config
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Fail2ban
|
||||
|
||||
Protect against brute force:
|
||||
|
||||
```bash
|
||||
sudo apt install fail2ban
|
||||
|
||||
# Create /etc/fail2ban/jail.local
|
||||
[nginx-foldsite]
|
||||
enabled = true
|
||||
port = http,https
|
||||
filter = nginx-foldsite
|
||||
logpath = /var/log/nginx/foldsite-access.log
|
||||
maxretry = 5
|
||||
bantime = 3600
|
||||
```
|
||||
|
||||
### Security Headers
|
||||
|
||||
Already in Nginx config, but verify:
|
||||
|
||||
```nginx
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "no-referrer-when-downgrade" always;
|
||||
add_header Content-Security-Policy "default-src 'self' https:; script-src 'self' 'unsafe-inline' https:; style-src 'self' 'unsafe-inline' https:;" always;
|
||||
```
|
||||
|
||||
### File Permissions
|
||||
|
||||
Ensure proper permissions:
|
||||
|
||||
```bash
|
||||
# Content should be readable by foldsite user
|
||||
chmod -R 755 ~/site/content
|
||||
chmod -R 755 ~/site/templates
|
||||
chmod -R 755 ~/site/styles
|
||||
|
||||
# Application should not be writable
|
||||
chmod -R 555 ~/foldsite/src
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Service Won't Start
|
||||
|
||||
```bash
|
||||
# Check logs
|
||||
sudo journalctl -u foldsite -xe
|
||||
|
||||
# Common issues:
|
||||
# - Wrong Python path
|
||||
# - Missing dependencies
|
||||
# - Port already in use
|
||||
# - Permission errors
|
||||
```
|
||||
|
||||
### 502 Bad Gateway
|
||||
|
||||
Nginx can't reach Foldsite:
|
||||
|
||||
```bash
|
||||
# Check if Foldsite is running
|
||||
sudo systemctl status foldsite
|
||||
|
||||
# Check if port is listening
|
||||
sudo netstat -tulpn | grep 8081
|
||||
|
||||
# Check Nginx error log
|
||||
sudo tail /var/log/nginx/error.log
|
||||
```
|
||||
|
||||
### High Memory Usage
|
||||
|
||||
```bash
|
||||
# Check process memory
|
||||
ps aux | grep gunicorn
|
||||
|
||||
# Reduce workers or add swap
|
||||
sudo fallocate -l 2G /swapfile
|
||||
sudo chmod 600 /swapfile
|
||||
sudo mkswap /swapfile
|
||||
sudo swapon /swapfile
|
||||
```
|
||||
|
||||
### Slow Response Times
|
||||
|
||||
```bash
|
||||
# Check Nginx access logs for slow requests
|
||||
sudo tail -f /var/log/nginx/foldsite-access.log
|
||||
|
||||
# Enable query logging in Foldsite
|
||||
# Check for expensive template helpers
|
||||
# Consider caching with Redis/Memcached
|
||||
```
|
||||
|
||||
## Platform-Specific Guides
|
||||
|
||||
### DigitalOcean
|
||||
|
||||
```bash
|
||||
# Create droplet (Ubuntu 22.04)
|
||||
# Follow server setup steps above
|
||||
|
||||
# Use DigitalOcean firewall for security
|
||||
# Enable backups in control panel
|
||||
```
|
||||
|
||||
### AWS EC2
|
||||
|
||||
```bash
|
||||
# Launch Ubuntu instance
|
||||
# Setup security groups (ports 22, 80, 443)
|
||||
# Use Elastic IP for static IP
|
||||
# Consider RDS for database if needed
|
||||
```
|
||||
|
||||
### Hetzner Cloud
|
||||
|
||||
```bash
|
||||
# Create CX11 or larger instance
|
||||
# Follow server setup
|
||||
# Use Hetzner firewall
|
||||
# Consider Hetzner volumes for storage
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- **[Local Development](local-development.md)** - Development workflow
|
||||
- **[Docker Deployment](docker.md)** - Container deployment
|
||||
- **[Support](../support.md)** - Get help
|
||||
|
||||
Your Foldsite is now production-ready! Monitor it regularly, keep it updated, and enjoy your self-hosted corner of the internet.
|
Reference in New Issue
Block a user