oCoreoCore Docs

Backend Configuration

Backend configuration details including startup validation, runtime behavior, and environment-specific defaults.

The oCore backend is a Go application that reads all configuration from environment variables at startup. There is no configuration file. This page covers how the backend loads, validates, and applies configuration.

Configuration Loading

At startup, the backend's config.Load() function reads environment variables and applies defaults:

Startup → Read env vars → Apply defaults → Validate → Start server

If any required variable is missing or invalid, the server exits immediately with a descriptive error message. This fail-fast behavior prevents running with an incomplete or insecure configuration.

Required vs Optional

Strictly Required

These variables must always be set:

VariableValidation
DATABASE_URLMust be non-empty
JWT_SECRETMust be non-empty and at least 32 characters

Required in Production

These variables are validated only when ENVIRONMENT is not development:

VariableValidation
SSH_ENCRYPTION_KEYMust be at least 32 characters if set

In development mode (ENVIRONMENT=development), the SSH encryption key is automatically derived from JWT_SECRET via HKDF key derivation. In production, it must be explicitly provided.

These variables have defaults that work for development but should be configured for production:

VariableDev DefaultProduction Recommendation
APP_URLhttp://localhost:3000Your public dashboard URL
SMTP_HOSTlocalhostYour SMTP provider
SMTP_PORT1025587 (STARTTLS) or 465 (TLS)
SMTP_FROMnoreply@ocore.localYour domain's noreply address

Environment Modes

The ENVIRONMENT variable controls runtime behavior:

Development Mode (ENVIRONMENT=development)

  • SSH encryption key auto-derived from JWT secret
  • Relaxed validation for optional security settings
  • Default SMTP points to local Mailpit (localhost:1025)
  • Default WebAuthn origin is http://localhost:3000

Production Mode (ENVIRONMENT=production)

  • Strict validation of security-related variables
  • SSH_ENCRYPTION_KEY must be explicitly set if SSH gateway is enabled
  • All security headers enabled by default
  • Cookie security flags enforced (Secure, HttpOnly, SameSite)

Duration Format

Variables that accept durations (JWT_ACCESS_EXPIRY, JWT_REFRESH_EXPIRY) use Go's time.ParseDuration format:

UnitSuffixExample
Nanosecondsns500ns
Microsecondsus100us
Millisecondsms500ms
Secondss30s
Minutesm15m
Hoursh24h

Units can be combined: 1h30m for one hour and thirty minutes.

Server Port

The backend listens on the port specified by SERVER_PORT (default 8080). In a Docker Compose deployment, this port is only exposed within the Docker network. The reverse proxy forwards external traffic to this port.

services:
  backend:
    expose:
      - "8080"  # Internal only, not published to host
    ports:
      - "2222:2222"  # SSH gateway is published directly

Do not publish port 8080 to the host in production. Always route HTTP traffic through a reverse proxy with TLS termination. See the Reverse Proxy guide.

Database Connection

The backend connects to PostgreSQL using the DATABASE_URL connection string. The Ent ORM manages a connection pool internally.

Connection String Format

postgres://user:password@host:port/database?sslmode=mode
ParameterDescription
userPostgreSQL username
passwordPostgreSQL password (URL-encode special characters)
hostDatabase hostname or IP
portDatabase port (default 5432)
databaseDatabase name
sslmodedisable, require, verify-ca, or verify-full

For Docker Compose deployments where the database runs alongside the backend, use sslmode=disable since traffic stays within the Docker network. For external databases or managed services, use sslmode=require or stricter.

SSH Encryption

oCore encrypts stored SSH credentials (keys and passwords) at rest using AES-256-GCM with a key derived from SSH_ENCRYPTION_KEY. This protects credentials if the database is compromised.

In development, the encryption key is derived from JWT_SECRET using HKDF for convenience. In production, always set a separate SSH_ENCRYPTION_KEY:

# Generate a 64-character encryption key
openssl rand -base64 48

Changing SSH_ENCRYPTION_KEY after deployment will make existing stored credentials unreadable. Back up the key securely.

Health Check

The backend exposes a health check at /api/health that verifies:

  • The HTTP server is accepting connections
  • The database connection is alive

This endpoint does not require authentication and returns a JSON response:

{
  "status": "ok",
  "database": "connected",
  "version": "1.0.0"
}

Use this for load balancer health checks, Docker health checks, and uptime monitoring.

Was this page helpful?