Skip to content

Deployment

import { Aside } from ‘@astrojs/starlight/components’;

This guide matches the docker-compose.prod.yml and .env.example files in the repository. For day-to-day local development, see Installation.

DependencyMinimum
Docker24+
Docker Compose v22.20+
RAM (app + Postgres + Redis)2 GB recommended (1 GB minimum tight)

TLS termination is usually handled by a reverse proxy (Nginx, Traefik, Caddy) or your platform (Coolify, Kubernetes ingress).

Terminal window
git clone https://github.com/defcon1702/orimora.git orimora
cd orimora
cp .env.example .env

Fill all variables marked as required in .env. The Compose file expects at least:

  • APP_URL — public HTTPS URL, e.g. https://wiki.example.com
  • POSTGRES_PASSWORD, REDIS_PASSWORD — strong random values
  • SESSION_SECRET, MAGIC_LINK_SECRET, LLM_ENCRYPTION_KEY — 64-character hex strings (32 bytes each)

Use the same pattern as in the root DEPLOYMENT.md:

Terminal window
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" # repeat for each *64 hex* secret

Keep generated values in a password manager; never commit .env.

Terminal window
docker compose -f docker-compose.prod.yml up -d --build

Required on first deploy and after upgrades that ship new migration files:

Terminal window
docker compose -f docker-compose.prod.yml exec app yarn db:migrate
Terminal window
curl -s http://localhost:3000/api/health

Then open APP_URL in the browser and complete onboarding if this is a fresh database.

The table below aligns with .env.example. Variable names differ from older drafts that used SECRET_KEY or PUBLIC_BASE_URL.

VariablePurpose
APP_URLCanonical public URL — used in links, OAuth redirects, magic-link URLs
DATABASE_URLSet automatically in Compose from POSTGRES_*; custom installs must point to PostgreSQL 16+
REDIS_URLSet automatically in Compose from REDIS_PASSWORD
SESSION_SECRETSigns session cookies
MAGIC_LINK_SECRETSigns magic-link tokens
LLM_ENCRYPTION_KEYAES-256-GCM for stored LLM API keys (required even if AI is off)
POSTGRES_PASSWORDDatabase user password (Compose)
REDIS_PASSWORDRedis ACL password (Compose)
VariablePurpose
CRON_SECRETBearer token for POST /api/admin/cron.cleanup (scheduled trash purge, reminders)
COLLAB_SECRETShared secret for Yjs / Hocuspocus collaboration
COLLAB_MAX_CONNECTIONSCap simultaneous collab sockets (default 100 in Compose)
SMTP_*Outbound email for magic links (SMTP_PASSWORD in .env.example)
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRETGoogle OAuth
OIDC_*Generic OIDC provider
S3_*Object storage for attachments (when configured)

Full column-style reference: DEPLOYMENT.md in the repo.

Terminate TLS at Nginx, Caddy, or Traefik and proxy to the app container (port 3000 inside the network). You must preserve:

  • Host
  • X-Forwarded-For
  • X-Forwarded-Proto (HTTPS detection)
  • WebSocket upgrade headers for /collab

Example Nginx location (HTTP → app):

location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
Terminal window
git pull
docker compose -f docker-compose.prod.yml build app
docker compose -f docker-compose.prod.yml up -d
docker compose -f docker-compose.prod.yml exec app yarn db:migrate

Watch application logs during the first request after a schema change.

IssueChecks
OAuth redirect mismatchAPP_URL must exactly match the URL in Google / OIDC console
Redis connection errorsPassword matches REDIS_URL; container healthy
502 from proxyApp not listening on expected port; WebSocket path blocked
Migrations failBackup DB first; ensure only one migration runner at a time