Key Environment Variables in Open‑SEO: A Complete Configuration Guide
Open‑SEO uses environment variables defined in process.env across more than a dozen files to configure site URLs, database connections, third‑party APIs, telemetry settings, and CI/test behavior.
The open‑source Open‑SEO repository (every-app/open-seo on GitHub) relies heavily on environment variables to remain flexible across self‑hosted, cloud, and development deployments. This guide catalogs every significant variable, where it appears in the source code, and how to set it correctly.
Core Site and Application Settings
These variables control the base identity of your Open‑SEO instance.
SITE_URL and VITE_SITE_URL
In web/src/lib/seo.ts, the SEO utilities resolve the canonical site address from two possible sources:
// web/src/lib/seo.ts (lines 6‑7)
const siteUrl = process.env.SITE_URL ?? process.env.VITE_SITE_URL;
- SITE_URL – Standard Node.js environment variable used in production.
- VITE_SITE_URL – Vite‑prefixed variant exposed to the client bundle during development.
If neither is set, the application falls back to http://localhost:3000.
PORT
The Vite development server port is configured in vite.config.ts:
// vite.config.ts (lines 12‑13)
export default defineConfig({
server: {
port: parseInt(process.env.PORT || "5173"),
},
});
NODE_ENV
In src/lib/auth.ts, the authentication logic branches based on environment:
// src/lib/auth.ts (line 184)
if (process.env.NODE_ENV !== "production") {
// Development‑only auth bypasses
}
Database and Cloudflare Infrastructure
Open‑SEO supports both Cloudflare D1 and PostgreSQL backends. Migration and ORM configuration require these credentials.
CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN, CLOUDFLARE_DATABASE_ID
The D1‑to‑Postgres migration script in scripts/migrate-d1-to-postgres.ts reads:
// scripts/migrate-d1-to-postgres.ts (line 90)
const accountId = process.env.CLOUDFLARE_ACCOUNT_ID;
const apiToken = process.env.CLOUDFLARE_API_TOKEN;
Additionally, drizzle-prod.config.ts uses:
// drizzle-prod.config.ts
accountId: process.env.CLOUDFLARE_ACCOUNT_ID,
databaseId: process.env.CLOUDFLARE_DATABASE_ID,
apiToken: process.env.CLOUDFLARE_API_TOKEN,
POSTGRES_DATABASE_URL
PostgreSQL deployments require a connection string:
// drizzle-pg.config.ts (line 13)
export default defineConfig({
dbCredentials: {
url: process.env.POSTGRES_DATABASE_URL!,
},
});
// scripts/migrate-d1-to-postgres.ts
const pgClient = new Client(process.env.POSTGRES_DATABASE_URL);
CLOUDFLARE_D1_DATABASE_ID
Optional override for the source D1 database during migrations:
// scripts/migrate-d1-to-postgres.ts
const d1DatabaseId = process.env.CLOUDFLARE_D1_DATABASE_ID ?? defaultId;
Third‑Party API Integrations
DATAFORSEO_API_KEY
Multiple scripts consume this key for SEO data services:
scripts/dataforseo-account-usage.ts– monitors API quotascripts/brand-lookup-cost-profile.ts– calculates brand search costsscripts/backlinks-cost-profile.ts– estimates backlink analysis costs
AUTUMN_SECRET_KEY
The data erasure utility in scripts/erase-user-data.ts uses:
// scripts/erase-user-data.ts (line 411)
const autumnKey = process.env.AUTUMN_SECRET_KEY;
if (!autumnKey) throw new Error("AUTUMN_SECRET_KEY required for secure deletion");
Telemetry and Privacy Controls
OPENSEO_TELEMETRY_DISABLED and DO_NOT_TRACK
The self‑host preflight script respects user privacy preferences:
// scripts/selfhost-preflight.ts (lines 23‑24)
const telemetryDisabled =
process.env.OPENSEO_TELEMETRY_DISABLED === "true" ||
process.env.DO_NOT_TRACK === "1" ||
process.env.DO_NOT_TRACK === "true";
CLI Authentication
BETTER_AUTH_URL and BETTER_AUTH_SECRET
The CLI tool in cli-auth.ts configures its auth provider:
// cli-auth.ts (lines 7‑13)
const authUrl = process.env.BETTER_AUTH_URL ?? "http://localhost:4000";
const authSecret = process.env.BETTER_AUTH_SECRET ?? crypto.randomUUID();
Testing and Performance Configuration
PLAYWRIGHT_CHANNEL
End‑to‑end test browser selection:
// playwright.config.ts (line 16)
channel: process.env.PLAYWRIGHT_CHANNEL ?? "chrome",
DOMAIN_FILTER_* Performance Knobs
The domain overview filter performance spec in e2e/domain-overview-filters.perf.spec.ts exposes fine‑grained controls:
- DOMAIN_FILTER_CPU_THROTTLE – CPU throttling rate for simulated devices
- DOMAIN_FILTER_ACTION_MS – Maximum acceptable interaction time
- DOMAIN_FILTER_MAX_LONG_TASK_MS – Per‑task duration threshold
- DOMAIN_FILTER_MAX_RAF_GAP_MS – RequestAnimationFrame gap limit
- DOMAIN_FILTER_MAX_INPUT_MS – Input delay ceiling
- DOMAIN_FILTER_TOTAL_LONG_TASK_MS – Cumulative long‑task budget
These allow CI pipelines to enforce strict performance budgets across different hardware.
CI and Debugging Flags
CI
When set to "true", cost‑profile scripts (brand-lookup-cost-profile.ts, backlinks-cost-profile.ts) enforce stricter validation and reporting formats suitable for automated pipelines.
DEBUG_DEPTH
The BadSEO audit runner supports verbose logging:
// badseo/scripts/run-audit.ts (line 248)
const debugDepth = parseInt(process.env.DEBUG_DEPTH || "0");
if (debugDepth > 2) console.log(extendedDiagnostics);
Summary
- Site identity:
SITE_URL,VITE_SITE_URL,PORTdefine how Open‑SEO presents itself and listens for traffic. - Infrastructure:
CLOUDFLARE_ACCOUNT_ID,CLOUDFLARE_API_TOKEN,CLOUDFLARE_DATABASE_ID, andPOSTGRES_DATABASE_URLenable database connectivity and migrations. - External data:
DATAFORSEO_API_KEYpowers SEO analytics;AUTUMN_SECRET_KEYsecures data deletion. - Privacy:
OPENSEO_TELEMETRY_DISABLEDandDO_NOT_TRACKlet operators opt out of usage reporting. - CLI and auth:
BETTER_AUTH_URLandBETTER_AUTH_SECRETsupport command‑line authentication flows. - Testing:
PLAYWRIGHT_CHANNELand the sixDOMAIN_FILTER_*variables provide deterministic, measurable test environments. - Debugging:
DEBUG_DEPTHandCIcontrol output verbosity and pipeline behavior.
Frequently Asked Questions
What is the minimum set of environment variables to run Open‑SEO locally?
For local development, you need VITE_SITE_URL (or SITE_URL), PORT if you want a custom port, and NODE_ENV=development. Database functionality requires either POSTGRES_DATABASE_URL for PostgreSQL or Cloudflare credentials for D1. See .env.example in the repository root for a complete template.
How do I disable telemetry when self‑hosting Open‑SEO?
Set OPENSEO_TELEMETRY_DISABLED=true or DO_NOT_TRACK=1 before running the preflight script in scripts/selfhost-preflight.ts. The script checks both variables and skips telemetry initialization if either is set.
Can I use Open‑SEO without DataForSEO?
Yes, but brand lookup, backlink analysis, and cost profiling features require DATAFORSEO_API_KEY. Core site auditing and local SEO tools function without it.
Why does the migration script need both Cloudflare and Postgres credentials?
scripts/migrate-d1-to-postgres.ts reads from Cloudflare D1 (source) and writes to PostgreSQL (target). It requires CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN, and POSTGRES_DATABASE_URL to establish both connections simultaneously.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →