# Docker vs Cloudflare Workers Self-Hosting for OpenSEO: Architecture and Deployment Guide

> Explore Docker vs Cloudflare Workers self hosting for OpenSEO. Understand architecture, deployment, and choose the best runtime for your needs.

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

---

**OpenSEO supports two distinct self-hosting models—Docker containers and Cloudflare Workers—that differ fundamentally in runtime environment, infrastructure automation, security architecture, and global distribution.**

The `every-app/open-seo` repository provides production-ready configurations for both deployment modes. While both methods execute the same application logic, Docker self-hosting keeps execution on infrastructure you control, whereas Cloudflare Workers distributes the application across Cloudflare's global edge network. Your choice determines how you handle authentication, database provisioning, scaling, and request latency.

## Execution Environment and Runtime Architecture

### Docker Container Runtime

In the Docker model, OpenSEO runs inside a Linux container on a host you fully control—whether a local machine, virtual private server, or on-premise hardware. According to `Dockerfile.selfhost`, the image bundles a complete **Node.js** runtime environment and executes the application as a traditional long-running process. You must provision and connect a **PostgreSQL** database (or Cloudflare D1 via tunnel) separately, managing the container lifecycle through Docker Compose or orchestration platforms like Kubernetes.

### Cloudflare Edge Runtime

The Cloudflare Workers deployment compiles OpenSEO into a lightweight **V8 isolate** that runs on Cloudflare's global network. The `wrangler.jsonc` configuration file defines how Wrangler bundles the code and uploads it to Cloudflare's edge nodes. Unlike Docker, this serverless model requires no persistent container; instead, the platform spins up execution environments on-demand at the nearest data center to the requesting user.

## Infrastructure and Deployment Workflow

### Docker Compose Method

