Reverse Proxy Setup
Running Snippbot directly on port 18781 is fine for local use, but for a production deployment you should place it behind a reverse proxy. A reverse proxy gives you:
- HTTPS/TLS termination via Let’s Encrypt
- Custom domain (e.g.
snippbot.yourcompany.com) - Security headers to harden the HTTP interface
- WebSocket support required for the real-time UI (
/wsendpoint) - Large upload support via increased
client_max_body_size
Installation
Section titled “Installation”sudo apt install nginx certbot python3-certbot-nginxConfiguration
Section titled “Configuration”Create a new site configuration:
server { listen 80; server_name snippbot.yourserver.com;
# Redirect all HTTP to HTTPS return 301 https://$host$request_uri;}
server { listen 443 ssl http2; server_name snippbot.yourserver.com;
# TLS certificates (managed by certbot) ssl_certificate /etc/letsencrypt/live/snippbot.yourserver.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/snippbot.yourserver.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Security headers add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Increase upload size limit for file attachments client_max_body_size 50M;
# Main proxy location / { proxy_pass http://127.0.0.1:18781; proxy_http_version 1.1; 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 timeout for long-running agent responses proxy_read_timeout 300s; proxy_connect_timeout 10s; proxy_send_timeout 300s; }
# WebSocket support for /ws endpoint location /ws { proxy_pass http://127.0.0.1:18781; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; 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_read_timeout 3600s; }
# Channel adapter webhooks location /slack/ { proxy_pass http://127.0.0.1:18790; 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; }
location /telegram/ { proxy_pass http://127.0.0.1:18790; 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; }}Enable the site and obtain a certificate
Section titled “Enable the site and obtain a certificate”sudo ln -s /etc/nginx/sites-available/snippbot /etc/nginx/sites-enabled/sudo nginx -tsudo systemctl reload nginxsudo certbot --nginx -d snippbot.yourserver.comsudo systemctl reload nginxCaddy is the simpler option — it handles TLS certificate issuance and renewal automatically with zero extra configuration.
Installation
Section titled “Installation”sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curlcurl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpgcurl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.listsudo apt update && sudo apt install caddyConfiguration
Section titled “Configuration”snippbot.yourserver.com { # Caddy automatically obtains and renews a Let's Encrypt certificate
# Security headers header Strict-Transport-Security "max-age=31536000; includeSubDomains" header X-Content-Type-Options "nosniff" header X-Frame-Options "SAMEORIGIN"
# Increase request body size limit for file uploads request_body { max_size 50MB }
# WebSocket support — Caddy handles the Upgrade header automatically reverse_proxy /ws* localhost:18781 { transport http { read_timeout 1h write_timeout 1h } }
# Channel adapter webhook paths reverse_proxy /slack/* localhost:18790 reverse_proxy /telegram/* localhost:18790 reverse_proxy /discord/* localhost:18790
# Everything else goes to the main Snippbot API + UI reverse_proxy localhost:18781 { transport http { read_timeout 5m write_timeout 5m } }}Apply the configuration
Section titled “Apply the configuration”sudo systemctl reload caddyCaddy immediately fetches a certificate from Let’s Encrypt and begins proxying traffic. There is no separate certbot step.
WebSocket Support
Section titled “WebSocket Support”The Snippbot UI uses a persistent WebSocket connection at /ws for:
- Real-time agent output streaming
- Live run status updates
- Browser panel synchronization
If the WebSocket is blocked or misconfigured, the UI will fall back to polling, which results in a degraded experience (slower updates, no live typing effect).
nginx WebSocket checklist
Section titled “nginx WebSocket checklist”The nginx config above handles this via the /ws location block. The critical headers are:
proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";Without these, nginx closes the connection when the client attempts the HTTP upgrade handshake.
Caddy WebSocket checklist
Section titled “Caddy WebSocket checklist”Caddy handles WebSocket upgrades automatically. No special configuration is needed beyond the reverse_proxy directive.
SSL/TLS with Let’s Encrypt
Section titled “SSL/TLS with Let’s Encrypt”Both configurations above use Let’s Encrypt for free, auto-renewing TLS certificates.
Requirements for Let’s Encrypt
Section titled “Requirements for Let’s Encrypt”- Your domain’s DNS A record must point to your server’s public IP
- Port 80 must be accessible from the internet for the HTTP-01 ACME challenge (Caddy and certbot handle this automatically)
- The domain must not be behind a CDN or proxy that intercepts HTTPS (at least during initial issuance)
Certificate renewal
Section titled “Certificate renewal”| Tool | Renewal method |
|---|---|
| Certbot (nginx) | Systemd timer or cron job, auto-configured by certbot |
| Caddy | Automatic, built-in — no configuration needed |
Example Domain Patterns
Section titled “Example Domain Patterns”| Use case | Example domain |
|---|---|
| Company internal tool | snippbot.yourcompany.com |
| Personal self-hosted | ai.yourname.dev |
| Team deployment | agent.team.example.com |
| Documentation site | docs.yourcompany.com (if hosting Snippbot docs alongside) |
Security Recommendations
Section titled “Security Recommendations”- Keep Snippbot and nginx/Caddy up to date
- Do not expose the SQLite database file or
~/.snippbot/directory via the web server - If using nginx, add
deny all;to block access to any paths that should not be public - Consider adding HTTP Basic Auth in front of the entire deployment if Snippbot will be accessible on the public internet and you have not yet enabled Snippbot’s built-in authentication
- Use the
X-Forwarded-Forheader (already set in the configs above) so Snippbot logs show real client IPs rather than127.0.0.1