# How to Configure Docker Deployment and Reverse Proxy for Open Notebook

> Learn how to configure Docker deployment and reverse proxy for Open Notebook. Expose port 8502 and set the API_URL environment variable for seamless Next.js and FastAPI integration.

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

---

**Open Notebook requires exposing only port 8502 through your reverse proxy, as the Next.js frontend automatically proxies `/api/*` requests to the FastAPI backend, but you must set the `API_URL` environment variable to ensure the UI generates correct HTTPS links.**

Open Notebook is a self-hosted AI note-taking application that runs as a multi-container Docker stack. Starting with version 1.1, the architecture simplifies reverse proxy configuration by handling API routing internally between the frontend and backend containers. This guide explains how to deploy the complete stack using the official [`docker-compose.yml`](https://github.com/lfnovo/open-notebook/blob/main/docker-compose.yml) from the `lfnovo/open-notebook` repository and configure a production-ready reverse proxy for secure HTTPS access.

## Architecture Overview

The application consists of three primary services defined in [`docker-compose.yml`](https://github.com/lfnovo/open-notebook/blob/main/docker-compose.yml). The **FastAPI back-end** runs on port 5055, the **Next.js front-end** runs on port 8502, and **SurrealDB** operates on port 8000. From version 1.1 onward, the frontend automatically proxies all `/api/*` requests to the backend internally. This means your reverse proxy only needs to expose a single port (8502), significantly reducing the attack surface and simplifying SSL termination.

The containers communicate over an internal Docker network. The frontend handles internal routing to `http://localhost:5055` for API calls, while external traffic flows through your reverse proxy to the frontend container.

## Environment Configuration

Before deploying, create a `.env` file in your project directory by copying the template from `.env.example`. The following variables are required for secure operation:

- `OPEN_NOTEBOOK_ENCRYPTION_KEY` – A secret string used for application-level encryption. Generate a strong random value (e.g., 32+ characters).
- `SURREAL_USER` and `SURREAL_PASSWORD` – Database credentials for SurrealDB authentication.

```bash

# .env

OPEN_NOTEBOOK_ENCRYPTION_KEY=your-secure-random-string-minimum-32-chars
SURREAL_USER=root
SURREAL_PASSWORD=secure-database-password

```

Never commit the `.env` file to version control. The [`docker-compose.yml`](https://github.com/lfnovo/open-notebook/blob/main/docker-compose.yml) references these variables to configure the Open Notebook and SurrealDB containers at runtime.

## Docker Compose Deployment

Create a [`docker-compose.yml`](https://github.com/lfnovo/open-notebook/blob/main/docker-compose.yml) file that pulls the official images and wires the services together. The composition defines volume mounts for persistent data and establishes network dependencies between the database and application layers.

```yaml

# docker-compose.yml

services:
  surrealdb:
    image: surrealdb/surrealdb:v2
    command: start --log info --user ${SURREAL_USER:-root} --pass ${SURREAL_PASSWORD:-root} rocksdb:/mydata/mydatabase.db
    ports: ["8000:8000"]
    volumes: ["./surreal_data:/mydata"]
    environment:
      - SURREAL_EXPERIMENTAL_GRAPHQL=true
    restart: always

  open-notebook:
    image: lfnovo/open_notebook:v1-latest
    ports: ["127.0.0.1:8502:8502"]  # Bind to localhost for reverse proxy only

    environment:
      - OPEN_NOTEBOOK_ENCRYPTION_KEY=${OPEN_NOTEBOOK_ENCRYPTION_KEY}
      - API_URL=https://notebook.example.com  # Critical for reverse proxy

      - SURREAL_URL=ws://surrealdb:8000/rpc
      - SURREAL_USER=${SURREAL_USER:-root}
      - SURREAL_PASSWORD=${SURREAL_PASSWORD:-root}
      - SURREAL_NAMESPACE=open_notebook
      - SURREAL_DATABASE=open_notebook
    volumes: ["./notebook_data:/app/data"]
    depends_on: [surrealdb]
    restart: always

```

Deploy the stack by running:

```bash
docker-compose up -d

```

The services will start on `localhost:8502` (UI) and `localhost:5055` (API), with SurrealDB available on `localhost:8000`. For integration with external Ollama instances, refer to the variant configuration in [`examples/docker-compose-ollama.yml`](https://github.com/lfnovo/open-notebook/blob/main/examples/docker-compose-ollama.yml).

## Reverse Proxy Configuration

Your reverse proxy must forward all traffic to the Next.js container on port 8502. Since the frontend handles internal API routing, you do not need separate upstream definitions for the backend.

### Nginx Configuration

Create an [`nginx.conf`](https://github.com/lfnovo/open-notebook/blob/main/nginx.conf) that includes WebSocket support for real-time features, generous timeouts for long-running AI operations (such as podcast generation), and sufficient client body size for file uploads.

```nginx

# nginx.conf

events { worker_connections 1024; }

http {
    upstream notebook {
        server open-notebook:8502;
    }

    # HTTP to 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;

        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;

        # Support large file uploads (default 1MB is insufficient)

        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";

        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;

            # Extended timeouts for AI generation tasks

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

```

Add the nginx service to your [`docker-compose.yml`](https://github.com/lfnovo/open-notebook/blob/main/docker-compose.yml):

```yaml
  nginx:
    image: nginx:alpine
    container_name: nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
    depends_on:
      - open-notebook
    restart: unless-stopped

```

### Caddy Configuration

For automatic HTTPS with Let's Encrypt, use this minimal Caddyfile:

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

```

The full documentation in [`docs/5-CONFIGURATION/reverse-proxy.md`](https://github.com/lfnovo/open-notebook/blob/main/docs/5-CONFIGURATION/reverse-proxy.md) also includes configuration examples for Traefik and other proxy solutions.

## Critical API_URL Configuration

When running behind a reverse proxy, you must explicitly set the `API_URL` environment variable in the `open-notebook` service definition. This variable overrides automatic detection and ensures the frontend generates correct absolute URLs for API callbacks and OAuth redirects.

Set this to your public HTTPS domain:

```yaml
environment:
  - API_URL=https://notebook.example.com

```

Without this variable, the application may construct internal `http://` links or localhost references, breaking authentication flows and external integrations. The container logs will confirm the runtime configuration with the message: `✅ [Config] Runtime API URL from server: https://notebook.example.com`.

## Verification and Health Checks

After deployment, verify the stack is functioning correctly:

1. **Browser validation** – Navigate to `https://notebook.example.com`. The browser console should show the runtime API URL matching your public domain.
2. **API health check** – Run `curl https://notebook.example.com/api/config` to receive a JSON response containing `"status":"ok"`.
3. **Container logs** – Execute `docker logs open-notebook` to confirm both services initialized: "Next.js ready on http://0.0.0.0:8502" and "Uvicorn running on http://0.0.0.0:5055".

If the UI fails to load or shows connection errors, verify that the `API_URL` environment variable is set and that your reverse proxy headers include `X-Forwarded-Proto`.

## Summary

- **Expose only port 8502** – The Next.js frontend in versions 1.1+ handles internal proxying to the FastAPI backend, eliminating the need to expose port 5055 publicly.
- **Set `API_URL`** – This environment variable is mandatory for reverse proxy deployments to ensure correct HTTPS URL generation.
- **Configure timeouts** – Set `proxy_read_timeout` and `proxy_send_timeout` to at least 600 seconds in your reverse proxy to accommodate long-running AI tasks.
- **Allow large uploads** – Set `client_max_body_size` to 100MB or higher in Nginx (or equivalent) to support file attachments.
- **Reference official docs** – The [`docs/5-CONFIGURATION/reverse-proxy.md`](https://github.com/lfnovo/open-notebook/blob/main/docs/5-CONFIGURATION/reverse-proxy.md) file contains platform-specific examples for Nginx, Caddy, and Traefik.

## Frequently Asked Questions

### Do I need to expose the FastAPI backend (port 5055) through my reverse proxy?

No. Starting with version 1.1, the Next.js frontend automatically proxies all `/api/*` requests to the FastAPI backend internally. Configure your reverse proxy to forward traffic only to port 8502. The backend should remain accessible only within the Docker network for security.

### Why is my Open Notebook UI generating HTTP links instead of HTTPS?

This occurs when the `API_URL` environment variable is not set or when your reverse proxy fails to forward the `X-Forwarded-Proto` header. Set `API_URL=https://your-domain.com` in the `open-notebook` service environment variables, and ensure your proxy passes `X-Forwarded-Proto $scheme` to the container.

### How do I handle large file uploads through the reverse proxy?

File uploads in Open Notebook can exceed the default 1MB limit of most reverse proxies. In Nginx, set `client_max_body_size 100M;` in your server block. For Caddy, this is handled automatically, but you may need to adjust the `read_timeout` settings for slow connections during upload.

### Can I deploy Open Notebook without SurrealDB?

No. SurrealDB is a required dependency for the application stack. The [`docker-compose.yml`](https://github.com/lfnovo/open-notebook/blob/main/docker-compose.yml) defines SurrealDB as a service dependency that must be running before the Open Notebook container starts. The database stores all user data, AI conversation history, and application configuration.