Skip to main content

Docker Deployment

Run NotebookLM MCP Server in a Docker container for isolated, reproducible deployments.

Quick Start

# Build and start
docker-compose up -d

# View logs
docker-compose logs -f

# Stop
docker-compose down

Using Docker CLI

# Build image
docker build -t notebooklm-mcp .

# Run container
docker run -d \
--name notebooklm-mcp \
--restart unless-stopped \
-p 3000:3000 \
-p 6080:6080 \
-v notebooklm-data:/data \
-e HEADLESS=true \
-e STEALTH_ENABLED=true \
-e NOTEBOOKLM_UI_LOCALE=fr \
notebooklm-mcp

Ports

PortDescription
3000HTTP REST API
6080noVNC web interface (for authentication)

First-Time Authentication via noVNC

Docker includes a noVNC server for visual browser access, required for initial Google authentication.

Step 1: Open noVNC

Open in your browser:

http://localhost:6080/vnc.html

Step 2: Trigger Authentication

curl -X POST http://localhost:3000/setup-auth \
-H "Content-Type: application/json" \
-d '{"show_browser": true}'

Step 3: Login in noVNC

  1. The Chromium browser appears in the noVNC window
  2. Complete Google login
  3. Authentication is saved automatically
  4. Browser closes when done

Verify Authentication

curl http://localhost:3000/health
# → {"success":true,"data":{"authenticated":true,...}}

Alternative: Copy Existing Credentials

If you've already authenticated locally:

# Copy from local machine to container
docker cp ~/.local/share/notebooklm-mcp/. notebooklm-mcp:/data/

# Restart container
docker restart notebooklm-mcp

Configuration

Environment Variables

VariableDefaultDescription
HTTP_PORT3000HTTP server port
HTTP_HOST0.0.0.0HTTP server host
HEADLESStrueRun browser headless
STEALTH_ENABLEDtrueEnable anti-detection
NOTEBOOKLM_DATA_DIR/dataData directory path
NOTEBOOKLM_UI_LOCALEfrUI language (fr/en)
AUTO_LOGIN_ENABLEDfalseEnable auto-login
ENABLE_VNCtrueEnable noVNC server
NOVNC_PORT6080noVNC web port

Custom Configuration

Edit docker-compose.yml to customize:

environment:
- HEADLESS=true
- NOTEBOOKLM_UI_LOCALE=en
- AUTO_LOGIN_ENABLED=true

Data Persistence

All data is stored in the /data volume:

/data/
├── library.json # Notebook library
├── chrome_profile/ # Chrome profile (Google session)
├── browser_state/ # Browser state backup
├── accounts.json # Account configuration
├── accounts/ # Per-account data
│ └── account-xxx/
│ ├── credentials.enc.json
│ ├── quota.json
│ └── state.json
└── encryption.key # Encryption key

Backup

# Backup data volume
docker run --rm \
-v notebooklm-mcp-data:/data:ro \
-v $(pwd):/backup \
alpine tar czf /backup/notebooklm-backup.tar.gz -C /data .

# Restore
docker run --rm \
-v notebooklm-mcp-data:/data \
-v $(pwd):/backup \
alpine tar xzf /backup/notebooklm-backup.tar.gz -C /data

NAS Deployment (Synology, QNAP)

Build and Export

# On your local machine
npm run build
docker build -t notebooklm-mcp:latest .
docker save notebooklm-mcp:latest | gzip > notebooklm-mcp.tar.gz

Upload and Deploy

# Upload to NAS
scp notebooklm-mcp.tar.gz user@nas:/volume1/docker/

# SSH to NAS and load
ssh user@nas
docker load < /volume1/docker/notebooklm-mcp.tar.gz

# Run container
docker run -d \
--name notebooklm-mcp \
--restart unless-stopped \
-p 3000:3000 \
-p 6080:6080 \
-v /volume1/docker/notebooklm/data:/data \
-e HEADLESS=true \
-e STEALTH_ENABLED=true \
-e NOTEBOOKLM_UI_LOCALE=fr \
notebooklm-mcp:latest

Authenticate via noVNC

  1. Open http://nas-ip:6080/vnc.html
  2. Run setup-auth command
  3. Complete Google login in VNC window

Resource Requirements

ResourceMinimumRecommended
Memory512 MB2 GB
CPU1 core2 cores
Disk500 MB2 GB

Chromium uses significant memory. Adjust limits in docker-compose.yml:

deploy:
resources:
limits:
memory: 4G
reservations:
memory: 1G

Troubleshooting

Container won't start

# Check logs
docker logs notebooklm-mcp

# Check container status
docker ps -a

Browser issues

If Chromium fails to launch:

  1. Ensure sufficient memory (minimum 512MB)
  2. Check logs for errors
  3. Try rebuilding: docker build --no-cache -t notebooklm-mcp .

noVNC not accessible

  1. Verify port 6080 is exposed
  2. Check firewall rules
  3. Verify container is running: docker ps

Authentication issues

# Check health endpoint
curl http://localhost:3000/health

# If not authenticated, use noVNC method above

Permission issues

# Fix volume permissions
docker run --rm -v notebooklm-mcp-data:/data alpine chown -R 1000:1000 /data

Production Deployment

With Reverse Proxy (nginx)

server {
listen 80;
server_name notebooklm.example.com;

location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_cache_bypass $http_upgrade;
}

# noVNC (restrict access!)
location /vnc {
proxy_pass http://localhost:6080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
# Add authentication here!
}
}

Security Considerations

  1. Don't expose port 6080 publicly - noVNC gives browser access
  2. Use a reverse proxy with authentication for production
  3. Regular backups of the data volume
  4. Monitor container health using the healthcheck endpoint

Architecture

Docker Container
├── Node.js HTTP Server (port 3000)
├── Xvfb (:99) - Virtual display
├── x11vnc - VNC server
├── websockify/noVNC (port 6080) - Web VNC
└── Chromium browser

User → noVNC (6080) → VNC → Xvfb → Chromium
User → HTTP API (3000) → Node.js → Chromium