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

> Compare Docker vs Cloudflare for self-hosting OpenSEO. Learn about local container vs edge Worker deployments, storage, and authentication for your SEO tool.

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

---

**Docker self-hosting runs OpenSEO in a local container with SQLite storage and disabled authentication, while Cloudflare deploys it as an edge Worker with D1 database, KV storage, and built-in Access authentication.**

OpenSEO from the `every-app/open-seo` repository offers two distinct paths for self-hosting: containerized local deployment via Docker or serverless edge deployment through Cloudflare. Both approaches support the core SEO auditing functionality but differ fundamentally in runtime architecture, authentication models, and data persistence strategies.

## Execution Environment and Architecture

### Docker Container Runtime

The Docker approach bundles OpenSEO into a containerized Node.js environment using **`Dockerfile.selfhost`**. It runs on the standard `node:22` base image and executes via **[`docker-entrypoint.sh`](https://github.com/every-app/open-seo/blob/main/docker-entrypoint.sh)**, which handles database migrations and service startup. This gives you full control over the runtime on any machine with Docker Engine installed, making it ideal for sandboxed or on-premises environments.

### Cloudflare Workers Edge Runtime

Cloudflare deployment compiles OpenSEO into a Worker script that runs in Cloudflare's V8 isolate environment across their global edge network. Unlike Docker's persistent container, this serverless model automatically distributes requests to the nearest data center without managing underlying infrastructure or maintaining server instances.

## Authentication and Security Models

### Docker Local No-Auth Setup

By default, Docker self-hosting sets **`AUTH_MODE=local_noauth`**, which disables authentication checks entirely and uses a built-in `admin@localhost` user. You must place the container behind your own reverse proxy, VPN, or tunnel if you require access control, as the application itself performs no authorization validation when running in this mode.

### Cloudflare Access Integration

The Cloudflare method automatically provisions Cloudflare Access during deployment, creating an identity-aware proxy in front of the Worker. Only email addresses specified in **`ACCESS_ALLOWED_EMAILS`** can authenticate through the login gate, providing zero-trust security without additional configuration.

## Data Persistence and Storage

### SQLite File Storage in Docker

Docker deployments use a local SQLite database file stored inside the container filesystem, persisted through Docker volumes if configured. This file-based approach requires manual backup strategies and is limited to the storage capacity of your host machine, with data living in the container's `/app` directory unless mapped to a host volume.

### Managed Cloudflare D1 and KV

Cloudflare self-hosting automatically provisions **D1** (a serverless SQLite-compatible database), **KV** namespaces for key-value storage, and **R2** buckets for static assets during the **`pnpm deploy:selfhost`** execution. These managed services eliminate backup responsibilities and provide automatic replication across Cloudflare's infrastructure.

## Deployment Workflow Comparison

### Docker Compose Quick Start

Deploying via Docker requires a single command after configuring your environment variables:

```bash
cp .env.example .env

# Edit DATAFORSEO_API_KEY and other variables

docker compose up -d

```

The **[`compose.yaml`](https://github.com/every-app/open-seo/blob/main/compose.yaml)** file pulls the pre-built image from GHCR or builds locally using **`Dockerfile.selfhost`**, depending on your `OPEN_SEO_IMAGE` setting. The [`docker-entrypoint.sh`](https://github.com/every-app/open-seo/blob/main/docker-entrypoint.sh) script automatically runs database migrations on startup.

### Cloudflare CLI Deployment

The Cloudflare workflow uses Node.js tooling to provision resources and deploy:

```bash
git clone https://github.com/every-app/open-seo.git
cd open-seo
corepack enable && pnpm install
pnpm alchemy login
pnpm alchemy cloudflare bootstrap
cp .env.selfhost.example .env.selfhost
pnpm deploy:selfhost --yes

```

The **`scripts/selfhost-deploy-preflight.mjs`** script validates prerequisites before the deployment creates the Worker, D1 database, and Access policies in a single atomic operation.

## Scalability and Operational Considerations

**Docker** deployments scale vertically on your host machine or require manual load balancing across multiple containers for horizontal scaling. This suits development environments, small teams, or air-gapped networks where you maintain complete infrastructure control.

**Cloudflare** deployments inherit global edge distribution automatically, handling traffic spikes without configuration changes. The serverless model suits production internet-facing deployments requiring high availability and minimal operational overhead.

## Telemetry Configuration

Both hosting methods include anonymous telemetry enabled by default, sending usage events to help improve the project. Disable this by setting **`OPENSEO_TELEMETRY_DISABLED=1`** in your environment variables, applicable to both Docker and Cloudflare configurations.

## Summary

- **Docker** provides a containerized Node.js runtime with local SQLite storage, requiring external authentication mechanisms and manual scaling.
- **Cloudflare** offers serverless edge execution with managed D1/KV/R2 storage, built-in Access authentication, and automatic global distribution.
- **Authentication** differs significantly: Docker uses `AUTH_MODE=local_noauth` with no built-in security, while Cloudflare enforces identity verification through Access policies.
- **Deployment complexity** favors Docker for quick local testing (`docker compose up -d`) and Cloudflare for production-grade zero-trust deployments (`pnpm deploy:selfhost`).
- **Data persistence** requires volume management in Docker but is fully managed with automatic backups in Cloudflare's serverless stack.

## Frequently Asked Questions

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

Migration requires exporting your SQLite database from the Docker container and importing it into Cloudflare D1. The schemas are compatible since both use SQLite, but you must manually transfer the database file contents as there is no automated migration path between the two deployment models.

### Which option is better for a development environment?

Docker is ideal for local development because the `docker compose up -d` command spins up the entire stack instantly without requiring Cloudflare account setup or internet-dependent edge services. The `AUTH_MODE=local_noauth` configuration eliminates authentication friction during rapid iteration.

### Does Cloudflare hosting cost more than Docker self-hosting?

Docker self-hosting only incurs costs for your own server infrastructure and the DataForSEO API key. Cloudflare hosting utilizes free-tier allowances for Workers, D1, and KV up to certain limits, though heavy usage may incur charges based on Cloudflare's pricing model. Both require the same DataForSEO API subscription regardless of hosting method.

### How do I secure my Docker deployment since it has no authentication?

You must place the Docker container behind a reverse proxy such as Nginx with basic authentication, a VPN tunnel like WireGuard or Tailscale, or a private network firewall. The application explicitly disables auth checks with `AUTH_MODE=local_noauth`, so never expose the container directly to the public internet without additional protection layers.