NoteGenNOTEGEN.

Self-hosting

Deploy NoteGen Server with Docker Compose, then configure HTTPS, initialize the instance, connect clients, and maintain it.

NoteGen Server provides accounts, device pairing, realtime sync, team collaboration, and account administration for NoteGen. This guide is for users running an experimental instance on their own Linux server or trusted local network.

NoteGen Server is experimental. Deployment, configuration, and database structures may change. Always keep your local NoteGen Markdown files and never treat an experimental instance as the only copy of important data.

Choose a deployment method

MethodBest forRequirements
Docker Compose (recommended)Quick trials and personal or small-team instancesDocker Engine and Docker Compose v2
Run from sourceReading the implementation, debugging the protocol, and contributingNode.js 22+, pnpm 10.20.0, and PostgreSQL 17

Use Docker Compose for production-like or long-running experiments. Source mode is primarily for development; do not expose pnpm dev directly as a production service.

Deploy with Docker Compose

The default Compose stack starts NoteGen Server and PostgreSQL 17. Two separate volumes store the database and attachments. The service listens only on 127.0.0.1:3789 on the host by default.

The official image is ghcr.io/codexu/note-gen-server and supports linux/amd64 and linux/arm64. Compose defaults to the latest image published from the release branch, so the server does not need Node.js, pnpm, or a local source build.

1. Prepare the server

Before starting, confirm that:

  • Docker Engine and Docker Compose v2 are installed;
  • the server can access ghcr.io;
  • remote deployments have a domain pointed at the server;
  • the firewall exposes only SSH, HTTP, and HTTPS, never PostgreSQL.

2. Download the deployment configuration

git clone https://github.com/codexu/note-gen-server.git
cd note-gen-server
cp .env.docker.example .env

compose.yaml defines the deployment topology. .env contains configuration for this instance. Never commit the real .env file to Git.

3. Configure environment variables

Run this command twice to generate two different random values:

openssl rand -hex 32

Edit .env and verify at least these values:

VariableValue
POSTGRES_PASSWORDThe first random value, used only by this PostgreSQL instance
AUTH_SECRETThe second random value; do not casually rotate it after launch
PUBLIC_BASE_URLThe exact address used by NoteGen clients, without a path or trailing slash
SERVER_BIND_ADDRESSKeep 127.0.0.1 and expose the service through a reverse proxy
NOTEGEN_SERVER_IMAGEDefaults to latest; pin a full version such as 0.1.0 for reproducible deployments

For a local-only trial:

PUBLIC_BASE_URL=http://127.0.0.1:3789

Remote deployments must use HTTPS:

PUBLIC_BASE_URL=https://sync.example.com

4. Start the services

docker compose pull
docker compose up -d
docker compose ps

By default, Compose pulls:

ghcr.io/codexu/note-gen-server:latest

On first startup, the server waits for PostgreSQL and applies pending database migrations. Once both services report healthy, check readiness:

curl --fail http://127.0.0.1:3789/health/ready

A successful response means the containers and database can accept requests. If readiness fails, start with Troubleshooting.

5. Configure HTTPS

Remote access requires Caddy, Nginx, or Traefik in front of NoteGen Server. The proxy must support:

  • WebSocket Upgrade;
  • the Authorization, Range, and X-Request-Id headers;
  • request bodies larger than an attachment part;
  • streaming responses from /v1/sync/events without response buffering.

Minimal Caddy configuration:

sync.example.com {
  reverse_proxy 127.0.0.1:3789
}

Caddy obtains and renews HTTPS certificates automatically. Continue only after the account page opens at https://sync.example.com.

Set TRUST_PROXY=true only when the proxy and containers are on a trusted network and external traffic cannot bypass the proxy to reach the server port directly.

6. Initialize the instance

Open PUBLIC_BASE_URL in a browser and follow the installer to:

  1. choose an instance name;
  2. create the first administrator account;
  3. sign in to the account portal;
  4. set registration to disabled, invitation-only, or public.

Public registration increases moderation and maintenance work. Keep personal instances closed and create time-limited invitations when another user needs access.

