# How to Run Open-SEO in a Docker Container: Complete Self-Hosting Guide

> Easily run Open-SEO in a Docker container for self-hosting. Follow our complete guide to set up and deploy this powerful SEO tool with Docker Compose. Get started now.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: how-to-guide
- Published: 2026-08-13

---

**Run Open-SEO locally using Docker Compose with a single command after configuring your environment variables and building the image.**

Open-SEO provides a streamlined Docker self-hosting workflow that packages the entire application stack—backend, database, and worker—into portable containers. This guide walks through running Open-SEO in a Docker container using the official `Dockerfile.selfhost` and [`compose.yaml`](https://github.com/every-app/open-seo/blob/main/compose.yaml) configuration from the every-app/open-seo repository.

## Prerequisites

Before starting, ensure you have:

- Docker Engine 20.10+ with Docker Compose v2
- A DataForSEO API key (required for SEO functionality)
- Git to clone the repository

## Step 1: Configure Environment Variables

Open-SEO requires specific environment variables to run in Docker mode. The repository includes an `.env.example` file that serves as a template.

Copy and customize the environment file:

```bash
cp .env.example .env

```

Edit `.env` to set at minimum:

```bash
DATAFORSEO_API_KEY=your-key-here
AUTH_MODE=local_noauth

```

The `AUTH_MODE=local_noauth` setting disables authentication checks and creates a default admin user at `admin@localhost`. Optional variables include:

- `OPENSEO_TELEMETRY_DISABLED` — set to `1` to opt out of telemetry
- `ALLOWED_HOST` — specify when running behind a reverse proxy

See `.env.example` in the repository root for the complete variable reference.

## Step 2: Build the Docker Image

The `Dockerfile.selfhost` at the repository root builds a production-ready image that compiles the TypeScript application and bundles the worker processes.

Build the image with a local tag:

```bash
docker build -f Dockerfile.selfhost -t open-seo:local .

```

This step compiles the application and creates a tagged image named `open-seo:local`. Rebuild this image whenever you modify the source code.

## Step 3: Start the Container Stack

The [`compose.yaml`](https://github.com/every-app/open-seo/blob/main/compose.yaml) file defines two services:

- `open-seo` — the main application container
- `postgres` — a throw-away PostgreSQL instance for local development

Launch both services in detached mode:

```bash
docker compose up -d

```

The first startup may take 1–2 minutes while the image builds and initializes. The web UI becomes available at `http://localhost:3001` once complete.

## Verify the Deployment

Confirm the container is healthy using the built-in health endpoint:

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

```

The [`src/routes/api/health.ts`](https://github.com/every-app/open-seo/blob/main/src/routes/api/health.ts) endpoint returns a JSON payload verifying that the container configuration is correct and the database is reachable. Alternatively, monitor startup logs:

```bash
docker compose logs -f open-seo

```

## Advanced Configuration

### Use a Custom Image Tag

Override the default image when testing custom builds:

```bash
OPEN_SEO_IMAGE=open-seo:local docker compose up -d

```

This pattern appears in the documentation at line 58 of [`docs/SELF_HOSTING_DOCKER.md`](https://github.com/every-app/open-seo/blob/main/docs/SELF_HOSTING_DOCKER.md).

### Run Behind a Reverse Proxy

Specify the allowed host for production deployments:

```bash
ALLOWED_HOST=mydomain.com docker compose up -d

```

### Disable Telemetry

Recreate the container with telemetry disabled:

```bash
OPENSEO_TELEMETRY_DISABLED=1 docker compose up -d --force-recreate open-seo

```

## Stop and Clean Up

Stop all containers while preserving data volumes:

```bash
docker compose down

```

Add `-v` to remove volumes and reset the database:

```bash
docker compose down -v

```

## Key Files Reference

| File | Purpose |
|------|---------|
| `Dockerfile.selfhost` | Production image build definition |
| [`compose.yaml`](https://github.com/every-app/open-seo/blob/main/compose.yaml) | Multi-service orchestration with PostgreSQL |
| [`docs/SELF_HOSTING_DOCKER.md`](https://github.com/every-app/open-seo/blob/main/docs/SELF_HOSTING_DOCKER.md) | Official step-by-step guide (lines 25, 58, 66, 87) |
| [`.github/workflows/docker-image.yml`](https://github.com/every-app/open-seo/blob/main/.github/workflows/docker-image.yml) | CI pipeline for automated builds |
| [`src/routes/api/health.ts`](https://github.com/every-app/open-seo/blob/main/src/routes/api/health.ts) | Container health verification endpoint (line 7) |
| `.env.example` | Environment variable template |

## Summary

- **Configuration**: Copy `.env.example` to `.env` and set `DATAFORSEO_API_KEY`
- **Build**: Run `docker build -f Dockerfile.selfhost -t open-seo:local .`
- **Deploy**: Execute `docker compose up -d` to start the stack
- **Access**: Open `http://localhost:3001` after the health check passes
- **Customize**: Override `OPEN_SEO_IMAGE` or `ALLOWED_HOST` for advanced scenarios

## Frequently Asked Questions

### What port does Open-SEO use in Docker?

Open-SEO serves the web UI on **port 3001** by default. Map this port in [`compose.yaml`](https://github.com/every-app/open-seo/blob/main/compose.yaml) if you need to expose it on a different host port.

### Does Open-SEO require a database when running in Docker?

Yes. The [`compose.yaml`](https://github.com/every-app/open-seo/blob/main/compose.yaml) includes a **throw-away PostgreSQL container** that automatically starts alongside the main application. Data persists in a Docker volume between restarts unless you run `docker compose down -v`.

### Can I disable authentication in the Docker container?

Yes. The `AUTH_MODE=local_noauth` setting (enabled by default in Docker mode) bypasses authentication and creates an admin user at `admin@localhost`. This is intentional for local development only—production deployments should configure proper authentication.

### How do I update Open-SEO when running in Docker?

Pull the latest code, rebuild the image with `docker build -f Dockerfile.selfhost -t open-seo:local .`, then restart with `docker compose up -d --force-recreate open-seo`. The `--force-recreate` flag ensures the new image is used.