For production deployments, you'll want to put Frona behind a reverse proxy. This handles TLS termination, serves both the frontend and backend on a single domain, and provides additional security.
Nginx configuration
Here's a basic Nginx configuration that proxies both the frontend and backend:
server {
listen 443 ssl http2;
server_name frona.example.com;
ssl_certificate /etc/ssl/certs/frona.pem;
ssl_certificate_key /etc/ssl/private/frona.key;
# Frontend
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
# Backend API
location /api/ {
proxy_pass http://127.0.0.1:3001;
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;
# SSE streaming support
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 300s;
}
# Increase body size for file uploads
client_max_body_size 100M;
}Key considerations
SSE streaming
Agent responses stream via Server-Sent Events. Make sure your proxy:
- Disables response buffering (
proxy_buffering off) - Disables caching (
proxy_cache off) - Has a long enough read timeout (
proxy_read_timeout 300s)
Without these settings, responses will appear delayed or arrive all at once instead of streaming.
WebSocket support
If you expose the Browserless debugger through the proxy, you'll need WebSocket support:
location /ws/ {
proxy_pass http://127.0.0.1:3333;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}CORS
Set FRONA_SERVER_CORS_ORIGINS to match your domain:
FRONA_SERVER_CORS_ORIGINS=https://frona.example.comBase URL
Set FRONA_SERVER_BASE_URL to your public URL. This is used for generating callback URLs (e.g., for Twilio):
FRONA_SERVER_BASE_URL=https://frona.example.comCaddy alternative
If you prefer Caddy, the configuration is simpler:
frona.example.com {
handle /api/* {
reverse_proxy localhost:3001 {
flush_interval -1
}
}
handle {
reverse_proxy localhost:3000
}
}Caddy handles TLS automatically via Let's Encrypt. The flush_interval -1 setting ensures SSE events stream immediately.