Environment Variables
Complete reference of every environment variable used by oCore, including type, default value, and description.
This page documents every environment variable that oCore reads at startup. Variables are organized by subsystem. Required variables must be set for the application to start.
Database
| Variable | Type | Default | Required | Description |
|---|---|---|---|---|
DATABASE_URL | string | -- | Yes | PostgreSQL connection string. Format: postgres://user:password@host:5432/dbname?sslmode=disable |
POSTGRES_USER | string | ocore | No | PostgreSQL user (used by the Docker Compose postgres service, not the backend directly) |
POSTGRES_PASSWORD | string | -- | Yes | PostgreSQL password (used by the Docker Compose postgres service) |
POSTGRES_DB | string | ocore | No | PostgreSQL database name (used by the Docker Compose postgres service) |
The DATABASE_URL is read by the backend service. The POSTGRES_* variables are read by the PostgreSQL Docker image during initialization. In Docker Compose, DATABASE_URL is constructed from the POSTGRES_* values.
JWT / Authentication
| Variable | Type | Default | Required | Description |
|---|---|---|---|---|
JWT_SECRET | string | -- | Yes | Secret key for signing JWT access and refresh tokens. Must be at least 32 characters. |
JWT_ACCESS_EXPIRY | duration | 1h | No | How long access tokens remain valid. Accepts Go duration format (e.g., 30m, 2h). |
JWT_REFRESH_EXPIRY | duration | 720h | No | How long refresh tokens remain valid. Default is 30 days. |
COOKIE_DOMAIN | string | -- | No | Domain for auth cookies (e.g., .ocore.dev). Set this to share cookies across subdomains. |
Generate a strong JWT secret:
openssl rand -base64 48SMTP / Email
| Variable | Type | Default | Required | Description |
|---|---|---|---|---|
SMTP_HOST | string | localhost | Recommended | SMTP server hostname for sending transactional emails (verification, password reset, notifications). |
SMTP_PORT | string | 1025 | No | SMTP server port. Use 587 for STARTTLS or 465 for implicit TLS. |
SMTP_FROM | string | noreply@ocore.local | No | Sender address for outgoing emails. |
SMTP_USERNAME | string | -- | No | SMTP authentication username. Leave empty for unauthenticated relay. |
SMTP_PASSWORD | string | -- | No | SMTP authentication password. |
In development, the defaults point to a local Mailpit instance. For production, configure a real SMTP provider (e.g., AWS SES, SendGrid, Postmark, or your own mail server).
OAuth Providers
| Variable | Type | Default | Required | Description |
|---|---|---|---|---|
OAUTH_GITHUB_CLIENT_ID | string | -- | No | GitHub OAuth application client ID. Enable GitHub login. |
OAUTH_GITHUB_CLIENT_SECRET | string | -- | No | GitHub OAuth application client secret. |
OAUTH_GOOGLE_CLIENT_ID | string | -- | No | Google OAuth client ID. Enable Google login. |
OAUTH_GOOGLE_CLIENT_SECRET | string | -- | No | Google OAuth client secret. |
Both OAuth providers are optional. If the client ID and secret are not set, the corresponding login button is hidden in the dashboard.
To set up GitHub OAuth:
- Go to GitHub Settings > Developer settings > OAuth Apps > New OAuth App
- Set the Authorization callback URL to
https://ocore.example.com/api/auth/oauth/github/callback - Copy the Client ID and Client Secret to your
.envfile
To set up Google OAuth:
- Go to the Google Cloud Console > APIs & Services > Credentials > Create OAuth client ID
- Set the Authorized redirect URI to
https://ocore.example.com/api/auth/oauth/google/callback - Copy the Client ID and Client Secret to your
.envfile
WebAuthn / Passkeys
| Variable | Type | Default | Required | Description |
|---|---|---|---|---|
WEBAUTHN_RP_ID | string | localhost | No | WebAuthn Relying Party ID. Set to your domain (e.g., ocore.example.com). |
WEBAUTHN_RP_ORIGIN | string | http://localhost:3000 | No | WebAuthn Relying Party origin. Set to your full origin (e.g., https://ocore.example.com). |
WebAuthn enables passkey and hardware security key authentication. Both WEBAUTHN_RP_ID and WEBAUTHN_RP_ORIGIN must match the domain users access the dashboard from.
Web Push / VAPID
| Variable | Type | Default | Required | Description |
|---|---|---|---|---|
VAPID_PUBLIC_KEY | string | -- | No | VAPID public key for Web Push notifications. |
VAPID_PRIVATE_KEY | string | -- | No | VAPID private key for Web Push notifications. |
VAPID_CONTACT | string | mailto:admin@ocore.local | No | Contact email for VAPID (must start with mailto:). |
Web Push notifications are optional. Generate VAPID keys with:
npx web-push generate-vapid-keysSSH Gateway
| Variable | Type | Default | Required | Description |
|---|---|---|---|---|
SSH_GATEWAY_ENABLED | boolean | true | No | Enable the SSH gateway server. Set to false to disable SSH access to Odoo instances. |
SSH_HOST_KEY_PATH | string | ./data/ssh_host_ed25519_key | No | Path to the SSH host key file. Auto-generated on first start if not present. |
SSH_LISTEN_ADDR | string | :2222 | No | Address and port the SSH gateway listens on. |
SSH_ENCRYPTION_KEY | string | -- | Production | Encryption key for stored SSH credentials. Must be at least 32 characters in production. In development, auto-derived from JWT_SECRET. |
The SSH gateway allows users to connect to Odoo instances via SSH through oCore. The host key is stored in a persistent volume so that clients do not see host key change warnings after container restarts.
OAuth 2.1 Authorization Server
| Variable | Type | Default | Required | Description |
|---|---|---|---|---|
OAUTH_ISSUER | string | -- | No | Canonical issuer URL for OAuth metadata endpoints. Falls back to APP_URL if not set, then to the request's scheme and host. Set this if the OAuth issuer URL differs from the dashboard URL (e.g., behind a reverse proxy with a separate domain). |
In most deployments, OAUTH_ISSUER does not need to be set because APP_URL is used by default. Set it only when the OAuth authorization server is exposed on a different URL than the dashboard.
Application
| Variable | Type | Default | Required | Description |
|---|---|---|---|---|
SERVER_PORT | string | 8080 | No | Port the backend API server listens on. |
APP_URL | string | http://localhost:3000 | Recommended | Public URL of the oCore dashboard. Used in emails, redirect URLs, and as the default OAuth issuer URL. |
ENVIRONMENT | string | development | No | Application environment. Set to production to enable production security defaults. |
GITHUB_TOKEN | string | -- | No | GitHub personal access token. Used for repository access and Git integration features. |
TRANSFER_BINARY_PATH | string | ./bin/ocore-transfer | No | Path to the compiled ocore-transfer binary used for file operations on remote servers. |
Frontend
These variables are set at build time as Docker build args. They are embedded into the Next.js bundle and cannot be changed at runtime.
| Variable | Type | Default | Required | Description |
|---|---|---|---|---|
NEXT_PUBLIC_API_URL | string | -- | Yes | URL of the backend API, as seen from the user's browser. Must be a publicly accessible URL (e.g., https://ocore.example.com). |
NEXT_PUBLIC_SSH_PORT | string | 2222 | No | SSH gateway port displayed in the dashboard UI for copy-paste connection strings. |
NEXT_PUBLIC_WAITLIST_ENDPOINT | string | -- | No | URL for waitlist form submissions on the docs/landing site. If not set, the waitlist form is hidden. |
Documentation Site
These variables are used by the oCore documentation site (Next.js, separate from the main frontend):
| Variable | Type | Default | Required | Description |
|---|---|---|---|---|
SHOW_DEV_DOCS | string | -- | No | Set to true to show contributing and developer-guide sections in the documentation sidebar. When not set or set to any other value, these sections are filtered out. |
See the Frontend Configuration page for details on build-time vs runtime behavior.
Docker Compose Reference
Here is how each variable maps to the production Docker Compose file:
services:
backend:
environment:
DATABASE_URL: postgres://${POSTGRES_USER:-ocore}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-ocore}?sslmode=disable
JWT_SECRET: ${JWT_SECRET}
SSH_ENCRYPTION_KEY: ${SSH_ENCRYPTION_KEY}
APP_URL: ${APP_URL}
ENVIRONMENT: ${ENVIRONMENT:-production}
SMTP_HOST: ${SMTP_HOST}
SMTP_PORT: ${SMTP_PORT}
SMTP_FROM: ${SMTP_FROM}
SMTP_USERNAME: ${SMTP_USERNAME:-}
SMTP_PASSWORD: ${SMTP_PASSWORD:-}
OAUTH_GITHUB_CLIENT_ID: ${OAUTH_GITHUB_CLIENT_ID:-}
OAUTH_GITHUB_CLIENT_SECRET: ${OAUTH_GITHUB_CLIENT_SECRET:-}
OAUTH_GOOGLE_CLIENT_ID: ${OAUTH_GOOGLE_CLIENT_ID:-}
OAUTH_GOOGLE_CLIENT_SECRET: ${OAUTH_GOOGLE_CLIENT_SECRET:-}
WEBAUTHN_RP_ID: ${WEBAUTHN_RP_ID:-}
WEBAUTHN_RP_ORIGIN: ${WEBAUTHN_RP_ORIGIN:-}
VAPID_CONTACT: ${VAPID_CONTACT:-}
VAPID_PUBLIC_KEY: ${VAPID_PUBLIC_KEY:-}
VAPID_PRIVATE_KEY: ${VAPID_PRIVATE_KEY:-}
SSH_GATEWAY_ENABLED: ${SSH_GATEWAY_ENABLED:-true}
SSH_HOST_KEY_PATH: /app/data/ssh_host_ed25519_key
SSH_LISTEN_ADDR: ${SSH_LISTEN_ADDR:-:2222}
frontend:
build:
args:
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL}
NEXT_PUBLIC_SSH_PORT: ${NEXT_PUBLIC_SSH_PORT:-2222}All variables with :- syntax have default values and are optional. Variables without defaults are required or conditionally required.
Validation Rules
The backend validates configuration at startup. If validation fails, the server exits with a descriptive error message.
| Rule | Error Message |
|---|---|
DATABASE_URL is empty | DATABASE_URL is required |
JWT_SECRET is empty | JWT_SECRET is required |
JWT_SECRET is less than 32 characters | JWT_SECRET must be at least 32 characters |
SSH_ENCRYPTION_KEY is less than 32 characters (production only) | SSH_ENCRYPTION_KEY must be at least 32 characters |
JWT_ACCESS_EXPIRY is not a valid Go duration | invalid JWT_ACCESS_EXPIRY "...": ... |
JWT_REFRESH_EXPIRY is not a valid Go duration | invalid JWT_REFRESH_EXPIRY "...": ... |