Self-Hosting Guides

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-webserver flag

Setup Steps

Run Rybbit without Caddy

First, set up Rybbit to expose ports without the built-in webserver:

./setup.sh your.domain.name --no-webserver

Optionally, include a Mapbox token for globe visualizations:

./setup.sh your.domain.name --no-webserver --mapbox-token YOUR_MAPBOX_TOKEN

This 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 nginx

Verify 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.name

SSL 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-nginx

Obtain Certificate

sudo certbot --nginx -d your.domain.name

Auto-renewal

Set up automatic renewal:

# Test renewal
sudo certbot renew --dry-run

# Check existing cron job
sudo crontab -l

Certbot usually sets up auto-renewal automatically, but you can add this cron job if needed:

0 12 * * * /usr/bin/certbot renew --quiet

Custom 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_TOKEN

Bind 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 logs

SSL Certificate Issues: Verify certificate paths:

sudo certbot certificates

Permission Denied: Check Nginx error logs:

sudo tail -f /var/log/nginx/error.log

Logs

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

On this page