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

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

cp .env.example .env

# Edit DATAFORSEO_API_KEY and other variables

docker compose up -d

The 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 script automatically runs database migrations on startup.

Cloudflare CLI Deployment

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

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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →