Notebook++

Self-hosted installation — Docker Compose

This guide installs Notebook++ as a self-contained Docker Compose stack — the app plus its PostgreSQL database — using the prebuilt image from GitHub Container Registry (GHCR). No build step, reverse proxy, or extra services are required.

Before you begin. You need a host with Docker and Docker Compose installed. The app image is public on GHCR, so no login or token is needed to pull it.

Steps

1

Get the compose file

Put docker-compose.standalone.yml (from the repository) into an empty folder. It defines the whole stack, so no other files are needed.

2

Generate three secrets

Each command prints one random value (use Git Bash or WSL on Windows):

openssl rand -hex 16     # -> DB_PASSWORD
openssl rand -base64 48  # -> SESSION_PASSWORD  (must be ≥ 32 characters)
openssl rand -hex 32     # -> ENCRYPTION_KEY
3

Create a .env file

Place it beside the compose file. Only the first three are required:

DB_PASSWORD=<from openssl>
SESSION_PASSWORD=<from openssl>
ENCRYPTION_KEY=<from openssl>

# optional
APP_PORT=3000
ALLOW_REGISTRATION=true
NUXT_PUBLIC_APP_URL=https://notes.mywebsite.com
NUXT_SESSION_COOKIE_SECURE=false
SMTP_URL=
4

Start the stack

docker compose -f docker-compose.standalone.yml up -d

Database migrations run automatically at first boot.

5

Open the app and register

Visit https://notes.mywebsite.com and register the first account — it arrives pre-loaded with the starter content. Turn sign-ups off afterwards in Settings → Registration to keep the instance private.

Environment variables

Variable Required Purpose How to generate / default
DB_PASSWORD Yes Password for the bundled PostgreSQL database. openssl rand -hex 16
SESSION_PASSWORD Yes Secret that seals login-session cookies. Must be at least 32 characters. openssl rand -base64 48
ENCRYPTION_KEY Yes Secret used to encrypt saved AI-provider keys at rest (any length; hashed to a 256-bit key). openssl rand -hex 32
APP_PORT No Host port the app is published on. Default 3000
IMAGE_TAG No Image version to run (e.g. a pinned release instead of latest). Default latest
ALLOW_REGISTRATION No Whether new sign-ups are allowed by default (also toggleable in Settings). Default true
NUXT_PUBLIC_APP_URL No Public base URL, used to build password-reset links. Default https://notes.mywebsite.com
NUXT_SESSION_COOKIE_SECURE No Marks the session cookie Secure. Set true only when serving over HTTPS; keep false for plain-HTTP localhost/LAN (browsers reject a Secure cookie over http on a non-localhost IP). Default false
SMTP_URL No SMTP server for password-reset email, e.g. smtp://user:pass@host:587. Left empty, the reset link is written to the container log instead. Default empty

Keep the three secrets safe and stable. Changing SESSION_PASSWORD logs everyone out; changing ENCRYPTION_KEY makes previously-saved AI keys undecryptable; changing DB_PASSWORD after the first run means the database must be recreated.

Data & backups

Everything lives in two Docker named volumes — notebookpp-pgdata (the database) and notebookpp-uploads (uploaded files). They survive restarts and image updates; back them up to back up the app.

Updating

Pull the newer image and recreate the containers — migrations run automatically:

docker compose -f docker-compose.standalone.yml pull
docker compose -f docker-compose.standalone.yml up -d

To wipe everything and start clean, run docker compose -f docker-compose.standalone.yml down -v before up — this deletes both volumes.

HTTPS on a LAN. Over plain HTTP on a non-localhost IP, browsers disable some features (pasting into the canvas, installing the app as a PWA). To use those across your network, serve the app over HTTPS through a reverse proxy and set NUXT_SESSION_COOKIE_SECURE=true.