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

Multi-Site Setup

BWS hosts multiple websites with individual configurations on different ports or hostnames.

Basic Multi-Site Configuration

[server]
name = "BWS Multi-Site Server"

# Main HTTP site
[[sites]]
name = "main"
hostname = "localhost"
port = 8080
static_dir = "static"
default = true

[sites.headers]
"X-Site-Name" = "Main Website"

# HTTPS blog site
[[sites]]
name = "blog"
hostname = "blog.localhost"
port = 8443
static_dir = "static-blog"

[sites.ssl]
enabled = true
auto_cert = true
domains = ["blog.localhost"]

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

# API proxy site
[[sites]]
name = "api"
hostname = "api.localhost"
port = 8080
static_dir = "static"

[sites.proxy]
enabled = true

[[sites.proxy.upstreams]]
name = "backend"
url = "http://127.0.0.1:3001"

[[sites.proxy.routes]]
path = "/v1/"
upstream = "backend"

Setup Multi-Site Content

Create directories and content for each site:

# Create directories
mkdir -p static static-blog acme-challenges

# Main site content
cat > static/index.html << 'EOF'
<h1>Main Website</h1>
<p>Welcome to the main site</p>
<a href="https://blog.localhost:8443">Visit Blog</a>
EOF

# Blog content
cat > static-blog/index.html << 'EOF'
<h1>Blog Site</h1>
<p>This is the blog running on HTTPS</p>
<a href="http://localhost:8080">Back to Main</a>
EOF

Virtual Hosting (Same Port)

Host multiple sites on the same port using hostname routing:

[server]
name = "Virtual Hosting Server"

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

# Blog site (same port, different hostname)
[[sites]]
name = "blog"
hostname = "blog.example.com"
port = 80
static_dir = "sites/blog"

# API site (same port, different hostname)
[[sites]]
name = "api"
hostname = "api.example.com"
port = 80
static_dir = "sites/api"

Testing Virtual Hosting

Add entries to /etc/hosts for local testing:

# Add to /etc/hosts
echo "127.0.0.1 www.example.com blog.example.com api.example.com" | sudo tee -a /etc/hosts

Test with curl:

curl -H "Host: www.example.com" http://localhost/
curl -H "Host: blog.example.com" http://localhost/
curl -H "Host: api.example.com" http://localhost/

Multi-Port Configuration

Run different services on different ports:

# HTTP on port 80
[[sites]]
name = "web"
hostname = "example.com"
port = 80
static_dir = "web"

# HTTPS on port 443
[[sites]]
name = "secure"
hostname = "example.com"
port = 443
static_dir = "web"

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

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

# API on port 8080
[[sites]]
name = "api"
hostname = "api.example.com"
port = 8080
static_dir = "api"

# Admin panel on port 9000
[[sites]]
name = "admin"
hostname = "admin.example.com"
port = 9000
static_dir = "admin"

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

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

Site-Specific Configuration

Each site can have unique settings:

Headers

# Different headers per site
[[sites]]
name = "api"
hostname = "api.example.com"
port = 80
static_dir = "api"

[sites.headers]
"Access-Control-Allow-Origin" = "*"
"X-API-Version" = "v1"

[[sites]]
name = "blog"
hostname = "blog.example.com"
port = 80
static_dir = "blog"

[sites.headers]
"X-Content-Type" = "blog"
"Cache-Control" = "public, max-age=3600"

Security Settings

# Secure admin site
[[sites]]
name = "admin"
hostname = "admin.example.com"
port = 443
static_dir = "admin"

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

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

Start Multi-Site Server

# Validate configuration
bws --config multi-site.toml --dry-run

# Start server
bws --config multi-site.toml

Testing Multiple Sites

# Test different sites
curl http://localhost:8080/                    # Main site
curl https://blog.localhost:8443/              # Blog site  
curl http://api.localhost:8080/v1/health       # API site

# Check site information
curl http://localhost:8080/api/sites

# Test virtual hosting
curl -H "Host: www.example.com" http://localhost/
curl -H "Host: blog.example.com" http://localhost/

Management

Hot Reload

Update configuration without stopping the server:

# Edit configuration file
nano multi-site.toml

# Reload configuration
curl -X POST http://127.0.0.1:7654/api/config/reload

Monitoring

# Check all sites health
curl http://localhost:8080/api/health

# Monitor logs for all sites
tail -f /var/log/bws.log | grep -E "(site:|error:|ssl:)"

Production Deployment

Directory Structure

/var/www/
├── sites/
│   ├── main/
│   ├── blog/
│   ├── api/
│   └── admin/
├── certs/
├── acme-challenges/
└── config/
    └── multi-site.toml

Service Configuration

[server]
name = "Production Multi-Site"

[[sites]]
name = "main"
hostname = "example.com"
port = 443
static_dir = "/var/www/sites/main"
default = true

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

[sites.ssl.acme]
enabled = true
email = "admin@example.com"
challenge_dir = "/var/www/acme-challenges"

[[sites]]
name = "api"
hostname = "api.example.com"
port = 443
static_dir = "/var/www/sites/api"

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

[sites.ssl.acme]
enabled = true
email = "admin@example.com"
challenge_dir = "/var/www/acme-challenges"

Firewall Setup

# Allow HTTP and HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Allow management API (localhost only)
sudo ufw allow from 127.0.0.1 to any port 7654