Reverse Proxy Setup
This guide covers setting up FOG Docker behind various reverse proxy solutions for SSL termination and load balancing.
Overview
Using a reverse proxy with FOG Docker provides:
- SSL/TLS termination and certificate management
- Load balancing for multiple FOG instances
- Domain-based routing and virtual hosting
- Security features like rate limiting and DDoS protection
- Centralized logging and monitoring
Supported Reverse Proxies
This guide covers:
- Traefik - Modern reverse proxy with automatic SSL
- Nginx - High-performance web server and reverse proxy
- Apache - Traditional web server with reverse proxy capabilities
- Caddy - Automatic HTTPS and modern web server
FOG Docker Configuration
Environment Variables
Configure FOG Docker for reverse proxy mode:
# Reverse proxy configuration
FOG_WEB_HOST=fog.example.com
FOG_STORAGE_HOST=fog.example.com
FOG_TFTP_HOST=fog.example.com
FOG_WOL_HOST=fog.example.com
# Protocol settings
FOG_HTTP_PROTOCOL=https
FOG_INTERNAL_HTTPS_ENABLED=false # SSL handled by reverse proxy
# Network settings
FOG_WEB_ROOT=/fog
Docker Compose Configuration
services:
fog-server:
image: ghcr.io/88fingerslukee/fog-docker:latest
environment:
- FOG_WEB_HOST=fog.example.com
- FOG_HTTP_PROTOCOL=https
- FOG_INTERNAL_HTTPS_ENABLED=false
- FOG_APACHE_EXPOSED_PORT=8080 # Map to different external port
ports:
- "8080:80" # Internal HTTP only
# ... other configuration
Traefik Configuration
Docker Compose with Traefik
services:
traefik:
image: traefik:v3.0
command:
- --api.dashboard=true
- --api.insecure=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --certificatesresolvers.letsencrypt.acme.tlschallenge=true
- --certificatesresolvers.letsencrypt.acme.email=${LETSENCRYPT_EMAIL}
- --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
ports:
- "80:80"
- "443:443"
- "8080:8080" # Traefik dashboard
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
networks:
- fog-network
fog-server:
image: ghcr.io/88fingerslukee/fog-docker:latest
environment:
- FOG_WEB_HOST=${FOG_WEB_HOST}
- FOG_HTTP_PROTOCOL=${FOG_HTTP_PROTOCOL}
- FOG_INTERNAL_HTTPS_ENABLED=${FOG_INTERNAL_HTTPS_ENABLED}
- FOG_APACHE_EXPOSED_PORT=${FOG_APACHE_EXPOSED_PORT}
labels:
- "traefik.enable=true"
- "traefik.http.routers.fog.rule=Host(`${FOG_WEB_HOST}`)"
- "traefik.http.routers.fog.entrypoints=websecure"
- "traefik.http.routers.fog.tls.certresolver=letsencrypt"
- "traefik.http.services.fog.loadbalancer.server.port=80"
- "traefik.docker.network=fog-network"
networks:
- fog-network
networks:
fog-network:
external: true
Required .env variables:
FOG_WEB_HOST=fog.example.com
FOG_HTTP_PROTOCOL=https
FOG_INTERNAL_HTTPS_ENABLED=false
FOG_APACHE_EXPOSED_PORT=80
LETSENCRYPT_EMAIL=your-email@example.com
Traefik Labels for FOG
labels:
# Basic routing
- "traefik.enable=true"
- "traefik.http.routers.fog.rule=Host(`fog.example.com`)"
- "traefik.http.routers.fog.entrypoints=websecure"
- "traefik.http.routers.fog.tls.certresolver=letsencrypt"
# Service configuration
- "traefik.http.services.fog.loadbalancer.server.port=80"
# Security headers
- "traefik.http.middlewares.fog-headers.headers.customrequestheaders.X-Forwarded-Proto=https"
- "traefik.http.middlewares.fog-headers.headers.customrequestheaders.X-Forwarded-For="
- "traefik.http.middlewares.fog-headers.headers.customrequestheaders.X-Real-IP="
- "traefik.http.routers.fog.middlewares=fog-headers"
# Rate limiting
- "traefik.http.middlewares.fog-ratelimit.ratelimit.burst=100"
- "traefik.http.middlewares.fog-ratelimit.ratelimit.average=50"
- "traefik.http.routers.fog.middlewares=fog-ratelimit"
Traefik Static Configuration
For more advanced configuration, use a static config file:
# traefik.yml
api:
dashboard: true
insecure: true
entryPoints:
web:
address: ":80"
http:
redirections:
entrypoint:
to: websecure
scheme: https
websecure:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
certificatesResolvers:
letsencrypt:
acme:
tlsChallenge: {}
email: ${LETSENCRYPT_EMAIL}
storage: /letsencrypt/acme.json
log:
level: INFO
accessLog: {}
Required .env variable:
LETSENCRYPT_EMAIL=your-email@example.com
Nginx Configuration
Basic Nginx Configuration
# /etc/nginx/sites-available/fog
server {
listen 80;
server_name fog.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name fog.example.com;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/fog.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/fog.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# Security Headers
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
# Proxy Configuration
location / {
proxy_pass http://127.0.0.1:8080;
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;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# Buffer settings
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}
# Special handling for large file uploads
location /fog/management/index.php {
proxy_pass http://127.0.0.1:8080;
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;
# Increase timeouts for large uploads
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
# Increase client body size for image uploads
client_max_body_size 10G;
}
}
Nginx with Let’s Encrypt
# Install certbot
sudo apt install certbot python3-certbot-nginx
# Obtain certificate
sudo certbot --nginx -d fog.example.com
# Auto-renewal
sudo crontab -e
# Add: 0 12 * * * /usr/bin/certbot renew --quiet
Nginx Load Balancing
upstream fog_backend {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
server 127.0.0.1:8082;
# Load balancing method
least_conn;
# Health checks
keepalive 32;
}
server {
listen 443 ssl http2;
server_name fog.example.com;
# SSL configuration...
location / {
proxy_pass http://fog_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;
}
}
Apache Configuration
Basic Apache Configuration
# /etc/apache2/sites-available/fog.conf
<VirtualHost *:80>
ServerName fog.example.com
Redirect permanent / https://fog.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName fog.example.com
# SSL Configuration
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/fog.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/fog.example.com/privkey.pem
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
# Security Headers
Header always set Strict-Transport-Security "max-age=63072000"
Header always set X-Frame-Options DENY
Header always set X-Content-Type-Options nosniff
Header always set X-XSS-Protection "1; mode=block"
# Proxy Configuration
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
# Proxy Headers
ProxyAddHeaders On
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
# Timeouts
ProxyTimeout 300
# Large file uploads
<Location "/fog/management/index.php">
ProxyPass http://127.0.0.1:8080/
ProxyPassReverse http://127.0.0.1:8080/
ProxyTimeout 300
</Location>
</VirtualHost>
Apache with Let’s Encrypt
# Install certbot
sudo apt install certbot python3-certbot-apache
# Obtain certificate
sudo certbot --apache -d fog.example.com
# Auto-renewal
sudo crontab -e
# Add: 0 12 * * * /usr/bin/certbot renew --quiet
Apache Load Balancing
# Load balancer configuration
<Proxy balancer://fog-cluster>
BalancerMember http://127.0.0.1:8080
BalancerMember http://127.0.0.1:8081
BalancerMember http://127.0.0.1:8082
ProxySet lbmethod=byrequests
</Proxy>
<VirtualHost *:443>
ServerName fog.example.com
# SSL configuration...
ProxyPreserveHost On
ProxyPass / balancer://fog-cluster/
ProxyPassReverse / balancer://fog-cluster/
</VirtualHost>
Caddy Configuration
Basic Caddyfile
# Caddyfile
fog.example.com {
# Automatic HTTPS with Let's Encrypt
tls your-email@example.com
# Security headers
header {
Strict-Transport-Security "max-age=63072000"
X-Frame-Options DENY
X-Content-Type-Options nosniff
X-XSS-Protection "1; mode=block"
}
# Proxy to FOG Docker
reverse_proxy 127.0.0.1:8080 {
header_up Host {host}
header_up X-Real-IP {remote}
header_up X-Forwarded-For {remote}
header_up X-Forwarded-Proto {scheme}
}
# Handle large file uploads
@large_uploads path /fog/management/index.php
reverse_proxy @large_uploads 127.0.0.1:8080 {
header_up Host {host}
header_up X-Real-IP {remote}
header_up X-Forwarded-For {remote}
header_up X-Forwarded-Proto {scheme}
# Increase timeouts for large uploads
timeout 300s
}
}
Caddy with Load Balancing
fog.example.com {
tls your-email@example.com
# Load balancing
reverse_proxy 127.0.0.1:8080 127.0.0.1:8081 127.0.0.1:8082 {
header_up Host {host}
header_up X-Real-IP {remote}
header_up X-Forwarded-For {remote}
header_up X-Forwarded-Proto {scheme}
# Load balancing method
lb_policy round_robin
}
}
Caddy with Custom SSL
fog.example.com {
tls /path/to/cert.pem /path/to/key.pem
reverse_proxy 127.0.0.1:8080 {
header_up Host {host}
header_up X-Real-IP {remote}
header_up X-Forwarded-For {remote}
header_up X-Forwarded-Proto {scheme}
}
}
Docker Compose Examples
Complete Traefik Setup
version: '3.8'
services:
traefik:
image: traefik:v3.0
command:
- --api.dashboard=true
- --api.insecure=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --certificatesresolvers.letsencrypt.acme.tlschallenge=true
- --certificatesresolvers.letsencrypt.acme.email=your-email@example.com
- --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
networks:
- fog-network
fog-server:
image: ghcr.io/88fingerslukee/fog-docker:latest
environment:
- FOG_WEB_HOST=fog.example.com
- FOG_HTTP_PROTOCOL=https
- FOG_INTERNAL_HTTPS_ENABLED=false
labels:
- "traefik.enable=true"
- "traefik.http.routers.fog.rule=Host(`fog.example.com`)"
- "traefik.http.routers.fog.entrypoints=websecure"
- "traefik.http.routers.fog.tls.certresolver=letsencrypt"
- "traefik.http.services.fog.loadbalancer.server.port=80"
networks:
- fog-network
networks:
fog-network:
driver: bridge
Nginx with FOG Docker
services:
nginx:
image: nginx:alpine
ports:
- "${FOG_APACHE_EXPOSED_PORT:-80}:80"
- "${FOG_APACHE_EXPOSED_SSL_PORT:-443}:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- fog-server
networks:
- fog-network
fog-server:
image: ghcr.io/88fingerslukee/fog-docker:latest
environment:
- FOG_WEB_HOST=${FOG_WEB_HOST}
- FOG_HTTP_PROTOCOL=${FOG_HTTP_PROTOCOL}
- FOG_INTERNAL_HTTPS_ENABLED=${FOG_INTERNAL_HTTPS_ENABLED}
- FOG_APACHE_EXPOSED_PORT=${FOG_APACHE_EXPOSED_PORT}
expose:
- "80"
networks:
- fog-network
networks:
fog-network:
driver: bridge
Required .env variables:
FOG_WEB_HOST=fog.example.com
FOG_HTTP_PROTOCOL=https
FOG_INTERNAL_HTTPS_ENABLED=false
FOG_APACHE_EXPOSED_PORT=80
FOG_APACHE_EXPOSED_SSL_PORT=443
Testing and Verification
Test SSL Configuration
# Test SSL certificate
openssl s_client -connect fog.example.com:443 -servername fog.example.com
# Test HTTP to HTTPS redirect
curl -I http://fog.example.com
# Test HTTPS access
curl -I https://fog.example.com/fog/
Test FOG Functionality
# Test web interface
curl -I https://fog.example.com/fog/
# Test HTTPBoot files
curl -I https://fog.example.com/fog/service/ipxe/ipxe.efi
# Test FOG client downloads
curl -I https://fog.example.com/fog/client/download.php
Monitor Reverse Proxy
# Check reverse proxy logs
docker logs traefik
docker logs nginx
docker logs apache
# Check FOG server logs
docker logs fog-server
# Monitor performance
htop
docker stats
Troubleshooting
Common Issues
SSL Certificate Issues
Symptoms: SSL errors or certificate warnings Solutions:
- Check certificate validity:
openssl x509 -in /path/to/cert.pem -text -noout - Verify certificate chain
- Check certificate renewal
- Verify domain name matches certificate
Proxy Headers Issues
Symptoms: FOG shows wrong protocol or IP addresses Solutions:
- Check proxy headers in reverse proxy configuration
- Verify X-Forwarded-Proto is set to “https”
- Check X-Forwarded-For headers
- Verify Host header is passed correctly
Large File Upload Issues
Symptoms: Image uploads fail or timeout Solutions:
- Increase timeout values in reverse proxy
- Check client_max_body_size (Nginx)
- Verify ProxyTimeout settings (Apache)
- Check FOG upload limits
Debug Commands
# Check reverse proxy status
docker ps | grep -E "(traefik|nginx|apache)"
# Check FOG server status
docker ps | grep fog-server
# Test connectivity
curl -v https://fog.example.com/fog/
# Check SSL certificate
openssl s_client -connect fog.example.com:443
# Monitor logs
docker logs -f traefik
docker logs -f fog-server
Security Considerations
SSL/TLS Security
- Use strong SSL/TLS configurations
- Enable HSTS headers
- Use modern cipher suites
- Regular certificate renewal
Access Control
- Implement rate limiting
- Use IP whitelisting if needed
- Enable access logging
- Monitor for suspicious activity
Network Security
- Use private networks for internal communication
- Implement firewall rules
- Monitor network traffic
- Use VPN for remote access
Performance Optimization
Caching
# Nginx caching for static content
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
Compression
# Enable gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
Load Balancing
- Use multiple FOG instances for high availability
- Implement health checks
- Use sticky sessions if needed
- Monitor backend health
Next Steps
After setting up reverse proxy:
- SSL/HTTPS Setup - Verify SSL configuration
- Network Boot Setup - Test HTTPBoot with HTTPS
- Troubleshooting Guide - Address any issues