Where OpenSEO Handles Self‑Hosting Configuration Validation

TLDR: OpenSEO performs self‑hosting configuration validation through a coordinated two‑layer system: src/lib/selfhost-preflight.ts orchestrates runtime pre‑flight checks during container startup, while src/shared/selfhost-checks.ts provides pure validation functions reused across the application including the /api/health endpoint.

When deploying OpenSEO from the every-app/open-seo repository in a self‑hosted environment, ensuring that environment variables and credentials are correctly configured prevents costly runtime failures. The codebase implements a robust validation pipeline that checks configuration at container startup and exposes results for continuous monitoring. Understanding exactly where this self‑hosting configuration validation occurs helps operators troubleshoot deployment issues and maintain healthy instances.

Runtime Pre‑Flight Validation in selfhost-preflight.ts

The primary entry point for self‑hosting configuration validation is src/lib/selfhost-preflight.ts, which executes immediately when a Docker or self‑hosted container starts via the CLI wrapper at scripts/selfhost-preflight.ts.

The Orchestration Layer

The runSelfhostPreflight function serves as the central coordinator. It accepts an environment object (defaulting to process.env in production) and delegates to three specialized helper functions:

  • checkAuthMode – validates the authentication configuration and required variables like POLICY_AUD
  • checkDataForSeo – verifies that DATAFORSEO_API_KEY is present and properly formatted
  • checkOptionalFeatures – inspects optional integrations including Google Search Console, AI features, and runtime host settings

Structured Reporting and Failure Handling

Each check produces a PreflightItem that aggregates into a PreflightResult object. This structure contains an array of validation items and a boolean failed flag. If any item reports a "fail" level, the routine returns failed: true, causing the container startup script to abort after printing a concise report via formatPreflightReport.

Shared Validation Logic in selfhost-checks.ts

Concrete validation rules reside in src/shared/selfhost-checks.ts as pure, reusable functions. This separation ensures consistent validation logic between the startup sequence and runtime health checks without code duplication.

Pure Validator Functions

The module exports specific validators used by the pre‑flight system:

  • validateTeamDomain – confirms TEAM_DOMAIN contains a valid domain format
  • looksLikeDataForSeoKey – verifies DATAFORSEO_API_KEY resembles a Base64 encoded login:password string
  • MIN_BETTER_AUTH_SECRET_LENGTH – a constant defining minimum secret length requirements for authentication

Cross‑Cutting Reusability

By isolating validation logic in src/shared/selfhost-checks.ts, OpenSEO prevents code drift. The same functions validate configuration during container startup and when responding to requests at the /api/health endpoint defined in src/routes/api/health.ts, ensuring consistent behavior across deployment stages.

The Self‑Hosting Configuration Validation Flow

The validation pipeline executes in a specific sequence to prevent misconfigured deployments from serving traffic:

  1. Container Initialization – The Docker container executes scripts/selfhost-preflight.ts, which imports the main runner from src/lib/selfhost-preflight.ts.

  2. Environment Ingestion – runSelfhostPreflight reads the environment object.

  3. Feature Validation – The system pushes a PreflightItem for each feature category: authentication mode, DataForSEO credentials, and optional features.

  4. Pure Validation – Each feature check invokes the corresponding validator from src/shared/selfhost-checks.ts.

  5. Fatal Error Handling – If any check returns level "fail", the runner sets failed: true and the startup script exits with code 1.

  6. Telemetry Gate – Only after successful validation does src/lib/selfhost-telemetry.ts initialize, ensuring misconfigurations do not generate false metrics.

Implementation Examples

Running the Full Pre‑Flight Check

Use the main runner to validate complete environment configurations during custom deployment scripts:

import { runSelfhostPreflight, formatPreflightReport } from '@/lib/selfhost-preflight';

// Pass a mock environment object (process.env is the default in production)
const env = {
  AUTH_MODE: 'cloudflare_access',
  TEAM_DOMAIN: 'mycompany.com',
  POLICY_AUD: '12345',
  DATAFORSEO_API_KEY: 'bXljaX... (base64)',
  // optional vars omitted for brevity
};

const result = runSelfhostPreflight(env);
console.log(formatPreflightReport(result));

// The `result.failed` flag can be used to abort startup:
if (result.failed) {
  process.exit(1);
}

Using Shared Validators Directly

Import pure functions from the shared module for targeted validation in tests or custom tooling:

import { validateTeamDomain, looksLikeDataForSeoKey } from '@/shared/selfhost-checks';

const domainCheck = validateTeamDomain('example.com');
console.log(domainCheck.ok ? 'Domain OK' : `Domain error: ${domainCheck.message}`);

const keyOk = looksLikeDataForSeoKey('bXJlYW...'); // Base64 string
console.log(keyOk ? 'Key looks valid' : 'Key format invalid');

Summary

  • Primary orchestration occurs in src/lib/selfhost-preflight.ts via the runSelfhostPreflight function, which runs automatically during container startup through scripts/selfhost-preflight.ts.
  • Core validation logic resides in src/shared/selfhost-checks.ts as pure functions like validateTeamDomain and looksLikeDataForSeoKey, ensuring reusability across the application.
  • Failure handling uses a structured PreflightResult with a failed flag to abort deployment when critical configuration errors are detected.
  • Health monitoring exposes identical validation results through the /api/health endpoint in src/routes/api/health.ts for real‑time UI status display.

Frequently Asked Questions

What happens if self‑hosting configuration validation fails during startup?

When runSelfhostPreflight detects a fatal configuration error, it returns failed: true in the PreflightResult object. The container startup script prints a formatted report via formatPreflightReport and exits with status code 1, preventing the application from serving traffic with invalid settings.

Can I run the configuration validation manually without starting the full application?

Yes. Import runSelfhostPreflight from @/lib/selfhost-preflight and pass a custom environment object to validate specific configurations. This is useful for testing deployment scripts or validating infrastructure‑as‑code changes before container initialization.

How does OpenSEO validate the DataForSEO API key format?

The looksLikeDataForSeoKey function in src/shared/selfhost-checks.ts validates that the DATAFORSEO_API_KEY environment variable contains a Base64‑encoded string matching the expected login:password format required by the DataForSEO API, without exposing the actual credential values.

Why are validation rules separated between selfhost-preflight.ts and selfhost-checks.ts?

This separation follows the single‑responsibility principle. The selfhost-checks.ts module contains pure, stateless validation functions that can be imported by both the startup routine and the health endpoint. The selfhost-preflight.ts file handles orchestration, environment reading, and report formatting specific to the container lifecycle.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →