# How to Deploy OpenSEO Using Docker for Local Testing

> Easily deploy OpenSEO locally with Docker Compose. Get instant access at http://localhost:3001 using GHCR images and PostgreSQL for quick testing.

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

---

**TLDR:** OpenSEO runs locally via Docker Compose using a pre-built GHCR image, a PostgreSQL container, and a `.env` file that defaults to `AUTH_MODE=local_noauth` for instant access at `http://localhost:3001`.

OpenSEO is a full-stack SEO analytics application designed for self-hosting. You can deploy OpenSEO using Docker for local testing in minutes by combining the official [[`compose.yaml`](https://github.com/every-app/open-seo/blob/main/compose.yaml)](https://github.com/every-app/open-seo/blob/main/compose.yaml), a published container image, and a few environment variables. This guide walks through the architecture, configuration files, and commands needed to get the stack running on your machine.

## Understanding the Docker Architecture

OpenSEO's Docker setup is optimized for quick local evaluation. The stack intentionally disables internal authentication and bundles the front-end, server functions, and database into a single Compose project.

### The Container Image and Compose Stack

By default, the stack pulls `ghcr.io/every-app/open-seo:latest` as documented in the project's [Docker guide](https://github.com/every-app/open-seo/blob/main/web/content/docs/self-hosting/docker.md). The root-level [[`compose.yaml`](https://github.com/every-app/open-seo/blob/main/compose.yaml)](https://github.com/every-app/open-seo/blob/main/compose.yaml) orchestrates two primary services:

- The **OpenSEO web container**, which packages the compiled Next.js / Vite front-end and Cloudflare-compatible server code.
- A **PostgreSQL** database using the `postgres:15-alpine` image to persist projects, keywords, and audits.

### Environment and Security Defaults

When running under Docker, the application automatically sets `AUTH_MODE=local_noauth`. This disables the built-in authentication flow and creates a default admin user (`admin@localhost`) so you can access the dashboard immediately.

You supply core settings through an `.env` file copied from [`.env.example`](https://github.com/every-app/open-seo/blob/main/.env.example). Critical variables include:

- `DATAFORSEO_API_KEY` – Required to fetch SEO data.
- `OPEN_SEO_IMAGE` – Overrides the default image tag (e.g., pin to a specific release).
- `ALLOWED_HOST` – Whitelists your external domain when running behind a reverse proxy.
- `PORT` – Defaults to `3001`.

### Telemetry and Server Functions

Anonymized usage metrics are collected by default via the logic in [[`src/server/lib/self-host-telemetry.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/self-host-telemetry.ts)](https://github.com/every-app/open-seo/blob/main/src/server/lib/self-host-telemetry.ts). You can opt out by setting `OPENSEO_TELEMETRY_DISABLED=1` or `DO_NOT_TRACK=1` in your `.env` file.

All server-side API endpoints—such as project creation, keyword tracking, and site audits—live under [`src/serverFunctions/`](https://github.com/every-app/open-seo/tree/main/src/serverFunctions) and execute inside the running container.

## Step-by-Step Local Deployment

Follow these steps to start OpenSEO on your local machine.

### Clone the Repository and Configure the Environment

First, clone the repository and prepare your environment file:

```bash
git clone https://github.com/every-app/open-seo.git
cd open-seo
cp .env.example .env

```

Open `.env` and add your `DATAFORSEO_API_KEY`. Verify that `AUTH_MODE=local_noauth` is present or leave it unset to accept the Compose default.

### Start the Stack

Run the following command to pull the image, build if necessary, and start all services:

```bash
docker compose up -d

```

The first start may take one to two minutes while the application compiles and runs database migrations.

### Verify the Deployment

Check that the containers are healthy:

```bash
docker compose ps

```

Then open your browser to `http://localhost:3001` (or the custom `PORT` you defined). You can also verify the backend status by querying the health endpoint:

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

```

## Custom Builds and Advanced Configuration

If you want to modify the source code or pin to a specific release, you can build locally or override the Compose environment.

### Build a Local Image with Dockerfile.selfhost

The repository includes a [`Dockerfile.selfhost`](https://github.com/every-app/open-seo/blob/main/Dockerfile.selfhost) for creating your own image. This is useful when testing local changes:

```bash
docker build -f Dockerfile.selfhost -t open-seo:local .
OPEN_SEO_IMAGE=open-seo:local docker compose up -d

```

### Update and Restart Commands

To pull the latest published image and recreate the container:

```bash
docker compose pull && docker compose up -d

```

If you change environment variables, force a fresh recreate:

```bash
docker compose up -d --force-recreate open-seo

```

Alternatively, restart only the application service:

```bash
docker compose up -d open-seo

```

### Disable Telemetry

Add one of the following lines to your `.env` file before starting the stack:

```bash
OPENSEO_TELEMETRY_DISABLED=1

```

Or:

```bash
DO_NOT_TRACK=1

```

## Common Docker Commands for OpenSEO

Keep these commands handy for day-to-day management:

- **View running services:** `docker compose ps`
- **Inspect effective configuration:** `docker compose config`
- **View logs:** `docker compose logs -f open-seo`
- **Stop the stack:** `docker compose down`
- **Stop and remove volumes:** `docker compose down -v`

## Summary

- OpenSEO is deployed locally via the root-level [[`compose.yaml`](https://github.com/every-app/open-seo/blob/main/compose.yaml)](https://github.com/every-app/open-seo/blob/main/compose.yaml) and a pre-built GHCR image.
- The Docker stack defaults to `AUTH_MODE=local_noauth` with an automatic `admin@localhost` user.
- You must copy [`.env.example`](https://github.com/every-app/open-seo/blob/main/.env.example) to `.env` and supply your `DATAFORSEO_API_KEY`.
- Use [`Dockerfile.selfhost`](https://github.com/every-app/open-seo/blob/main/Dockerfile.selfhost) to build custom images for development.
- Telemetry can be disabled with `OPENSEO_TELEMETRY_DISABLED=1` or `DO_NOT_TRACK=1`.
- Always verify the deployment with `docker compose ps` and the `/api/health` endpoint.

## Frequently Asked Questions

### What authentication mode does OpenSEO use in Docker?

OpenSEO uses `AUTH_MODE=local_noauth` when deployed through Docker Compose. This mode disables the internal authentication system and creates a default admin user at `admin@localhost`, allowing immediate access to the dashboard for local testing.

### How do I update to the latest OpenSEO Docker image?

Run `docker compose pull && docker compose up -d` from the repository root. This fetches the latest `ghcr.io/every-app/open-seo:latest` tag—or the tag specified by `OPEN_SEO_IMAGE` in your `.env` file—and recreates the container.

### Can I build my own OpenSEO image instead of using GHCR?

Yes. Use the provided [`Dockerfile.selfhost`](https://github.com/every-app/open-seo/blob/main/Dockerfile.selfhost) to build a local image, then set `OPEN_SEO_IMAGE=your-tag` in `.env` before running `docker compose up -d`. This workflow is ideal for testing source code modifications.

### Is it safe to expose the OpenSEO Docker container directly to the internet?

No. The Docker documentation recommends placing the container behind your own reverse proxy, tunnel, or private network. If you use a reverse proxy, set the `ALLOWED_HOST` environment variable to your external domain so the application correctly validates incoming requests.