How to Self-Host OpenSEO: Complete Docker and Cloudflare Deployment Guide
You can self-host OpenSEO using Docker for simple private deployments or Cloudflare Workers for production, both requiring only a DataForSEO API key and the pre-flight validation script found in scripts/selfhost-preflight.ts.
OpenSEO is a modern, serverless TypeScript application providing SEO analysis through an MCP (Model Context Protocol) server and web interface. According to the every-app/open-seo source code, the architecture supports two distinct deployment paths that share common core logic located under src/ but differ in infrastructure orchestration and authentication models.
Docker Self-Hosting Path
The Docker deployment offers the fastest way to run OpenSEO locally or within private networks. This method uses AUTH_MODE=local_noauth and is intended for trusted environments only.
Prerequisites and Setup
You need Docker Desktop or Docker Engine with Compose, plus a DataForSEO account. Clone the repository and prepare your environment variables before starting the container.
cp .env.example .env
# Edit .env to set DATAFORSEO_API_KEY (base64-encoded email:password)
Running the Container
The Dockerfile.selfhost builds an optimized image that the pre-built ghcr.io/every-app/open-seo:latest tracks. Start the application with:
docker compose up -d
This command executes the pre-flight checks defined in src/lib/selfhost-preflight.ts, validating that DATAFORSEO_API_KEY exists and that AUTH_MODE is compatible with containerized deployments.
Security Configuration
Docker deployments default to AUTH_MODE=local_noauth, disabling built-in authentication checks. As noted in docs/SELF_HOSTING_DOCKER.md, this configuration is safe only when running behind a private network or reverse proxy you control. Optional configuration variables include PORT, ALLOWED_HOST, and OPENSEO_TELEMETRY_DISABLED.
Cloudflare Self-Hosting Path (Recommended)
The Cloudflare deployment provides production-grade authentication, serverless scaling, and managed storage through Workers, D1, KV, and R2.
Prerequisites
This path requires Node.js 22+, pnpm, a Cloudflare account with R2 enabled, and the Alchemy framework for infrastructure-as-code management. The deployment provisions multiple cloud resources automatically via wrangler.jsonc.
Step-by-Step Deployment
First, authenticate with Cloudflare and bootstrap the required state-store Worker:
pnpm alchemy login
pnpm alchemy cloudflare bootstrap
Create your environment file from the template:
cp .env.selfhost.example .env.selfhost
Edit .env.selfhost to include:
DATAFORSEO_API_KEY(required)ACCESS_ALLOWED_EMAILS(comma-separated list for Cloudflare Access)- Optional:
TEAM_DOMAINandPOLICY_AUDfor SSO integration
Deploy with a single command:
pnpm deploy:selfhost --yes
This executes the deployment scripts that provision a D1 database (SQLite-compatible for projects and rankings), KV namespaces for static assets, an R2 bucket for large files like uploaded PDFs, and applies all migrations automatically.
Architecture Overview
The Cloudflare deployment runs the compiled Vite application as a Cloudflare Worker, configured in wrangler.jsonc. Cloudflare Access guards the MCP endpoint and UI, allowing only emails listed in ACCESS_ALLOWED_EMAILS to authenticate. The MCP server exposes an HTTP API that agents like Claude Code and Hermes connect to for SEO data retrieval.
Pre-Flight Validation and Telemetry
Every self-hosted instance runs validation logic before accepting traffic, implemented in scripts/selfhost-preflight.ts which imports core checks from src/lib/selfhost-preflight.ts.
Environment Validation
The pre-flight script aborts deployment if critical checks fail, including:
- Missing
DATAFORSEO_API_KEY - Unsupported
AUTH_MODEconfigurations - Incompatible runtime environments
Telemetry Controls
OpenSEO includes optional anonymous telemetry reporting installation status. Disable this by setting either OPENSEO_TELEMETRY_DISABLED=1 or DO_NOT_TRACK=1 in your environment file before starting the application.
Summary
- Docker deployments use
docker compose up -dwithAUTH_MODE=local_noauth, suitable for private networks and documented indocs/SELF_HOSTING_DOCKER.md - Cloudflare deployments use
pnpm deploy:selfhost --yesto provision D1, KV, R2, and Access policies automatically, requiringACCESS_ALLOWED_EMAILSfor authentication - Core validation runs from
src/lib/selfhost-preflight.tsto verifyDATAFORSEO_API_KEYand environment compatibility before startup - Telemetry can be disabled via
OPENSEO_TELEMETRY_DISABLED=1orDO_NOT_TRACK=1environment variables
Frequently Asked Questions
What is the difference between Docker and Cloudflare self-hosting for OpenSEO?
Docker provides a containerized local deployment ideal for development or private networks without authentication, while Cloudflare offers production serverless scaling with built-in SSO authentication, managed databases, and object storage through the Workers platform.
How do I secure my self-hosted OpenSEO instance?
For Docker, place the container behind a reverse proxy or VPN since AUTH_MODE=local_noauth disables authentication checks. For Cloudflare, configure ACCESS_ALLOWED_EMAILS in .env.selfhost to restrict access via Cloudflare Access, which creates an SSO-style login gate before users can reach the UI or MCP endpoints.
What happens if the pre-flight check fails?
The application will abort startup and log specific validation errors. The scripts/selfhost-preflight.ts checks for required environment variables like DATAFORSEO_API_KEY and validates that your AUTH_MODE matches your deployment target, preventing misconfiguration issues in production.
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 →