Sign inSign up

serpapi/serptrail

By serpapi

Updated 2 months ago

SerpTrail is a self-hosted SEO and GEO rank tracker built with Ruby on Rails and SQLite.

Image
API management
Monitoring & observability
Web analytics
0

467

serpapi/serptrail repository overview

SerpTrail

SerpTrail is a self-hosted SEO rank tracker built with Ruby on Rails and SQLite. It helps you monitor how your websites rank for important keywords across locations, keep historical position data, and inspect SERP snapshots over time.

It uses SerpApi for Google search results and includes an optional AI chat assistant powered by OpenAI via RubyLLM. The assistant can answer questions about your tracked keywords, historical rankings, competitors, and live search data when API keys are configured.

Features

  • Track multiple websites and keywords
  • Track rankings across multiple Google locations/country codes
  • Daily, weekly, biweekly, or monthly checks
  • Historical ranking charts and search run history
  • AI Overview citation tracking
  • Competitor discovery from live search results
  • Built-in chat assistant for SEO questions
  • SQLite-backed for simple self-hosting
  • Background jobs via Solid Queue

Docker image

docker pull serpapi/serptrail:latest

The container listens on port 80.

SerpTrail’s production configuration assumes it is running behind an HTTPS-terminating reverse proxy. For real deployments, put it behind Caddy, Traefik, Nginx, Kamal Proxy, Cloudflare Tunnel, or another TLS proxy.

Required environment variables

SerpTrail stores API keys encrypted in the database, so Active Record encryption keys must stay stable for the lifetime of your data.

VariableRequiredDescription
SECRET_KEY_BASEYesRails secret used for signing/encryption. Generate once and keep stable.
HTTP_AUTH_USERNAMEYesUsername for built-in HTTP Basic Auth.
HTTP_AUTH_PASSWORDYesPassword for built-in HTTP Basic Auth.
AR_ENCRYPTION_PRIMARY_KEYYesRails Active Record encryption primary key.
AR_ENCRYPTION_DETERMINISTIC_KEYYesRails Active Record encryption deterministic key.
AR_ENCRYPTION_KEY_DERIVATION_SALTYesRails Active Record encryption salt.
SOLID_QUEUE_IN_PUMARecommendedSet to true for a simple one-container deployment with background jobs in the web process.
SERPAPI_API_KEYOptionalInitial SerpApi key seed value. You can also set it later in /settings.
OPENAI_API_KEYOptionalInitial OpenAI key seed value / fallback for chat. You can also set it later in /settings.
RAILS_LOG_LEVELOptionalDefaults to info. Use debug, warn, or error as needed.

Generate SECRET_KEY_BASE with Rails:

docker run --rm serpapi/serptrail:latest bin/rails secret

Generate Active Record encryption keys with Rails:

docker run --rm serpapi/serptrail:latest bin/rails db:encryption:init

The encryption command prints values for:

AR_ENCRYPTION_PRIMARY_KEY
AR_ENCRYPTION_DETERMINISTIC_KEY
AR_ENCRYPTION_KEY_DERIVATION_SALT

Quick start with docker run

Create a persistent volume for SQLite databases and Active Storage files:

docker volume create serptrail_storage

Run the app:

docker run -d \
  --name serptrail \
  -p 80:80 \
  -v serptrail_storage:/rails/storage \
  -e SECRET_KEY_BASE="change-me-generate-a-long-random-value" \
  -e HTTP_AUTH_USERNAME="admin" \
  -e HTTP_AUTH_PASSWORD="change-me" \
  -e AR_ENCRYPTION_PRIMARY_KEY="change-me-generate-once" \
  -e AR_ENCRYPTION_DETERMINISTIC_KEY="change-me-generate-once" \
  -e AR_ENCRYPTION_KEY_DERIVATION_SALT="change-me-generate-once" \
  -e SOLID_QUEUE_IN_PUMA="true" \
  serpapi/serptrail:latest

The container entrypoint runs database preparation automatically before the Rails server starts.

Open your deployed URL and sign in with the HTTP Basic Auth credentials you configured.

First setup in the web UI

After the container starts:

  1. Visit /settings.
  2. Add your SerpApi key to enable keyword checks and live Google search tools.
  3. Add your OpenAI key to enable the chat assistant.
  4. Add sites and keywords.
  5. SerpTrail will schedule checks according to each keyword’s frequency.

Docker Compose example

Create docker-compose.yml:

services:
  web:
    image: serpapi/serptrail:latest
    ports:
      - "80:80"
    environment:
      SECRET_KEY_BASE: "change-me-generate-a-long-random-value"
      HTTP_AUTH_USERNAME: "admin"
      HTTP_AUTH_PASSWORD: "change-me"
      AR_ENCRYPTION_PRIMARY_KEY: "change-me-generate-once"
      AR_ENCRYPTION_DETERMINISTIC_KEY: "change-me-generate-once"
      AR_ENCRYPTION_KEY_DERIVATION_SALT: "change-me-generate-once"
      SOLID_QUEUE_IN_PUMA: "true"
      # Optional initial values; these can also be configured in /settings.
      # SERPAPI_API_KEY: "your-serpapi-key"
      # OPENAI_API_KEY: "your-openai-key"
    volumes:
      - serptrail_storage:/rails/storage
    restart: unless-stopped

volumes:
  serptrail_storage:

Start it:

docker compose up -d

Tail logs:

docker compose logs -f

Stop it:

docker compose down

Data remains in the serptrail_storage volume. To delete all app data too, run:

docker compose down -v

Running background jobs separately

For a small single-container deployment, SOLID_QUEUE_IN_PUMA=true is the easiest option.

For larger deployments, run jobs in a separate container instead:

services:
  web:
    image: serpapi/serptrail:latest
    ports:
      - "80:80"
    environment:
      SOLID_QUEUE_IN_PUMA: "false"
      # include the same required env vars as above
    volumes:
      - serptrail_storage:/rails/storage
    restart: unless-stopped

  jobs:
    image: serpapi/serptrail:latest
    command: ./bin/jobs
    environment:
      # include the same required env vars as web
    volumes:
      - serptrail_storage:/rails/storage
    depends_on:
      - web
    restart: unless-stopped

volumes:
  serptrail_storage:

Both containers must share the same /rails/storage volume because SerpTrail uses SQLite.

Backups

SerpTrail stores its SQLite databases and local files under:

/rails/storage

Back up the Docker volume mounted at that path. Do not rotate the Active Record encryption keys unless you are prepared to lose access to encrypted values already stored in the database.

Health check

SerpTrail exposes a basic Rails health endpoint:

/up

Source

Built by SerpApi.

Tag summary

Content type

Image

Digest

sha256:121f14035

Size

204.5 MB

Last updated

2 months ago

docker pull serpapi/serptrail