# How to Configure a Reverse Proxy (nginx) for Open Notebook Deployment

> Learn to configure an nginx reverse proxy for your Open Notebook deployment. Simplify routing with automatic internal API handling for a seamless user experience.

- Repository: [Luis Novo/open-notebook](https://github.com/lfnovo/open-notebook)
- Tags: how-to-guide
- Published: 2026-06-24

---

**Configure your reverse proxy to forward all traffic to the Next.js frontend container on port 8502; since version 1.1, Open Notebook automatically routes `/api/*` requests internally to the FastAPI backend, eliminating the need for complex multi-path proxy rules.**

Open Notebook is a containerized application that runs as two distinct services: a Next.js frontend and a FastAPI backend. When deploying Open Notebook in production, you must place a reverse proxy in front of the application to handle TLS termination, security headers, and traffic routing. Because the frontend handles internal API forwarding since version 1.1, your proxy configuration only needs to target a single port, simplifying SSL management and avoiding CORS complications.

## Architecture Overview

Open Notebook exposes two services inside its Docker container:

- **Next.js frontend**: Listens on port `8502` and serves the user interface
- **FastAPI backend**: Listens on port `5055` and handles all API endpoints

Since version 1.1, the frontend includes a rewrite rule that proxies any request matching `/api/*` internally to `http://localhost:5055`. This architecture means the backend never needs direct exposure to the browser or external network.

**Key advantage**: Your reverse proxy only requires a single `location /` block pointing to port `8502`. The frontend handles the internal routing to the backend, preventing cross-origin issues and reducing proxy complexity.

## Complete nginx Configuration

The following configuration from [`docs/5-CONFIGURATION/reverse-proxy.md`](https://github.com/lfnovo/open-notebook/blob/main/docs/5-CONFIGURATION/reverse-proxy.md) demonstrates a production-ready nginx setup that terminates TLS and forwards all traffic to the Open Notebook container.

```nginx

# Full nginx configuration for a production deployment

events {
    worker_connections 1024;
}

http {
    upstream notebook {
        server open-notebook:8502;   # Next.js container

    }

    # HTTP → HTTPS redirect

    server {
        listen 80;
        server_name notebook.example.com;
        return 301 https://$server_name$request_uri;
    }

    # HTTPS server

    server {
        listen 443 ssl http2;
        server_name notebook.example.com;

        # TLS certificates (replace with your own or use Let’s Encrypt)

        ssl_certificate /etc/nginx/ssl/fullchain.pem;
        ssl_certificate_key /etc/nginx/ssl/privkey.pem;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!MD5;

        # Allow large file uploads (default is 1 MiB)

        client_max_body_size 100M;

        # Security headers

        add_header X-Frame-Options DENY;
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

        # Proxy all traffic to the Next.js container

        location / {
            proxy_pass http://notebook;
            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;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_cache_bypass $http_upgrade;

            # Timeouts for long-running operations (transformations, podcasts, etc.)

            proxy_read_timeout 600s;
            proxy_connect_timeout 60s;
            proxy_send_timeout 600s;
        }
    }
}

```

### TLS Termination and Security Headers

The reverse proxy handles all HTTPS encryption, keeping the application containers free from certificate management complexity. Configure `ssl_protocols` to use TLSv1.2 or higher, and add security headers to prevent common web vulnerabilities like clickjacking and MIME-type sniffing.

### Body Size and Timeout Settings

Open Notebook processes large file uploads and long-running AI operations. You must increase the default nginx limits:

- **`client_max_body_size 100M`**: Supports document uploads that exceed the default 1 MiB limit
- **`proxy_read_timeout 600s`** and **`proxy_send_timeout 600s`**: Prevents timeouts during podcast generation, document transformation, and other extended AI tasks

## Alternative Reverse Proxy Options

While nginx is the most common choice, Open Notebook supports other reverse proxies with minimal configuration changes.

### Caddy

Caddy handles HTTPS automatically and requires significantly less configuration:

```caddy
notebook.example.com {
    reverse_proxy open-notebook:8502 {
        transport http {
            read_timeout 600s
            write_timeout 600s
        }
    }
}

```

### Traefik

When using Traefik with Docker Compose, add labels to the Open Notebook service:

```yaml
labels:
  - "traefik.enable=true"
  - "traefik.http.services.notebook.loadbalancer.server.port=8502"
  - "traefik.http.routers.notebook.rule=Host(`notebook.example.com`)"

```

Note that Traefik requires additional static configuration to set timeout values for long-running AI operations.

### Coolify

For UI-driven deployments, set the service port to **8502** and configure `API_URL=https://your-domain.com` in the environment variables section.

## Required Environment Variables

The `API_URL` environment variable is **mandatory** when running behind a reverse proxy. Set this to your public HTTPS URL so the frontend can construct absolute API URLs correctly. If you omit this variable, the application attempts to auto-detect the host, which often fails behind complex proxy setups.

```bash
API_URL=https://notebook.example.com

```

If you run the frontend and backend in separate containers, use `INTERNAL_API_URL` to tell the frontend how to reach the backend internally.

## Docker Compose Setup

Bind the Open Notebook container to localhost only, letting nginx handle the public exposure:

```yaml
services:
  open-notebook:
    image: lfnovo/open_notebook:v1-latest
    environment:
      - API_URL=https://notebook.example.com
    ports:
      - "127.0.0.1:8502:8502"   # expose only to localhost; nginx handles the public side

  
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
    depends_on:
      - open-notebook

```

This configuration ensures port 8502 is not exposed to the internet directly, forcing all traffic through the nginx reverse proxy.

## Testing the Configuration

Verify your deployment by testing the proxy endpoints:

```bash

# Verify TLS termination

curl -I https://notebook.example.com

# Verify the UI loads

curl https://notebook.example.com | head -n 20

# Verify API endpoint (through the proxy)

curl https://notebook.example.com/api/config

```

## Summary

- Open Notebook uses a **single-port architecture** where the Next.js frontend (port 8502) internally proxies `/api/*` requests to the FastAPI backend (port 5055)
- Configure your reverse proxy to forward **all traffic** to port 8502; no separate `/api/` routes are required
- Set **`API_URL`** to your public HTTPS domain to ensure correct URL generation
- Increase **`client_max_body_size`** to at least 100M for file uploads
- Set **`proxy_read_timeout`** and **`proxy_send_timeout`** to 600 seconds to accommodate long-running AI operations
- Reference the complete configuration examples in [`docs/5-CONFIGURATION/reverse-proxy.md`](https://github.com/lfnovo/open-notebook/blob/main/docs/5-CONFIGURATION/reverse-proxy.md)

## Frequently Asked Questions

### Do I need to expose port 5055 to the internet?

No. Port 5055, which runs the FastAPI backend, should never be exposed directly to browsers or the public internet. The Next.js frontend on port 8502 handles all `/api/*` routing internally, making the backend accessible only through the frontend container.

### Why does my deployment fail with CORS errors?

CORS errors typically occur when the `API_URL` environment variable is not set or does not match your public HTTPS domain. The frontend uses this variable to construct absolute URLs for API requests; if it auto-detects incorrectly behind your proxy, the browser rejects the mismatched origins. Set `API_URL=https://your-domain.com` explicitly in your container environment.

### How do I handle very large file uploads?

Increase the `client_max_body_size` directive in your nginx configuration (or equivalent in other proxies) from the default 1 MiB to at least 100M. Open Notebook processes documents, audio files, and other media that frequently exceed standard web server limits.

### Can I use separate subdomains for the frontend and backend?

While technically possible, it is not recommended. Since version 1.1, Open Notebook is designed to run behind a single-domain reverse proxy. Using separate subdomains (e.g., `api.example.com` and `app.example.com`) requires additional CORS configuration and complicates the deployment. The single-port approach through port 8502 is the officially supported method.