NestFleetDocs

Docker Compose

The recommended way to self-host NestFleet is with the production Docker Compose stack. It starts five services — PostgreSQL, the Hono API, the Next.js console, the pg-boss worker, and Caddy as a reverse proxy — and handles TLS automatically via Let's Encrypt.

Prerequisites

  • A Linux server (or Mac/Windows with Docker Desktop) with Docker Engine 24+ and Docker Compose v2
  • A domain name pointed at your server's public IP (A record) — required for automatic TLS
  • Ports 80 and 443 open in your firewall
  • Git installed on the server

Step 1 — Clone the repository

git clone https://github.com/nestfleet/nestfleet.git
cd nestfleet

Step 2 — Create your .env file

Copy the example file and open it in your editor:

cp .env.example .env
nano .env

Step 3 — Generate secrets

You need cryptographically random values for JWT_SECRET and ENCRYPTION_KEY. Run this command twice — once for each:

openssl rand -hex 32

This produces 64 hex characters, which is exactly the format both secrets expect.

Step 4 — Set the minimum required variables

At minimum, you must set these variables in your .env file before starting the stack:

VariableValue
JWT_SECRET64 random hex chars (openssl rand -hex 32)
ENCRYPTION_KEY64 random hex chars (openssl rand -hex 32)
LLM_PROVIDERopenai, anthropic, ollama, or google
LLM_API_KEYYour API key for the chosen provider
NESTFLEET_DOMAINYour domain, e.g. nestfleet.example.com
POSTGRES_PASSWORDA strong random password for the database
CONSOLE_ORIGINhttps://your-domain (same as NESTFLEET_DOMAIN with https://)

See the Environment Variables reference for the full list of options including email, Telegram, Slack, and Sentry configuration.

Step 5 — Start the stack

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

This starts the following services:

ServiceDescription
postgresPostgreSQL 16 database. Data is persisted in a named Docker volume.
apiThe Hono API server. Runs database migrations on startup.
workerpg-boss background worker for AI jobs (triage, auto-reply, change prep).
consoleNext.js admin console served on port 3001 internally.
caddyReverse proxy with automatic Let's Encrypt TLS. Terminates HTTPS and routes traffic to api and console.

Step 6 — Create the first admin user

Self-hosted installs ship with public registration disabled. To create the first admin account:

  1. Set REGISTRATION_ENABLED=true in your .env file.
  2. Restart the API: docker compose -f docker-compose.prod.yml restart api
  3. Navigate to https://your-domain/signup and create your account.
  4. Assign yourself the Admin role via the database or by promoting your account through the API.
  5. Set REGISTRATION_ENABLED=false and restart the API again.

Leave REGISTRATION_ENABLED=false in production. With it enabled, anyone who can reach your domain can create an account. Invite additional users from Settings → Team Members once you are logged in as admin.

Step 7 — Verify the deployment

Check the health endpoint to confirm the API and database are running:

curl https://your-domain/health

A healthy instance returns:

{"status":"ok","db":"ok"}

Viewing logs

# Tail all services
docker compose -f docker-compose.prod.yml logs -f

# Tail a specific service
docker compose -f docker-compose.prod.yml logs -f api

Stopping the stack

docker compose -f docker-compose.prod.yml down

This stops and removes containers but preserves the PostgreSQL data volume. Add -v to also remove volumes (destructive — deletes all data).