# How to Build the OpenSEO Project for Deployment: Docker and Cloudflare Guide

> Build and deploy OpenSEO with Docker for local hosting or Cloudflare Workers for edge deployment. This guide covers Vite TypeScript compilation and environment configuration.

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

---

**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:

```bash
cp .env.example .env

```

Edit `.env` to add your `DATAFORSEO_API_KEY` (required) and optionally `OPENROUTER_API_KEY`. Reference [`docs/DATAFORSEO_API_KEY.md`](https://github.com/every-app/open-seo/blob/main/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:

```bash
docker compose up -d

```

**Option B: Build a custom image (for local development)**

If you need to test local changes, build from `Dockerfile.selfhost`:

```bash
docker build -f Dockerfile.selfhost -t open-seo:local .
OPEN_SEO_IMAGE=open-seo:local docker compose up -d

```

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

```bash
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`](https://github.com/every-app/open-seo/blob/main/docs/SELF_HOSTING_CLOUDFLARE.md).

### Installation and Authentication

Clone the repository and install dependencies:

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

```bash
pnpm alchemy login
pnpm alchemy cloudflare bootstrap

```

### Deploy

Copy the self-hosting environment template:

```bash
cp .env.selfhost.example .env.selfhost

```

Populate `.env.selfhost` with your `DATAFORSEO_API_KEY` and other required secrets. Then deploy:

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

```bash
curl https://<YOUR_WORKER_HOST>/api/health

```

To update an existing deployment:

```bash
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`](https://github.com/every-app/open-seo/blob/main/vite.config.ts) with a custom plugin ([`vite-plugin-lean-worker-bundle.ts`](https://github.com/every-app/open-seo/blob/main/vite-plugin-lean-worker-bundle.ts)) to produce a lean worker bundle. This configuration handles:

- TypeScript compilation via [`tsconfig.json`](https://github.com/every-app/open-seo/blob/main/tsconfig.json)
- Asset optimization for edge environments
- Worker-specific bundling requirements

### Server Entry Point

The [`src/server.ts`](https://github.com/every-app/open-seo/blob/main/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`](https://github.com/every-app/open-seo/blob/main/compose.yaml)) or Cloudflare Workers for production (`wrangler.jsonc`, `deploy:selfhost`).
- **Environment setup**: Copy `.env.example` for Docker or `.env.selfhost.example` for Cloudflare, adding your `DATAFORSEO_API_KEY`.
- **Build process**: Vite compiles TypeScript from [`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts) using [`vite.config.ts`](https://github.com/every-app/open-seo/blob/main/vite.config.ts) and [`vite-plugin-lean-worker-bundle.ts`](https://github.com/every-app/open-seo/blob/main/vite-plugin-lean-worker-bundle.ts).
- **Cloudflare workflow**: `pnpm alchemy login` → `bootstrap` → `deploy:selfhost --yes`.
- **Telemetry**: Disable with `OPENSEO_TELEMETRY_DISABLED=1` in 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`](https://github.com/every-app/open-seo/blob/main/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.