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:
| Variable | Value |
|---|---|
JWT_SECRET | 64 random hex chars (openssl rand -hex 32) |
ENCRYPTION_KEY | 64 random hex chars (openssl rand -hex 32) |
LLM_PROVIDER | openai, anthropic, ollama, or google |
LLM_API_KEY | Your API key for the chosen provider |
NESTFLEET_DOMAIN | Your domain, e.g. nestfleet.example.com |
POSTGRES_PASSWORD | A strong random password for the database |
CONSOLE_ORIGIN | https://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:
| Service | Description |
|---|---|
postgres | PostgreSQL 16 database. Data is persisted in a named Docker volume. |
api | The Hono API server. Runs database migrations on startup. |
worker | pg-boss background worker for AI jobs (triage, auto-reply, change prep). |
console | Next.js admin console served on port 3001 internally. |
caddy | Reverse 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:
- Set
REGISTRATION_ENABLED=truein your.envfile. - Restart the API:
docker compose -f docker-compose.prod.yml restart api - Navigate to
https://your-domain/signupand create your account. - Assign yourself the Admin role via the database or by promoting your account through the API.
- Set
REGISTRATION_ENABLED=falseand 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).