Custom Nginx setup
Set up Rybbit with your own Nginx installation instead of using the built-in Caddy server
This guide shows you how to set up Rybbit with your own Nginx installation instead of using the built-in Caddy server.
Prerequisites
- Existing Nginx installation
- SSL certificates (Let's Encrypt recommended)
- Domain pointed to your server
- Rybbit running with
--no-webserverflag
Setup Steps
Run Rybbit without Caddy
First, set up Rybbit to expose ports without the built-in webserver:
./setup.sh your.domain.name --no-webserverOptionally, include a Mapbox token for globe visualizations:
./setup.sh your.domain.name --no-webserver --mapbox-token YOUR_MAPBOX_TOKENThis publishes the backend on port 3001 and the client on port 3002 on all interfaces, over plain HTTP.
Since Nginx runs on the same host, bind both ports to localhost so they can't be reached from outside. Edit these lines in .env:
HOST_BACKEND_PORT="127.0.0.1:3001:3001"
HOST_CLIENT_PORT="127.0.0.1:3002:3002"Then apply the change with docker compose up -d. Ports published by Docker bypass host firewalls such as ufw, so don't rely on those to block them.
Configure Nginx
Create or update your Nginx configuration file (usually in /etc/nginx/sites-available/):
server {
listen 80;
server_name your.domain.name;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name your.domain.name;
# SSL configuration (using Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/your.domain.name/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your.domain.name/privkey.pem;
# Modern SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Backend service: the API and the OAuth discovery documents MCP clients use
location ~ ^/(api/|\.well-known/oauth-|\.well-known/openid-configuration) {
proxy_pass http://localhost: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;
proxy_set_header X-Forwarded-Host $server_name;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# Client service
location / {
proxy_pass http://localhost:3002;
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 $server_name;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}Enable the Site
Enable your Nginx configuration:
# Create symlink to enable the site
sudo ln -s /etc/nginx/sites-available/your-site /etc/nginx/sites-enabled/
# Test the configuration
sudo nginx -t
# Reload Nginx
sudo systemctl reload nginxVerify Setup
Check that everything is working:
# Check Nginx status
sudo systemctl status nginx
# Check Rybbit services
docker compose ps
# Test the website
curl -I https://your.domain.nameSSL Certificate Setup with Certbot
If you need to set up SSL certificates with Let's Encrypt:
Install Certbot
# Ubuntu/Debian
sudo apt update
sudo apt install certbot python3-certbot-nginx
# CentOS/RHEL
sudo yum install certbot python3-certbot-nginxObtain Certificate
sudo certbot --nginx -d your.domain.nameAuto-renewal
Set up automatic renewal:
# Test renewal
sudo certbot renew --dry-run
# Check existing cron job
sudo crontab -lCertbot usually sets up auto-renewal automatically, but you can add this cron job if needed:
0 12 * * * /usr/bin/certbot renew --quietCustom Ports
If you need to use custom ports for Rybbit:
./setup.sh your.domain.name --no-webserver --backend-port 8080 --client-port 8081
# With Mapbox token
./setup.sh your.domain.name --no-webserver --backend-port 8080 --client-port 8081 --mapbox-token YOUR_MAPBOX_TOKENBind them to localhost the same way, e.g. HOST_BACKEND_PORT="127.0.0.1:8080:3001", and update your Nginx configuration accordingly:
location ~ ^/(api/|\.well-known/oauth-|\.well-known/openid-configuration) {
proxy_pass http://localhost:8080; # Custom backend port
# ... rest of config
}
location / {
proxy_pass http://localhost:8081; # Custom client port
# ... rest of config
}Troubleshooting
Common Issues
502 Bad Gateway: Check if Rybbit services are running:
docker compose ps
docker compose logsSSL Certificate Issues: Verify certificate paths:
sudo certbot certificatesPermission Denied: Check Nginx error logs:
sudo tail -f /var/log/nginx/error.logLogs
Monitor logs for debugging:
# Nginx access logs
sudo tail -f /var/log/nginx/access.log
# Nginx error logs
sudo tail -f /var/log/nginx/error.log
# Rybbit logs
docker compose logs -f