# Docker vs Cloudflare Workers Self-Hosting for OpenSEO: Key Architectural Differences

> Explore Docker vs Cloudflare Workers self-hosting for OpenSEO. Understand key architectural differences in containerized Node.js versus serverless edge functions with automatic storage provisioning.

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

---

**OpenSEO supports both Docker and Cloudflare Workers self-hosting, but Docker runs in a containerized Node.js environment requiring manual infrastructure management, while Cloudflare Workers deploys as serverless edge functions with automatic provisioning of D1, KV, and R2 storage.**

The every-app/open-seo repository offers two distinct paths for running the SEO platform on your own infrastructure. While both approaches execute the same application logic, they differ fundamentally in runtime architecture, deployment workflows, and operational overhead. Understanding these Docker vs Cloudflare Workers self-hosting distinctions ensures you select the model that aligns with your security, scaling, and cost requirements.

## Execution Environment and Runtime Architecture

Docker self-hosting executes OpenSEO inside a **Linux container** on infrastructure you control. The container runs a full **Node.js runtime** and connects to a PostgreSQL or D1 database that you provision and manage separately.

In contrast, Cloudflare Workers self-hosting runs OpenSEO as an **Edge Worker** on Cloudflare’s global network. The runtime uses a lightweight **V8 isolate** rather than a full Node.js environment. The build process bundles your code via Wrangler—configured in `wrangler.jsonc`—and uploads it to Cloudflare’s edge, where it executes geographically close to your users.

## Deployment Workflows and Commands

The Docker deployment model relies on container orchestration commands. As documented in [`docs/SELF_HOSTING_DOCKER.md`](https://github.com/every-app/open-seo/blob/main/docs/SELF_HOSTING_DOCKER.md), you pull the image from GitHub Container Registry and start services with Docker Compose:

```bash

# Copy environment template

cp .env.example .env

# Edit DATAFORSEO_API_KEY, then launch

docker compose up -d

```

The Cloudflare Workers deployment automates infrastructure provisioning through a single command. According to [`docs/SELF_HOSTING_CLOUDFLARE.md`](https://github.com/every-app/open-seo/blob/main/docs/SELF_HOSTING_CLOUDFLARE.md), the `pnpm deploy:selfhost --yes` command provisions Cloudflare D1, KV namespaces, and R2 buckets, runs database migrations, and publishes the Worker:

```bash

# Authenticate and bootstrap

pnpm alchemy login
pnpm alchemy cloudflare bootstrap

# Copy self-host config and deploy

cp .env.selfhost.example .env.selfhost
pnpm deploy:selfhost --yes

```

The [`scripts/selfhost-preflight.ts`](https://github.com/every-app/open-seo/blob/main/scripts/selfhost-preflight.ts) file performs local validation before the Cloudflare deployment proceeds, checking environment variables and credentials.

## Authentication and Security Models

Security architectures diverge significantly between the two hosting options. Docker defaults to `AUTH_MODE=local_noauth`, meaning the application handles no authentication internally. You must protect the container using a reverse proxy, private network tunnel, or external authentication layer.

Cloudflare Workers integrates **Cloudflare Access** out-of-the-box. The deployment creates an Access application that enforces Zero-Trust authentication, requiring login from emails specified in the `ACCESS_ALLOWED_EMAILS` environment variable before granting entry to the application.

## Networking and TLS Configuration

Docker exposes OpenSEO on a single TCP port defined by the `PORT` environment variable (default **3001**). You must configure TLS termination, certificate management, and reverse proxy rules manually, typically using nginx, Traefik, or a cloud load balancer.

Cloudflare Workers automatically handles networking infrastructure. The deployment exposes your application under a `*.workers.dev` subdomain or a custom domain you bind, with **automatic TLS termination** and global CDN routing handled by Cloudflare’s edge network.

## Data Storage and State Management

Stateful storage requirements differ based on your hosting choice. Docker requires you to attach a Postgres database manually, typically via Docker Compose or an external managed service, as defined in [`compose.yaml`](https://github.com/every-app/open-seo/blob/main/compose.yaml).

Cloudflare Workers automatically creates managed storage resources during deployment:
- **Cloudflare D1** for relational data
- **KV namespaces** for key-value storage
- **R2 buckets** for object storage

No external database server provisioning is required for the Workers deployment.

## Scaling Characteristics

Scaling behavior represents a fundamental architectural difference. Docker requires manual scaling through container orchestration platforms like Docker Swarm or Kubernetes, or by provisioning larger host instances to handle increased load.

Cloudflare Workers provides **implicit automatic scaling**. Each incoming request is served by the nearest Cloudflare edge node, with the platform automatically distributing load across its global infrastructure without operational intervention.

## Cost Considerations

Docker self-hosting follows a traditional infrastructure cost model. You pay only for the host machine (whether on-premise hardware or cloud VM) and any external database services you provision.

Cloudflare Workers incurs costs based on actual usage of **D1 queries**, **KV operations**, and **R2 storage/egress**. While many operations fall within Cloudflare’s free tier, R2 requires a payment method even when usage remains free, and higher volumes may necessitate a paid Cloudflare plan.

## Summary

- **Docker** runs OpenSEO in a containerized Node.js environment on your own infrastructure, requiring manual database setup, reverse proxy configuration, and scaling management.
- **Cloudflare Workers** deploys to a serverless edge runtime with automatic provisioning of D1, KV, and R2 storage, built-in Zero-Trust authentication, and global auto-scaling.
- Choose **Docker** when you need full control over the host environment, require private network isolation, or want to minimize external vendor dependencies.
- Choose **Cloudflare Workers** when you prioritize global low-latency distribution, minimal operational overhead, and automatic infrastructure provisioning.

## Frequently Asked Questions

### Which self-hosting option provides better performance for global users?

Cloudflare Workers delivers superior global performance through its edge network architecture. Requests execute on V8 isolates at the nearest Cloudflare data center, providing sub-millisecond latency worldwide without requiring multi-region Docker deployments or complex load balancing configurations.

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

Migration between platforms requires manual data transfer since storage systems differ. Docker typically uses PostgreSQL, while Cloudflare Workers uses D1. You would need to export your PostgreSQL data and import it into D1, then update environment variables in `.env.selfhost` before running `pnpm deploy:selfhost --yes`.

### Is authentication required for the Docker deployment?

Docker deployments default to `AUTH_MODE=local_noauth`, meaning no authentication is enforced by the application itself. You must implement authentication at the infrastructure layer using a reverse proxy with authentication, VPN tunnels, or private network segmentation to secure access.

### What happens to telemetry data in each hosting model?

Both deployments send telemetry to OpenSEO’s backend by default. In Docker, you can disable this by setting `OPENSEO_TELEMETRY_DISABLED=1` in your `.env` file. The Cloudflare Workers deployment includes the same telemetry logic but executes it within the Worker environment without requiring additional configuration.