7. Connect NoteGen

In NoteGen sync settings, select NoteGen Server and enter the exact PUBLIC_BASE_URL, then register or sign in.

Validate the connection in this order:

  1. create a test note on device A;
  2. confirm that device B receives it;
  3. briefly take one device offline and edit the test content on both devices;
  4. reconnect and confirm sync continues while local Markdown remains available.

See Sync for Git, S3, WebDAV, and cloud-drive options.

Upgrade the instance

The latest image follows releases from the release branch and may still include configuration or database changes. Before upgrading, review repository notes and create a consistent backup of PostgreSQL and attachment data.

cd note-gen-server
git pull --ff-only
docker compose pull
docker compose up -d
docker compose ps

Database migrations run during service startup. Recheck the instance after an upgrade:

curl --fail http://127.0.0.1:3789/health/ready
docker compose logs --tail=200 server

To pin the current version, replace latest in NOTEGEN_SERVER_IMAGE with a full version tag such as ghcr.io/codexu/note-gen-server:0.1.0. A sha-<commit> tag can also reproduce a specific build for troubleshooting.

Data and backups

The default deployment stores two groups of data:

DataDefault location
Accounts, devices, sync cursors, and object versionsDocker postgres_data volume
Attachments, blobs, and server-generated filesDocker notegen_data volume

A backup must cover PostgreSQL and notegen_data at a consistent point in time, and recovery must be verified in an isolated environment. Backing up only one part is incomplete.

Complete backup and restore tooling is still being developed. Until it is stable, use an externally audited backup process appropriate for your environment and continue keeping local Markdown on every device.

Stop containers while preserving data:

docker compose down

Do not run docker compose down -v while the data is needed. -v requests deletion of the Compose-managed volumes.

Routine maintenance

Check container state and recent logs:

docker compose ps
docker compose logs --tail=200 server
docker compose logs --tail=200 postgres

Follow server logs:

docker compose logs -f server

Check readiness and advertised capabilities:

curl --fail http://127.0.0.1:3789/health/ready
curl --fail http://127.0.0.1:3789/v1/capabilities

Run from source

Source mode is for debugging and contributions. Install Node.js 22 or newer, pnpm 10.20.0, and PostgreSQL 17, then run:

git clone https://github.com/codexu/note-gen-server.git
cd note-gen-server
createuser notegen
createdb -O notegen notegen
pnpm install
cp .env.example .env
pnpm dev

Set DATABASE_URL, AUTH_SECRET, and PUBLIC_BASE_URL in .env. In development, the API listens on 3789 and the account portal on 3790 by default.

See the contribution guide in the NoteGen Server repository for project structure, change boundaries, and contribution checks.

Troubleshooting

SymptomCheck and action
Image pull failsConfirm access to ghcr.io, then check proxy and DNS settings
PostgreSQL never becomes healthyInspect docker compose logs --tail=200 postgres, free disk space, and POSTGRES_PASSWORD
Server never becomes healthyInspect server logs and confirm PostgreSQL is ready and required .env values are set
Browser works but the client cannot connectMatch the client address exactly to PUBLIC_BASE_URL and validate the HTTPS certificate
Realtime sync does not triggerConfirm the reverse proxy supports WebSocket Upgrade
Attachment upload returns 413Increase the reverse proxy request-body limit
Sign-in fails after restartConfirm AUTH_SECRET was not changed and the server clock is correct

When opening an issue, include the operating system and CPU architecture, deployment method, image tag, reverse proxy, reproduction steps, and redacted container logs. Never publish .env, tokens, passwords, or recovery keys.

Deployment checklist

  • POSTGRES_PASSWORD and AUTH_SECRET are different random values;
  • PUBLIC_BASE_URL exactly matches the address used by clients;
  • public access uses a valid HTTPS certificate;
  • PostgreSQL and internal service ports are not directly exposed;
  • the reverse proxy supports WebSocket and large attachment requests;
  • PostgreSQL and attachment data have a coordinated backup;
  • local Markdown is retained and at least one multi-device sync check has passed.