RankSurge

Docker Self-Hosting

Run RankSurge locally with Docker Compose using the published GHCR image.

Run RankSurge locally with Docker.

In Docker mode, RankSurge uses AUTH_MODE=local_noauth (no auth checks, local admin user admin@localhost). Only expose it behind your own auth-protected reverse proxy, tunnel, or private network. For internet-facing self-hosting, use Cloudflare instead.

The default compose.yaml builds RankSurge from this checkout as ranksurge:local. Set RANKSURGE_IMAGE to use a different image name; the legacy OPEN_SEO_IMAGE variable is still accepted. The Compose project, service key open-seo, and named data volume keep their existing identities across the folder rename.

Prerequisites

Quickstart

Clone the repo, then:

git clone https://github.com/shekhu10/RankSurge.git
cd RankSurge
cp .env.example .env

Set DATAFORSEO_API_KEY in .env using the DataForSEO setup guide, then start RankSurge:

docker compose up -d --build

Open http://localhost:<PORT> (default 3001). Each container start builds the app and may take 1-2 minutes; follow progress with docker compose logs -f.

Optional env values:

  • PORT (defaults to 3001)
  • ALLOWED_HOST (single reverse-proxy hostname to allow in Vite preview)
  • AUTH_MODE=local_noauth (already set in compose)
  • RANKSURGE_IMAGE (defaults to ranksurge:local)

If you are putting Docker behind a reverse proxy or a temporary tunnel, remember that Docker self-hosting runs with app auth disabled. Only expose it behind your own auth-protected reverse proxy, tunnel, or private network, and add the public hostname before restarting:

ALLOWED_HOST=yourdomain.com docker compose up -d --build

You can also persist it in .env.

Telemetry

Self-host telemetry is off by default in RankSurge. The heartbeat inherited from the upstream OpenSEO project reports to the upstream maintainers' PostHog, so nothing is sent unless you opt in.

To opt in, set OPENSEO_TELEMETRY_DISABLED=0 in .env, then run docker compose up -d --no-build --force-recreate open-seo. When enabled, it sends anonymized heartbeats with aggregate counts (installs, users, projects, feature usage) tied to a random install ID, every 5 minutes during the first two hours after install and then at most once daily, plus failed setup check names and statuses (never values or error messages). No URLs, keywords, prompts, emails, or IP-derived location are collected, and idle installs send nothing. DO_NOT_TRACK=1 always wins.

Heartbeats are triggered by requests to the app or MCP server. Requests to /api/health, including Docker's automatic health checks, do not trigger telemetry.

Pin to a specific image tag

To use an existing published image, set RANKSURGE_IMAGE in .env to its registry path and tag. Use a tag that your registry actually provides; this checkout does not require a published RankSurge image. Then run:

docker compose pull open-seo
docker compose up -d --no-build open-seo

Do not pass --build for a pinned image: that would rebuild the checkout and overwrite the selected local image tag.

Build your own image locally

If you are testing local code changes, build and run a local tag:

docker build -f Dockerfile.selfhost -t ranksurge:local .
RANKSURGE_IMAGE=ranksurge:local docker compose up -d --no-build

Common commands

Restart service after env changes:

docker compose up -d --no-build open-seo

Update a published image (requires RANKSURGE_IMAGE in .env):

docker compose pull open-seo
docker compose up -d --no-build open-seo

Stop:

docker compose down

Health and troubleshooting

Startup checks appear in docker compose logs before the build. Once running, /api/health reports configuration and database status, and docker compose ps reports container health.

Troubleshooting environment variables

To confirm Docker Compose is using the expected environment variables:

docker compose config

Check that AUTH_MODE=local_noauth, and that DATAFORSEO_API_KEY is the base64 encoded value of your DataForSEO email and API password in this format: email:password.

If you changed .env, recreate the container so Compose reapplies it:

docker compose up -d --no-build --force-recreate open-seo