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-docs2. Create your environment file
Copy the example file, then edit it with your production values:
cp .env.example .envFor 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:6379At minimum, also set:
NEXT_PUBLIC_APP_URLandNEXTAUTH_URLto your public URL, for examplehttps://docs.your-domain.comAUTH_SECRETfor Auth.js session signingAI_KEY_ENCRYPTION_SECRETfor organization-provided AI API keys encrypted in the databaseRESEND_API_KEYandEMAIL_FROMfor email- Storage provider credentials, covered below
3. Generate secrets
Generate separate values for AUTH_SECRET and AI_KEY_ENCRYPTION_SECRET:
openssl rand -base64 32Keep 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-exportsFor 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-keyCreate these Supabase Storage buckets:
procedure-imagesprocedure-importsaudit-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/googleThen 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 --buildWhen 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-hostedIf 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 -dService architecture
- app: Navis Docs Next.js app, exposed on port
3000 - db: Postgres with pgvector, persisted in the
db_dataDocker volume - redis: Redis, persisted in the
redis_dataDocker volume
Upgrading
Pull the latest code, rebuild the image, and start the services again:
git pull
docker compose pull
docker compose up --buildMigrations 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 psFollow app logs
docker compose logs -f appApp cannot connect to Postgres
Inside Docker Compose, use the service hostname db, not localhost:
DATABASE_URL=postgresql://postgres:password@db:5432/navis_docsOAuth redirect mismatch
Check that Google Cloud Console contains the exact redirect URI for your deployment:
https://your-domain.com/api/auth/callback/googleCloud-only UI still appears
Set NEXT_PUBLIC_DEPLOY_MODE=self-hosted and rebuild the image with docker compose up --build.