How to Build the OpenSEO Project for Deployment: Docker and Cloudflare Guide
You can build and deploy OpenSEO using Docker for quick local hosting or Cloudflare Workers for production-grade edge deployment, both requiring a TypeScript compilation step via Vite and environment configuration.
The open-source OpenSEO project (available at every-app/open-seo) provides a modern SEO analysis platform that compiles TypeScript sources into a deployable worker bundle. Whether you choose the containerized Docker path or the serverless Cloudflare Workers route, the build pipeline leverages Vite to bundle the application and prepare the runtime environment.
Docker Self-Hosting (Quick Start)
The Docker path offers the fastest way to build the open-seo project for deployment on your local machine or private server.
Configure Environment Variables
Start by copying the example environment file located in the repository root:
cp .env.example .env
Edit .env to add your DATAFORSEO_API_KEY (required) and optionally OPENROUTER_API_KEY. Reference docs/DATAFORSEO_API_KEY.md for detailed setup instructions.
Build and Run
You have two options for building the Docker image:
Option A: Use the pre-built image (fastest)
Run the compose stack directly:
docker compose up -d
Option B: Build a custom image (for local development)
If you need to test local changes, build from Dockerfile.selfhost:
docker build -f Dockerfile.selfhost -t open-seo:local .
OPEN_SEO_IMAGE=open-seo:local docker compose up -d
The compose.yaml forwards your .env values and maps port 3001 by default. The first start may take a few minutes while the front-end compiles.
Access and Telemetry
Open your browser to http://localhost:3001 (or your custom PORT). To disable anonymized usage data, add this to your .env:
OPENSEO_TELEMETRY_DISABLED=1
Cloudflare Workers Self-Hosting (Production)
For production-grade deployment, build the open-seo project for deployment on Cloudflare's edge network using Wrangler and the Alchemy CLI.
Prerequisites
Before starting, ensure you have:
- Node.js ≥ 22
- pnpm (enabled via
corepack) - A Cloudflare account with R2 enabled
- A DataForSEO API key
Detailed requirements are documented in docs/SELF_HOSTING_CLOUDFLARE.md.
Installation and Authentication
Clone the repository and install dependencies:
git clone https://github.com/every-app/open-seo.git
cd open-seo
corepack enable
pnpm install
Authenticate with Cloudflare and bootstrap the state-store worker:
pnpm alchemy login
pnpm alchemy cloudflare bootstrap
Deploy
Copy the self-hosting environment template:
cp .env.selfhost.example .env.selfhost
Populate .env.selfhost with your DATAFORSEO_API_KEY and other required secrets. Then deploy:
pnpm deploy:selfhost --yes
This command (defined in scripts/selfhost-deploy-preflight.mjs) provisions D1, KV, R2, runs database migrations, deploys the worker, and creates a Cloudflare Access gate.
Validation and Updates
Visit the printed Worker URL and sign in via Cloudflare Access. Verify health at:
curl https://<YOUR_WORKER_HOST>/api/health
To update an existing deployment:
git pull
pnpm install
pnpm deploy:selfhost --yes
Core Build Pipeline
Both deployment paths share a common build process that compiles TypeScript and bundles the worker code.
TypeScript Compilation and Vite Bundling
The project uses vite.config.ts with a custom plugin (vite-plugin-lean-worker-bundle.ts) to produce a lean worker bundle. This configuration handles:
- TypeScript compilation via
tsconfig.json - Asset optimization for edge environments
- Worker-specific bundling requirements
Server Entry Point
The src/server.ts file serves as the HTTP handler entry point, wiring the MCP (mobile-client-protocol) routes and chat agents. This file is the primary target for the Vite build process.
Worker Configuration
wrangler.jsonc (and its Cloudflare-specific variant under badseo/) defines Wrangler settings, including:
- Entry point mappings
- Secret bindings
- D1 database connections
Summary
- Two deployment paths: Docker for quick local setup (
Dockerfile.selfhost,compose.yaml) or Cloudflare Workers for production (wrangler.jsonc,deploy:selfhost). - Environment setup: Copy
.env.examplefor Docker or.env.selfhost.examplefor Cloudflare, adding yourDATAFORSEO_API_KEY. - Build process: Vite compiles TypeScript from
src/server.tsusingvite.config.tsandvite-plugin-lean-worker-bundle.ts. - Cloudflare workflow:
pnpm alchemy login→bootstrap→deploy:selfhost --yes. - Telemetry: Disable with
OPENSEO_TELEMETRY_DISABLED=1in your environment file.
Frequently Asked Questions
What are the system requirements to build OpenSEO?
For Docker deployment, you only need Docker and Docker Compose. For Cloudflare deployment, you need Node.js ≥ 22, pnpm, and a Cloudflare account with R2 storage enabled. Both methods require a DataForSEO API key to function.
How do I disable telemetry when building OpenSEO?
Add OPENSEO_TELEMETRY_DISABLED=1 to your .env file (for Docker) or .env.selfhost file (for Cloudflare) before starting the application. This prevents the sending of anonymized usage data to the maintainers.
What is the difference between Docker and Cloudflare deployment options?
The Docker path (Dockerfile.selfhost, compose.yaml) runs the application in a container on your own infrastructure, exposing port 3001 by default. The Cloudflare path compiles the project into a Worker bundle deployed to Cloudflare's edge network, using D1 for database, KV for storage, and R2 for assets, providing global distribution and automatic scaling.
How do I update an existing Cloudflare deployment?
Pull the latest code from the repository, reinstall dependencies with pnpm install, and rerun pnpm deploy:selfhost --yes. The deployment script in scripts/selfhost-deploy-preflight.mjs will apply any new migrations and update the worker without losing your existing data in D1 or KV.
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 →