Technical Requirements for Self-Hosting OpenSEO on Cloudflare Workers

To self-host OpenSEO on Cloudflare Workers, you need Node.js 22.6 or newer, pnpm, a Cloudflare account with R2 enabled, a DataForSEO API key, and a configured .env.selfhost file containing allowed user emails and external service credentials.

The every-app/open-seo repository deploys as a Cloudflare Worker using a serverless edge architecture that relies on Cloudflare-native storage and external SEO data providers. Successfully self-hosting requires specific runtime versions, API accounts, and environment variables that are validated during the deployment process. This guide details the exact technical prerequisites, resource bindings, and configuration steps defined in the source documentation and wrangler.jsonc.

Prerequisites and Runtime Dependencies

Before deploying, your local environment must meet the following specifications:

  • Node.js 22.6 or newer — The package.json explicitly declares "engines": { "node": ">=22.6" } for build-time compatibility.
  • pnpm package manager — Install via corepack enable. The deployment scripts in package.json (such as pnpm deploy:selfhost) depend on pnpm.
  • Cloudflare account with R2 enabled — You must have a Cloudflare account with R2 object storage activated. According to docs/SELF_HOSTING_CLOUDFLARE.md, a payment method is required on file even for the free tier to enable R2.

External Service Accounts

Self-hosting OpenSEO requires active accounts with the following third-party providers:

  • DataForSEO account — Required for SEO data APIs. You must generate an API key and reference it as DATAFORSEO_API_KEY in your environment file, as documented in docs/DATAFORSEO_API_KEY.md.
  • Alchemy CLI — Used for bootstrapping the state-store Worker and managing infrastructure. You will run pnpm alchemy login to authenticate with the access:write OAuth scope before deploying.

Environment Configuration and Required Variables

Create a .env.selfhost file by copying .env.selfhost.example. At minimum, the file must define:

  • ACCESS_ALLOWED_EMAILS — A comma-separated list of email addresses permitted to access the application through Cloudflare Access.
  • DATAFORSEO_API_KEY — Your DataForSEO API credentials.

Optional variables include:

  • TEAM_DOMAIN and POLICY_AUD — For customizing Cloudflare Access policies.
  • OPENSEO_TELEMETRY_DISABLED=1 — Set this to disable anonymized usage telemetry, as noted in docs/SELF_HOSTING_CLOUDFLARE_OPERATIONS.md.

Cloudflare Resources and Architecture

The OpenSEO Worker binds to several Cloudflare resources defined in wrangler.jsonc. During deployment via pnpm deploy:selfhost, the Alchemy CLI automatically provisions:

  • D1 database — A SQLite-compatible database (binding d1_databases) for application state.
  • KV namespaces — Two separate namespaces: KV for general caching and OAUTH_KV for OAuth state management.
  • R2 bucket — An open-seo bucket for static assets and file storage.

The Worker entry point is src/server.ts, configured as the main handler in wrangler.jsonc. Database migrations located in drizzle.config.ts and the drizzle/ directory target the D1 instance.

Deployment Workflow

Execute the following commands in sequence to provision resources and deploy the Worker:


# Clone and prepare the repository

git clone https://github.com/every-app/open-seo.git
cd open-seo
corepack enable
pnpm install

# Authenticate with Cloudflare (required once)

pnpm alchemy login
pnpm alchemy cloudflare bootstrap

# Configure environment variables

cp .env.selfhost.example .env.selfhost

# Edit .env.selfhost to set:

#   ACCESS_ALLOWED_EMAILS="admin@example.com"

#   DATAFORSEO_API_KEY="your-api-key"

# Deploy the self-host stage

pnpm deploy:selfhost --yes

The deploy:selfhost command creates D1 tables, provisions KV and R2 bindings, runs database migrations, and configures a Cloudflare Access application to gate entry.

To update an existing deployment after pulling new code:

git pull
pnpm install
pnpm deploy:selfhost --yes

To completely remove the deployment and clean up resources:

pnpm alchemy destroy --env-file .env.selfhost --stage selfhost

Post-Deployment Operations

After initial deployment, you may need to configure additional access controls and monitoring.

Telemetry Management

By default, OpenSEO transmits anonymized usage telemetry. To opt out, set OPENSEO_TELEMETRY_DISABLED=1 in .env.selfhost and redeploy.

MCP Client Access

To enable Managed Client Protocol (MCP) clients, you must turn on Managed OAuth within the Cloudflare Access application settings. Details are provided in docs/SELF_HOSTING_CLOUDFLARE_OPERATIONS.md.

Summary

  • Node.js 22.6+ and pnpm are required local dependencies.
  • A Cloudflare account with R2 enabled and a DataForSEO API key are mandatory external requirements.
  • The .env.selfhost file must define ACCESS_ALLOWED_EMAILS and DATAFORSEO_API_KEY at minimum.
  • Cloudflare resources (D1, KV, R2) are automatically provisioned by the Alchemy CLI during pnpm deploy:selfhost.
  • The Worker entry point is src/server.ts, with database migrations managed via drizzle.config.ts.
  • Telemetry can be disabled via environment variable, and MCP access requires additional Cloudflare Access configuration.

Frequently Asked Questions

Can I self-host OpenSEO without a DataForSEO account?

No. The application depends on DataForSEO for search engine ranking and keyword data. Without a valid DATAFORSEO_API_KEY defined in .env.selfhost, the Worker cannot fetch SEO metrics, causing functionality to fail.

What Cloudflare plan is required for self-hosting OpenSEO?

The free tier is sufficient, but you must add a payment method to your Cloudflare account to activate R2 storage. The deployment uses R2 for static assets, D1 for the database, and KV for caching, all of which operate within free tier limits for low-to-moderate traffic.

How do I update my self-hosted OpenSEO deployment?

Pull the latest changes from the every-app/open-seo repository, run pnpm install to update dependencies, and execute pnpm deploy:selfhost --yes to apply changes. The Alchemy CLI will update the Worker and run any pending database migrations without destroying existing data.

Where is application data persisted in a Cloudflare Workers environment?

Data persists in Cloudflare D1 (a SQLite-compatible edge database) for structured data, R2 for static files and assets, and KV for session caching and OAuth state. These bindings are defined in wrangler.jsonc and injected into the Worker at runtime.

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 →