Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Production Setup

Deploy BWS in production with security, performance, and reliability best practices.

Quick Production Setup

1. Install BWS

# Install from crates.io
cargo install bws-web-server

# Or use Docker
docker pull ghcr.io/benliao/bws:latest

2. Create Production Configuration

[server]
name = "BWS Production"

# Main HTTPS site
[[sites]]
name = "main"
hostname = "example.com"
port = 443
static_dir = "/var/www/html"
default = true

[sites.ssl]
enabled = true
auto_cert = true
domains = ["example.com", "www.example.com"]

[sites.ssl.acme]
enabled = true
email = "admin@example.com"
staging = false

[sites.headers]
"Strict-Transport-Security" = "max-age=31536000"
"X-Frame-Options" = "DENY"
"X-Content-Type-Options" = "nosniff"

# Management API
[management]
enabled = true
port = 7654
api_key = "secure-random-key-here"

# Performance tuning
[performance]
worker_threads = 8
max_connections = 2000

# Security
[security]
hide_server_header = true
max_request_size = "50MB"

# Logging
[logging]
level = "info"
log_requests = true

3. System Setup

# Create user and directories
sudo useradd -r -s /bin/false bws
sudo mkdir -p /var/www/html /var/log/bws /etc/bws
sudo chown -R bws:bws /var/www /var/log/bws

# Copy configuration
sudo cp config.toml /etc/bws/

# Set permissions
sudo chmod 600 /etc/bws/config.toml
sudo chown bws:bws /etc/bws/config.toml

Systemd Service

Create Service File

# /etc/systemd/system/bws.service
[Unit]
Description=BWS Web Server
After=network.target
Wants=network.target

[Service]
Type=forking
User=bws
Group=bws
ExecStart=/usr/local/bin/bws --config /etc/bws/config.toml --daemon
ExecReload=/bin/kill -HUP $MAINPID
PIDFile=/var/run/bws.pid
Restart=always
RestartSec=5
LimitNOFILE=65535

# Security
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/www /var/log/bws /var/run

[Install]
WantedBy=multi-user.target

Service Management

# Enable and start service
sudo systemctl enable bws
sudo systemctl start bws

# Check status
sudo systemctl status bws

# View logs
sudo journalctl -u bws -f

# Reload configuration
sudo systemctl reload bws

Docker Production Deployment

Docker Compose

# docker-compose.prod.yml
version: '3.8'

services:
  bws:
    image: ghcr.io/benliao/bws:v0.3.5
    container_name: bws-prod
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./config.toml:/app/config.toml:ro
      - ./static:/app/static:ro
      - ./acme-challenges:/app/acme-challenges
      - ./logs:/app/logs
    environment:
      - BWS_LOG_LEVEL=info
    networks:
      - bws-network
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/api/health"]
      interval: 30s
      timeout: 10s
      retries: 3

networks:
  bws-network:
    driver: bridge

Deploy with Docker

# Start production stack
docker-compose -f docker-compose.prod.yml up -d

# View logs
docker-compose -f docker-compose.prod.yml logs -f

# Update deployment
docker-compose -f docker-compose.prod.yml pull
docker-compose -f docker-compose.prod.yml up -d

Reverse Proxy Setup

Nginx Frontend (Optional)

# /etc/nginx/sites-available/bws
upstream bws_backend {
    server 127.0.0.1:8080;
    keepalive 32;
}

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
        proxy_pass http://bws_backend;
        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;
    }
}

Security

Firewall Configuration

# UFW setup
sudo ufw allow 22/tcp      # SSH
sudo ufw allow 80/tcp      # HTTP
sudo ufw allow 443/tcp     # HTTPS
sudo ufw enable

# Restrict management API
sudo ufw allow from 127.0.0.1 to any port 7654

SSL/TLS Security

# Strong SSL configuration
[sites.ssl]
enabled = true
auto_cert = true
min_tls_version = "1.2"

[sites.headers]
"Strict-Transport-Security" = "max-age=31536000; includeSubDomains; preload"
"Content-Security-Policy" = "default-src 'self'"
"X-Frame-Options" = "DENY"
"X-Content-Type-Options" = "nosniff"
"Referrer-Policy" = "strict-origin-when-cross-origin"

Monitoring

Health Checks

# Basic health check
curl -f http://localhost/api/health

# Detailed health information
curl http://localhost/api/health/detailed

# Check SSL certificate
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates

Log Monitoring

# Monitor access logs
tail -f /var/log/bws/access.log

# Monitor error logs
tail -f /var/log/bws/error.log

# System resource monitoring
htop
iostat -x 1

Alerting Setup

# Check certificate expiration
#!/bin/bash
# check-ssl.sh
DOMAIN="example.com"
EXPIRY=$(echo | openssl s_client -connect $DOMAIN:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_DATE=$(date -d "$EXPIRY" +%s)
CURRENT_DATE=$(date +%s)
DAYS_UNTIL_EXPIRY=$(( ($EXPIRY_DATE - $CURRENT_DATE) / 86400 ))

if [ $DAYS_UNTIL_EXPIRY -lt 30 ]; then
    echo "SSL certificate for $DOMAIN expires in $DAYS_UNTIL_EXPIRY days!"
    # Send alert (email, Slack, etc.)
fi

Performance Tuning

System Limits

# /etc/security/limits.conf
bws soft nofile 65535
bws hard nofile 65535

# /etc/sysctl.conf
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.core.netdev_max_backlog = 5000

BWS Configuration

[performance]
worker_threads = 16              # 2x CPU cores
max_connections = 10000          # Per worker
keep_alive_timeout = 75          # Seconds
request_timeout = 30             # Seconds
max_header_size = "16KB"

Backup and Recovery

Configuration Backup

# Backup script
#!/bin/bash
BACKUP_DIR="/backups/bws/$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR

# Backup configuration
cp /etc/bws/config.toml $BACKUP_DIR/
cp -r /var/www $BACKUP_DIR/
cp -r /etc/letsencrypt $BACKUP_DIR/

# Create archive
tar -czf $BACKUP_DIR.tar.gz $BACKUP_DIR
rm -rf $BACKUP_DIR

Recovery Procedure

# Restore from backup
tar -xzf /backups/bws/20250827.tar.gz -C /

# Restore permissions
sudo chown -R bws:bws /var/www /etc/bws
sudo chmod 600 /etc/bws/config.toml

# Restart service
sudo systemctl restart bws

Troubleshooting

Common Issues

# Check BWS status
sudo systemctl status bws

# Validate configuration
bws --config /etc/bws/config.toml --dry-run

# Check logs
sudo journalctl -u bws --since "1 hour ago"

# Test configuration reload
curl -X POST http://127.0.0.1:7654/api/config/reload \
  -H "X-API-Key: your-api-key"

# Check process tree
pstree -p $(pgrep -f bws)

Performance Debugging

# Check resource usage
top -p $(pgrep bws)

# Network connections
ss -tulpn | grep bws

# File descriptors
lsof -p $(pgrep bws) | wc -l

Updates and Maintenance

Rolling Updates

# Download new version
cargo install bws-web-server --force

# Validate new binary
bws --version
bws --config /etc/bws/config.toml --dry-run

# Hot reload (zero downtime)
sudo systemctl reload bws

# Or restart if needed
sudo systemctl restart bws

Maintenance Window

# Graceful shutdown
sudo systemctl stop bws

# Perform maintenance
# - Update system packages
# - Update BWS configuration
# - Clean log files

# Start service
sudo systemctl start bws

# Verify operation
curl -f http://localhost/api/health