# Docker vs Cloudflare Deployment for OpenSEO: 7 Key Differences Explained

> Explore Docker vs Cloudflare deployment for OpenSEO. Understand key differences in execution, storage, and authentication to choose the best fit for your project.

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

---

**Docker and Cloudflare deployments differ fundamentally in execution environment, data storage, authentication model, and operational responsibility—Docker runs locally with SQLite and no built-in auth, while Cloudflare runs on the edge with D1/KV/R2 storage and Cloudflare Access authentication.**

OpenSEO, the open‑source SEO intelligence platform from `every-app/open-seo`, supports two primary self‑hosting strategies. While both run identical application code, the **deployment method you choose** determines your infrastructure footprint, security model, and maintenance workflow. This guide breaks down the technical distinctions between Docker and Cloudflare deployments based on the actual source implementation.

## Execution Environment: Container vs Edge Worker

The most fundamental difference lies in where your code runs.

**Docker deployment** executes inside a container on infrastructure you control. As defined in `Dockerfile.selfhost`, the image bundles the Node.js runtime and launches the app via `docker compose`. The service binds to a local port (default `3001`) and remains isolated to your host network.

**Cloudflare deployment** compiles the same source into a V8 isolate that runs on Cloudflare's edge network. The Worker is distributed globally, with requests routed to the nearest point of presence. No persistent server process exists—each request spins up a fresh execution context.

This architectural split affects cold-start latency, geographic reach, and resource scaling without configuration changes.

## Provisioning Workflow: Manual vs Automated

Docker requires minimal setup but manual orchestration.

```bash

# Docker: pull and run

cp .env.example .env

# edit .env with DATAFORSEO_API_KEY, etc.

docker compose up -d

```

Cloudflare deployment automates infrastructure provisioning through Alchemy, the infrastructure-as-code toolkit used by OpenSEO.

```bash

# Cloudflare: single-command provisioning

pnpm install
pnpm alchemy login
pnpm alchemy cloudflare bootstrap
pnpm deploy:selfhost --yes

```

