Skip to content

Getting Started with Self Hosting

How to run Navis Docs on your own infrastructure.

Prerequisites

This guide walks through a Docker Compose deployment of Navis Docs. It is intended for teams who want to run the app on their own server or behind an existing reverse proxy.

  • Docker Engine with Docker Compose. Docker 23 or newer is recommended because BuildKit is enabled by default.
  • A reverse proxy such as Nginx, Caddy, Traefik, or your platform proxy
  • Object storage credentials from either Supabase Storage or an S3-compatible provider
  • Resend credentials for email sign-in, invitations, and transactional mail
  • Optional: Google OAuth credentials if you want Google sign-in

The bundled Compose file starts the app, Postgres with pgvector, and Redis. It exposes the app on port 3000.

Setup steps

1. Clone the repository

Clone Navis Docs onto the server where you will run Docker Compose:

git clone https://github.com/navis-docs/navis-docs.git
cd navis-docs

2. Create your environment file

Copy the example file, then edit it with your production values:

cp .env.example .env

For the bundled Docker Compose database and Redis services, make sure these URLs use the service names db and redis:

DATABASE_URL=postgresql://postgres:password@db:5432/navis_docs
REDIS_URL=redis://redis:6379

At minimum, also set:

  • NEXT_PUBLIC_APP_URL and NEXTAUTH_URL to your public URL, for example https://docs.your-domain.com
  • AUTH_SECRET for Auth.js session signing
  • AI_KEY_ENCRYPTION_SECRET for organization-provided AI API keys encrypted in the database
  • RESEND_API_KEY and EMAIL_FROM for email
  • Storage provider credentials, covered below

3. Generate secrets

Generate separate values for AUTH_SECRET and AI_KEY_ENCRYPTION_SECRET:

openssl rand -base64 32

Keep AI_KEY_ENCRYPTION_SECRET backed up. If it changes, existing encrypted AI keys in the database become permanently unreadable and must be re-entered.

4. Choose storage

Navis Docs needs object storage for procedure images, procedure imports, and audit exports. Choose either Supabase Storage or S3-compatible storage.

S3-compatible storage

Use this option for AWS S3, Cloudflare R2, Garage, MinIO, and similar providers. Create the three buckets first, then set:

STORAGE_PROVIDER=s3
S3_ENDPOINT=              # leave blank for AWS S3; set for R2, Garage, or MinIO
S3_REGION=auto            # use your AWS region for AWS S3
S3_ACCESS_KEY_ID=
S3_SECRET_ACCESS_KEY=
S3_PROCEDURE_IMAGES_BUCKET=procedure-images
S3_PROCEDURE_IMPORTS_BUCKET=procedure-imports
S3_PROCEDURE_AUDITS_BUCKET=audit-exports

For many MinIO and Garage deployments, also set S3_FORCE_PATH_STYLE=true.

Supabase Storage

Use this option if you already have a Supabase project and want to store files there:

STORAGE_PROVIDER=supabase
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

Create these Supabase Storage buckets:

  • procedure-images
  • procedure-imports
  • audit-exports

5. Configure Google OAuth

If you want Google sign-in, create a web OAuth client in Google Cloud Console and register this redirect URI:

https://your-domain.com/api/auth/callback/google

Then add the credentials to your environment:

GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=

6. Build and start

Build the image and start all services:

docker compose up --build

When the container starts, it runs database migrations automatically and then starts the Next.js server. Locally, open http://localhost:3000. In production, point your reverse proxy at the app container on port 3000.

Build-time environment variables

Most environment variables are read when the container starts. Variables prefixed with NEXT_PUBLIC_ are different: Next.js embeds them into the browser bundle during docker compose up --build.

The important self-hosting value is:

NEXT_PUBLIC_DEPLOY_MODE=self-hosted

If you change NEXT_PUBLIC_DEPLOY_MODE or NEXT_PUBLIC_APP_URL, rebuild the image. If you only change runtime values such as database, Redis, email, or storage credentials, restart the container.

# Rebuild after NEXT_PUBLIC_* changes
docker compose up --build

# Restart after runtime-only environment changes
docker compose up -d

Service architecture

  • app: Navis Docs Next.js app, exposed on port 3000
  • db: Postgres with pgvector, persisted in the db_data Docker volume
  • redis: Redis, persisted in the redis_data Docker volume

Upgrading

Pull the latest code, rebuild the image, and start the services again:

git pull
docker compose pull
docker compose up --build

Migrations run automatically before the app starts. Before major upgrades, back up your Postgres data, .env file, and object storage buckets.

Troubleshooting

Check service status

docker compose ps

Follow app logs

docker compose logs -f app

App cannot connect to Postgres

Inside Docker Compose, use the service hostname db, not localhost:

DATABASE_URL=postgresql://postgres:password@db:5432/navis_docs

OAuth redirect mismatch

Check that Google Cloud Console contains the exact redirect URI for your deployment:

https://your-domain.com/api/auth/callback/google

Cloud-only UI still appears

Set NEXT_PUBLIC_DEPLOY_MODE=self-hosted and rebuild the image with docker compose up --build.