Deploying via Docker relies on the [`compose.yaml`](https://github.com/every-app/open-seo/blob/main/compose.yaml) file, which pulls the container image from GitHub Container Registry (`ghcr.io/every-app/open-seo:latest`). You control the deployment through standard Docker commands:

```bash

# Configure local environment

cp .env.example .env

# Edit DATAFORSEO_API_KEY, optional PORT, etc.

# Start services

docker compose up -d

```

This approach requires you to manually configure networking, TLS termination, and reverse proxies. Version pinning is achieved by setting `OPEN_SEO_IMAGE=ghcr.io/every-app/open-seo:<tag>` in your environment file and restarting the service.

### Cloudflare Wrangler Automation

The Cloudflare pathway automates infrastructure provisioning through the `pnpm deploy:selfhost --yes` command. As implemented in [`scripts/selfhost-preflight.ts`](https://github.com/every-app/open-seo/blob/main/scripts/selfhost-preflight.ts), this script validates local configuration before creating **Cloudflare D1** databases, **KV** namespaces, and **R2** buckets automatically. The deployment flow requires Cloudflare authentication via `pnpm alchemy login` and bootstraps the state store with `pnpm alchemy cloudflare bootstrap`:

```bash

# Authenticate and bootstrap

pnpm alchemy login
pnpm alchemy cloudflare bootstrap

# Configure self-host environment

cp .env.selfhost.example .env.selfhost

# Edit DATAFORSEO_API_KEY, ACCESS_ALLOWED_EMAILS, etc.

# Deploy to edge

pnpm deploy:selfhost --yes

```

## Authentication and Security Models

### Local No-Auth Mode (Docker)

By default, Docker deployments set `AUTH_MODE=local_noauth`, disabling internal application authentication. Security responsibility shifts entirely to your infrastructure; you must protect the exposed TCP port (default `3001`) using a reverse proxy, VPN tunnel, or private network segmentation.

### Zero-Trust Access (Cloudflare)

Cloudflare Workers installations leverage **Cloudflare Access** out-of-the-box. The deployment creates a Zero-Trust application requiring authentication via the email addresses specified in `ACCESS_ALLOWED_EMAILS`. TLS termination and DDoS protection are handled automatically by Cloudflare's global CDN, with no additional proxy configuration required.

## Storage and Database Architecture

Docker self-hosting requires you to attach a **PostgreSQL** database yourself, typically defined alongside the application container in your Compose configuration or connected to an external managed database service. All state persists on infrastructure you maintain.

Conversely, the Cloudflare deployment provisions **D1** (serverless SQLite), **KV** (key-value store), and **R2** (object storage) automatically during the `deploy:selfhost` execution. This eliminates database server maintenance but binds your data to Cloudflare's platform.

## Networking and Global Distribution

Docker exposes a single TCP port that you must route to the internet manually, creating a single point of origin for all traffic. Cloudflare Workers automatically deploys to a `*.workers.dev` subdomain (or custom domain) with global anycast routing, serving requests from the nearest edge location without additional configuration.

## Scalability Characteristics

Scaling Docker requires horizontal container replication via Docker Swarm, Kubernetes, or larger host provisioning—operations you must manage yourself. Cloudflare Workers offers implicit scaling; the platform automatically distributes execution across its global infrastructure, handling load spikes without manual intervention or container orchestration.

## Deployment Quickstart Examples

### Docker Self-Hosting

Following the instructions in [`docs/SELF_HOSTING_DOCKER.md`](https://github.com/every-app/open-seo/blob/main/docs/SELF_HOSTING_DOCKER.md):

```bash

# 1. Prepare environment variables

cp .env.example .env

# Edit .env to set DATAFORSEO_API_KEY

# 2. Launch container stack

docker compose up -d

# 3. Verify health endpoint

curl http://localhost:3001/api/health

```

### Cloudflare Workers Self-Hosting

Following the instructions in [`docs/SELF_HOSTING_CLOUDFLARE.md`](https://github.com/every-app/open-seo/blob/main/docs/SELF_HOSTING_CLOUDFLARE.md):

```bash

# 1. Clone and setup

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

# 2. Authenticate with Cloudflare

pnpm alchemy login
pnpm alchemy cloudflare bootstrap

# 3. Configure deployment

cp .env.selfhost.example .env.selfhost

# Edit ACCESS_ALLOWED_EMAILS, DATAFORSEO_API_KEY

# 4. Deploy

pnpm deploy:selfhost --yes

# 5. Test deployment

curl https://<your-worker>.workers.dev/api/health

```

## Summary

- **Docker** runs OpenSEO as a containerized Node.js process on your infrastructure, requiring manual database provisioning, reverse proxy configuration, and scaling management.
- **Cloudflare Workers** executes OpenSEO as V8 isolates on Cloudflare's edge network, automatically provisioning D1, KV, and R2 storage while handling global distribution, TLS, and authentication via Cloudflare Access.
- **Authentication** defaults to disabled (`local_noauth`) in Docker, placing security burden on your network architecture, whereas Cloudflare enforces Zero-Trust Access with email-based authentication.
- **Deployment** involves `docker compose up -d` for Docker versus `pnpm deploy:selfhost --yes` for Cloudflare, with the latter automating infrastructure creation defined in `wrangler.jsonc`.
- **Scaling** is manual in Docker (container replication) and automatic in Cloudflare Workers (serverless edge distribution).

## Frequently Asked Questions

### Which self-hosting option is easier for beginners?

**Cloudflare Workers self-hosting requires less infrastructure knowledge** because the `pnpm deploy:selfhost --yes` command automatically provisions databases, storage, and security policies. Docker requires familiarity with container networking, reverse proxies, and PostgreSQL administration, making it better suited for teams with existing DevOps expertise.

### Can I migrate from Docker to Cloudflare Workers without losing data?

**Migration requires manual data export and import** because Docker typically uses PostgreSQL while Cloudflare uses D1 (SQLite-compatible). You would need to export your PostgreSQL data and import it into the D1 database created by the Cloudflare deployment, as the two storage backends use different SQL dialects and connection methods.

### How do costs compare between Docker and Cloudflare Workers self-hosting?

**Docker costs are limited to your host and database expenses** (VM rental or hardware amortization), while Cloudflare Workers incurs usage-based charges for D1 queries, KV reads/writes, and R2 storage. Note that Cloudflare R2 requires a payment method on file even for the free tier, whereas Docker self-hosting can run entirely on free open-source software.

### Is telemetry collected in both deployment modes?

**Yes, both modes send telemetry to OpenSEO's backend by default**, though it can be disabled in Docker by setting `OPENSEO_TELEMETRY_DISABLED=1` in your environment file. The Cloudflare Workers implementation runs the same telemetry logic within the V8 isolate, requiring no additional container-level configuration to operate.