Skip to Content

Nginx Proxy Manager (NPM) Setup

This guide shows you how to set up Rybbit with Nginx Proxy Manager without exposing ports directly to the host.

Prerequisites

  • Nginx Proxy Manager already running
  • Basic knowledge of Docker networks
  • Domain name pointed to your server

This setup assumes you have NPM running and are capable of creating SSL certificates. You can also use any other reverse proxy as long as you can put it on the same Docker network as Rybbit.

Setup Steps

Create Custom Docker Compose

Create a new directory for your Rybbit installation and create a docker-compose.yml file:

services: rybbit_clickhouse: image: clickhouse/clickhouse-server:25.4.2 container_name: rybbit_clickhouse volumes: - ./clickhouse-data:/var/lib/clickhouse - ./clickhouse_config:/etc/clickhouse-server/config.d environment: - CLICKHOUSE_DB=${CLICKHOUSE_DB:-analytics} - CLICKHOUSE_USER=${CLICKHOUSE_USER:-default} - CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD:-frog} healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8123/ping"] interval: 3s timeout: 5s retries: 5 start_period: 10s restart: unless-stopped networks: - internal rybbit_postgres: image: postgres:17.4 container_name: rybbit_postgres environment: - POSTGRES_USER=${POSTGRES_USER:-frog} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-frog} - POSTGRES_DB=${POSTGRES_DB:-analytics} volumes: - ./postgres-data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 3s timeout: 5s retries: 5 start_period: 10s restart: unless-stopped networks: - internal rybbit_backend: image: ghcr.io/rybbit-io/rybbit-backend:${IMAGE_TAG:-latest} container_name: rybbit_backend environment: - NODE_ENV=production - CLICKHOUSE_HOST=http://rybbit_clickhouse:8123 - CLICKHOUSE_DB=${CLICKHOUSE_DB:-analytics} - CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD:-frog} - POSTGRES_HOST=rybbit_postgres - POSTGRES_PORT=5432 - POSTGRES_DB=${POSTGRES_DB:-analytics} - POSTGRES_USER=${POSTGRES_USER:-frog} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-frog} - BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET} - BASE_URL=${BASE_URL} - DISABLE_SIGNUP=${DISABLE_SIGNUP} depends_on: rybbit_clickhouse: condition: service_healthy rybbit_postgres: condition: service_started healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3001/api/health"] interval: 3s timeout: 5s retries: 5 start_period: 10s restart: unless-stopped networks: - internal - npm_proxy rybbit_client: image: ghcr.io/rybbit-io/rybbit-client:${IMAGE_TAG:-latest} container_name: rybbit_client environment: - NODE_ENV=production - NEXT_PUBLIC_BACKEND_URL=${BASE_URL} - NEXT_PUBLIC_DISABLE_SIGNUP=${DISABLE_SIGNUP} depends_on: - rybbit_backend restart: unless-stopped networks: - internal - npm_proxy networks: internal: driver: bridge npm_proxy: external: true volumes: clickhouse-data: postgres-data:

Configure Environment

Create a .env file in the same directory:

# Required: Your domain and base URL DOMAIN_NAME=your.domain.com BASE_URL=https://your.domain.com # Required: Authentication secret (generate a random 32+ character string) BETTER_AUTH_SECRET=your_generated_secret_here # Optional: Disable new user signups after creating admin account DISABLE_SIGNUP=false # Optional: Custom image tag IMAGE_TAG=latest

Generate a secure BETTER_AUTH_SECRET using: openssl rand -hex 32

Setup Docker Network

Create the external network that NPM uses (if it doesn’t exist):

docker network create npm_proxy

Make sure your NPM container is connected to this network:

# Check if NPM is on the network docker network inspect npm_proxy # If needed, connect NPM to the network docker network connect npm_proxy <npm_container_name>

Copy ClickHouse Config (Optional)

Optionally, copy the ClickHouse configuration for better control:

# If you cloned the main repo, copy the config cp -r /path/to/rybbit/clickhouse_config ./ # Or download it directly curl -L https://github.com/rybbit-io/rybbit/archive/master.tar.gz | tar -xz --strip=2 rybbit-master/clickhouse_config

Start Services

Start all Rybbit services:

docker compose up -d

Verify all services are running:

docker compose ps

Configure NPM

In your Nginx Proxy Manager interface:

  1. Create Proxy Host:

    • Domain Names: your.domain.com
    • Scheme: http
    • Forward Hostname/IP: rybbit_client
    • Forward Port: 3002
    • Enable “Cache Assets”, “Block Common Exploits”, “Websockets Support”
  2. Add Custom Location:

    • Location: /api
    • Scheme: http
    • Forward Hostname/IP: rybbit_backend
    • Forward Port: 3001
  3. Advanced Configuration (in the custom location):

    location /api/ { proxy_pass http://rybbit_backend: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; }
  4. SSL Configuration:

    • Enable SSL
    • Request a new SSL certificate with Let’s Encrypt
    • Enable “Force SSL” and “HTTP/2 Support”

Access Rybbit

Navigate to https://your.domain.com and create your admin account.

Alternative Proxy Configurations

Traefik

If you’re using Traefik instead, add these labels to your services:

services: rybbit_backend: # ... existing config labels: - "traefik.enable=true" - "traefik.http.routers.rybbit-api.rule=Host(`your.domain.com`) && PathPrefix(`/api`)" - "traefik.http.routers.rybbit-api.tls.certresolver=letsencrypt" - "traefik.http.services.rybbit-api.loadbalancer.server.port=3001" - "traefik.docker.network=traefik_proxy" rybbit_client: # ... existing config labels: - "traefik.enable=true" - "traefik.http.routers.rybbit-client.rule=Host(`your.domain.com`)" - "traefik.http.routers.rybbit-client.tls.certresolver=letsencrypt" - "traefik.http.services.rybbit-client.loadbalancer.server.port=3002" - "traefik.docker.network=traefik_proxy" networks: traefik_proxy: external: true

Cloudflare Tunnel

For Cloudflare Tunnel, create a tunnel configuration:

tunnel: your-tunnel-id credentials-file: /path/to/credentials.json ingress: - hostname: your.domain.com path: /api service: http://rybbit_backend:3001 - hostname: your.domain.com service: http://rybbit_client:3002 - service: http_status:404

Troubleshooting

Common Issues

NPM can’t reach containers:

  • Verify both NPM and Rybbit are on the same network
  • Check container names match the proxy configuration

SSL certificate issues:

  • Ensure domain is pointed to your server
  • Check NPM logs for certificate generation errors

502 Bad Gateway:

  • Verify Rybbit services are healthy: docker compose ps
  • Check container logs: docker compose logs

Networking

Check network connectivity:

# List all networks docker network ls # Inspect the npm_proxy network docker network inspect npm_proxy # Check which containers are connected docker ps --format "table {{.Names}}\t{{.Networks}}"

Logs

Monitor logs for debugging:

# Rybbit services docker compose logs -f # Specific service docker compose logs -f rybbit_backend # NPM logs (adjust container name) docker logs -f nginx-proxy-manager
⚠️

Remember to regularly backup your data volumes (clickhouse-data and postgres-data) and your .env file.

Last updated on