Self-hosting in production
OKR.ai is one Node.js process plus a database. Anything that can run a long-lived Node 22 service can host it: a VM, a container platform or Kubernetes.
Production checklist
- Set
OKRAI_SECRET_KEY. OKR.ai refuses to start in production without it. Store it in your secrets manager. - Set
OKRAI_URLto the public HTTPS URL, so sign-in links and OIDC redirects are correct. - Configure email (
SMTP_URLor an email API) so people receive sign-in codes. - Choose a database. Built-in SQLite needs persistent disk and your own backups. For larger teams, use Postgres or MySQL. See Databases.
- Turn on SSO for your identity provider. See Sign-in & SSO.
- Terminate TLS at a reverse proxy or load balancer.
- Keep the process running. The snapshot scheduler runs in-process; on platforms that sleep idle apps, call the cron endpoint instead.
Run the server
$ npm install -g okr-ai $ NODE_ENV=production PORT=3000 okr-ai
From source, use npm ci && npm run build && npm start.
systemd
[Unit] Description=OKR.ai After=network.target [Service] WorkingDirectory=/srv/okr-ai EnvironmentFile=/srv/okr-ai/.env Environment=NODE_ENV=production PORT=3000 ExecStart=/usr/bin/okr-ai Restart=always User=okrai [Install] WantedBy=multi-user.target
Docker
FROM node:22-slim WORKDIR /app RUN npm install -g okr-ai ENV NODE_ENV=production PORT=3000 VOLUME /app/data EXPOSE 3000 CMD ["okr-ai"]
$ docker build -t okr-ai . $ docker run -d -p 3000:3000 --env-file .env -v okrai-data:/app/data okr-ai
Reverse proxy
okr.example.com {
reverse_proxy localhost:3000
}
server {
listen 443 ssl;
server_name okr.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Backups
- Built-in SQLite: back up the
datafolder. Copy the database while the app is stopped, or usesqlite3 okrai.db ".backup backup.db". - Postgres, MySQL and managed services: use your provider’s backups or point-in-time recovery.
- OKR.ai Cloud: DynamoDB point-in-time recovery is on by default.
- Keep
OKRAI_SECRET_KEYwith your backups. Without it, stored secrets can’t be decrypted.
Upgrades
Install the new version and restart. Missing tables are created on start-up. Read the release notes before upgrading across minor versions.