# How to Self-Host OpenSEO: Complete Docker and Cloudflare Deployment Guide

> Self-host OpenSEO easily with Docker or Cloudflare. Deploy your private SEO tool using the official guide and a DataForSEO API key for efficient website analysis.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: how-to-guide
- Published: 2026-08-30

---

**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`](https://github.com/every-app/open-seo/blob/main/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.

```bash
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:

```bash
docker compose up -d

```

This command executes the pre-flight checks defined in [`src/lib/selfhost-preflight.ts`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/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:

```bash
pnpm alchemy login
pnpm alchemy cloudflare bootstrap

```

Create your environment file from the template:

```bash
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_DOMAIN` and `POLICY_AUD` for SSO integration

Deploy with a single command:

```bash
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`](https://github.com/every-app/open-seo/blob/main/scripts/selfhost-preflight.ts) which imports core checks from [`src/lib/selfhost-preflight.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/selfhost-preflight.ts).

### Environment Validation

The pre-flight script aborts deployment if critical checks fail, including:
- Missing `DATAFORSEO_API_KEY`
- Unsupported `AUTH_MODE` configurations
- 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 -d` with `AUTH_MODE=local_noauth`, suitable for private networks and documented in [`docs/SELF_HOSTING_DOCKER.md`](https://github.com/every-app/open-seo/blob/main/docs/SELF_HOSTING_DOCKER.md)
- **Cloudflare deployments** use `pnpm deploy:selfhost --yes` to provision D1, KV, R2, and Access policies automatically, requiring `ACCESS_ALLOWED_EMAILS` for authentication
- **Core validation** runs from [`src/lib/selfhost-preflight.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/selfhost-preflight.ts) to verify `DATAFORSEO_API_KEY` and environment compatibility before startup
- **Telemetry** can be disabled via `OPENSEO_TELEMETRY_DISABLED=1` or `DO_NOT_TRACK=1` environment 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`](https://github.com/every-app/open-seo/blob/main/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.