The `pnpm deploy:selfhost --yes` command, documented in [`docs/SELF_HOSTING_CLOUDFLARE.md`](https://github.com/every-app/open-seo/blob/main/docs/SELF_HOSTING_CLOUDFLARE.md), creates:
- A **D1 database** for relational data
- **KV namespaces** for key‑value caching
- An **R2 bucket** for object storage
- A **Cloudflare Access application** for authentication

No equivalent automation exists for Docker—you manage storage volumes, networking, and auth integration yourself.

## Data Persistence: Local SQLite vs Managed Cloud Services

| Storage Layer | Docker | Cloudflare |
|-------------|--------|-----------|
| Primary database | Local SQLite file (`sqlite.db`) | Cloudflare D1 (SQLite‑compatible) |
| Caching | In‑memory or local Redis (manual setup) | Native KV namespaces |
| Object storage | Local filesystem or self‑hosted MinIO | Cloudflare R2 |
| Backup/restore | Manual file operations | D1 snapshots via CLI/API |

In Docker, the SQLite database lives inside the container filesystem. Data persists across restarts only if you mount a volume—`docker compose down` without volume preservation destroys all data.

Cloudflare D1 provides managed replication, automated backups, and point‑in‑time recovery. When you run `pnpm alchemy destroy`, D1 databases, KV stores, and R2 buckets are permanently deleted, making environment lifecycle management explicit and reversible.

## Authentication Model: Disabled by Default vs Cloudflare Access

Security posture diverges sharply between the two approaches.

Docker ships with **authentication disabled** (`AUTH_MODE=local_noauth`). The `.env.example` template sets this explicitly, assuming you'll place the container behind a corporate VPN, reverse proxy with basic auth, or Tailscale tunnel. No identity provider integration exists in the default configuration.

Cloudflare deployment **mandates authentication** through Cloudflare Access. The `ACCESS_ALLOWED_EMAILS` environment variable defines an allowlist of email addresses that can reach the Worker. Unauthorized requests are intercepted at Cloudflare's network edge before reaching your code, with customizable login methods (one‑time PIN, SAML, OIDC) configurable in the Zero‑Trust dashboard.

This represents a shift from application‑layer auth to network‑layer identity, reducing your attack surface but adding vendor dependency.

## Networking and Exposure: Internal vs Global

Docker exposes a single TCP port bound to localhost or your host's network interface. Reachability requires additional infrastructure:

- Port forwarding for external access
- Reverse proxy (Nginx, Caddy, Traefik) for TLS termination
- VPN or tunnel (Cloudflare Tunnel, ngrok) for secure remote access

Cloudflare Workers receive a public HTTPS URL immediately—`https://<worker>.workers.dev` by default, or your custom domain. Cloudflare handles TLS certificate provisioning, HTTP/2 and HTTP/3 termination, DDoS protection, and edge caching without configuration.

For teams needing rapid external sharing or client demonstrations, Cloudflare eliminates days of networking setup.

## Operational Responsibilities: You vs The Platform

| Responsibility | Docker | Cloudflare |
|--------------|--------|-----------|
| Runtime patching | You manage base image updates | Cloudflare manages V8 isolate |
| Database maintenance | Vacuum, backup, migration scripts | Automated by D1 |
| Scaling | Vertical (bigger host) or orchestrator (K8s) | Automatic to zero and unlimited |
| Uptime monitoring | Self‑implemented health checks | Cloudflare status dashboard |
| Log aggregation | Local stdout/file or external Loki | Cloudflare Logs/Analytics |

Docker maximizes control—you own the entire stack from kernel to application. Cloudflare trades control for operational simplicity, abstracting away infrastructure concerns common to small teams.

## Update and Teardown Workflows

Docker updates require image management:

```bash

# Update Docker deployment

docker compose pull        # fetch latest ghcr.io/every-app/open-seo:latest

docker compose up -d       # recreate containers

```

Data persists in mounted volumes unless explicitly pruned.

Cloudflare updates re‑provision infrastructure in place:

```bash

# Update Cloudflare deployment

git pull origin main
pnpm deploy:selfhost --yes

```

Schema migrations run automatically against D1.

Complete removal differs dramatically:

```bash

# Docker: stop containers, preserve volumes by default

docker compose down

# Cloudflare: destroy all cloud resources and data

pnpm alchemy destroy --env-file .env.selfhost --stage selfhost

```

The Alchemy destroy command, referenced in [`docs/SELF_HOSTING_CLOUDFLARE.md`](https://github.com/every-app/open-seo/blob/main/docs/SELF_HOSTING_CLOUDFLARE.md), provides clean environment teardown that Docker lacks by design.

## Cost Model: Local Resources vs Cloud Tier

Docker incurs **no cloud service charges**—only your underlying hardware costs (electricity, amortized server purchase, or VPS rental). The `ghcr.io/every-app/open-seo:latest` image pulls are free.

Cloudflare operates on a **generous free tier**: D1, KV, and R2 include substantial monthly allowances. Costs emerge only at scale or when using paid features like advanced Access policies. You also pay separately for the DataForSEO API key, required for both deployment modes.

For personal use or small teams, both approaches are effectively free. For production workloads, Cloudflare's pricing becomes predictable whereas Docker costs scale with your infrastructure management overhead.

## Summary

- **Execution**: Docker runs containers locally; Cloudflare runs V8 isolates on the global edge
- **Provisioning**: Docker requires manual `docker compose` setup; Cloudflare automates D1/KV/R2/Access creation via `pnpm deploy:selfhost --yes`
- **Storage**: Docker uses local SQLite; Cloudflare uses managed D1 with KV and R2
- **Authentication**: Docker disables auth by default; Cloudflare enforces Access‑based identity
- **Networking**: Docker needs manual proxy/VPN configuration; Cloudflare provides instant HTTPS endpoints
- **Operations**: Docker demands full infrastructure ownership; Cloudflare abstracts runtime management
- **Teardown**: Docker preserves data by default; Cloudflare's `alchemy destroy` permanently removes all resources

Choose Docker when you need **air‑gapped environments**, **custom networking**, or **existing container infrastructure**. Choose Cloudflare when you prioritize **rapid global deployment**, **zero infrastructure maintenance**, and **built‑in security gating**.

## Frequently Asked Questions

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

No direct migration path exists in the current OpenSEO codebase. Your SQLite database from Docker cannot be automatically imported into Cloudflare D1. You would need to export data manually and re‑import via D1's SQL API or restart data collection after switching deployment modes. Plan your choice based on long‑term storage needs.

### Does Cloudflare deployment work without a Cloudflare account?

No. The `pnpm alchemy login` command authenticates against Cloudflare's API, and `pnpm alchemy cloudflare bootstrap` requires account credentials to provision D1, KV, R2, and Access resources. The entire Cloudflare workflow is tied to their platform infrastructure; there is no hybrid or portable equivalent.

### Is Docker deployment suitable for production use?

Docker can serve production traffic but requires additional engineering effort. You must implement: TLS termination (via reverse proxy), authentication (via external IdP or proxy), backup procedures for the SQLite file, and monitoring/alerting. The OpenSEO documentation explicitly notes that Docker's `AUTH_MODE=local_noauth` is intended for local development unless augmented with external security controls.

### What happens to my data when I destroy a Cloudflare deployment?

Running `pnpm alchemy destroy --env-file .env.selfhost --stage selfhost` permanently deletes the Cloudflare Worker, D1 database, KV namespaces, R2 bucket, and Access application. All stored SEO data, cached results, and uploaded assets are irreversibly removed. OpenSEO provides no built‑in backup mechanism—export D1 data manually via the Cloudflare CLI if preservation is required.