How to Configure a Reverse Proxy (nginx) for Open Notebook Deployment
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
8502and serves the user interface - FastAPI backend: Listens on port
5055and 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 demonstrates a production-ready nginx setup that terminates TLS and forwards all traffic to the Open Notebook container.
# 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 limitproxy_read_timeout 600sandproxy_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:
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:
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.
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:
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:
# 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_URLto your public HTTPS domain to ensure correct URL generation - Increase
client_max_body_sizeto at least 100M for file uploads - Set
proxy_read_timeoutandproxy_send_timeoutto 600 seconds to accommodate long-running AI operations - Reference the complete configuration examples in
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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →