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.
Put docker-compose.standalone.yml (from the repository) into an empty folder.
It defines the whole stack, so no other files are needed.
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
.env filePlace 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=
docker compose -f docker-compose.standalone.yml up -d
Database migrations run automatically at first boot.
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.
| 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.
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.
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.