Skip to main content

Deploying the intranet

The intranet always runs as a container — Docker or Podman. There is no VM/bare-metal install path: the image bundles the SvelteKit server, the background worker, and the migration/seed tooling. The only external dependency is PostgreSQL and an OIDC provider (Authentik) for sign-in.

Audience

This section is for whoever deploys and operates the service. The rest of the guide (Getting started, Engineer, Reviewer, …) is for end users.

What runs​

The stack is a handful of containers built from one image:

ContainerCommandRole
dbpostgres:16-alpineDatabase (bundled for convenience)
migratepnpm db:migrateApplies migrations once, then exits
appnode buildWeb server on port 3000
workernode --import tsx src/worker/index.tsTransactional-outbox dispatcher

app and worker start only after migrate completes successfully.

Requirements​

  • Docker Engine 24+ with Compose v2, or Podman 4+ with podman compose.
  • PostgreSQL 16 — the compose file bundles one, but any reachable Postgres works; set DATABASE_URL.
  • An OIDC provider. The reference provider is Authentik; any OIDC/OAuth2 provider works (see Single sign-on).
  • Outbound network from the container to the provider.
  • For production: a TLS-terminating reverse proxy and a hostname.

Node, pnpm, or Postgres are not needed on the host.

Image properties​

  • Built with @sveltejs/adapter-node (ADAPTER=node), served by node build.
  • Runs as the non-root node user.
  • Exposes port 3000; healthcheck polls GET /login.
  • Contains the worker and migration/seed entrypoints (overridden per service).
  1. Quick start — stand up a local stack.
  2. Configuration — every environment variable.
  3. Single sign-on with Authentik.
  4. Production hardening and Operations.