Skip to main content

Install with Docker Compose

One host, one DNS name, one command. The deployment runs the Norn API, web dashboard, worker, database migrations, and authorisation policy seed, alongside PostgreSQL, Valkey, and a Caddy reverse proxy that obtains and renews the TLS certificate.

Requirements

  • a Linux host with Docker Engine 25 or newer and Docker Compose v2.23 or newer
  • 2 CPU cores, 4 GB of memory, and disk for the database and attachments
  • one DNS record pointing at the host, resolving before you start
  • ports 80 and 443 reachable from the internet, which certificate issuance requires

The bundled PostgreSQL and Valkey run on the same host as Norn and suit a team-sized installation. For data that cannot be recreated, use managed or replicated services as described in external data services. The application workloads are the same in either configuration.

Install

curl -fsSL https://get.norn.so | bash

The installer asks for the domain and an address for certificate notices, generates the database, cache, and encryption secrets, writes them to .env, and starts the stack. It works without prompts too:

curl -fsSL https://get.norn.so | bash -s -- --domain norn.example.com --email [email protected]

It writes into ./norn when piped, or into its own directory when you download it first. Set NORN_DIR to choose another.

When it finishes, open the URL it prints and create the first account. Norn shows the confirmation link on screen until email is configured.

Install without the script

The installer only writes a .env and calls docker compose. Doing that by hand:

mkdir -p /opt/norn && cd /opt/norn

curl -fsSLO https://get.norn.so/compose.yaml
curl -fsSLO https://get.norn.so/.env.example

cp .env.example .env
chmod 600 .env

Generate the three secrets and put them in .env:

openssl rand -hex 32 # POSTGRES_PASSWORD
openssl rand -hex 32 # VALKEY_PASSWORD
openssl rand -base64 32 # NORN_SECURITY_ENCRYPTION_KEY

The two service passwords travel inside a connection string, so they must stay URL-safe. The encryption key is read as 32 bytes of base64 and is rejected at any other length.

Set the public origin and the certificate contact, then start:

.env
NORN_APP_BASE_URL=https://norn.example.com
docker compose up -d

NORN_APP_BASE_URL is the value everything else follows. Caddy takes its site address, its certificate, and its scheme from it; the dashboard sends it as the Origin header; and the API refuses every write whose origin does not match.

danger

NORN_SECURITY_ENCRYPTION_KEY protects credentials stored by Norn. Losing or replacing it makes existing encrypted data unreadable. Copy it out of .env and keep it somewhere outside the host.

What the first start does

PostgreSQL and Valkey come up and report healthy. A one-shot migrate container applies the embedded database migrations. A one-shot seed container writes the authorisation policy. Only then do the API, worker, dashboard, and Caddy start. Both one-shot containers run again on every start, which is how an upgrade applies its migrations.

Caddy requests the certificate on first start. Until that finishes, the site is not reachable over HTTPS.

Email

Invitations and password recovery need outbound mail. Until SMTP is configured, Norn shows sign-up and invitation links on screen instead of sending them, which is enough to create the first account and no further.

.env
NORN_SMTP_HOST=smtp.epostix.com
NORN_SMTP_PORT=587
NORN_SMTP_USERNAME=<smtp-username>
NORN_SMTP_PASSWORD=<smtp-password>
./setup.sh restart

The host and the sender address are set together or not at all. Test invitation and recovery mail before opening the instance.

Close signups

An instance accepts signups until you turn them off. Once the administrator account exists:

.env
NORN_INSTANCE_SIGNUPS_OPEN=false
./setup.sh restart

Every remaining setting is listed in the environment variable reference and can be added to .env.

Production checklist

Before adding users, confirm that you have:

  • a tested backup of PostgreSQL and the attachment volume
  • an offline recovery copy of NORN_SECURITY_ENCRYPTION_KEY
  • SMTP configured and account recovery tested
  • NORN_VERSION pinned to a release you chose
  • a host firewall that exposes only ports 80 and 443
  • a tested upgrade and restore procedure

Continue with the shared Norn configuration, then review the Compose-specific settings and operations.