Run with Docker

For running Replayowl on your own server. One file starts Replayowl and Postgres together. You need Docker and nothing else.

If you would rather not run a server, deploy to Cloudflare Workers instead.

1. Save this as docker-compose.yml

services:
  app:
    image: replayowl/replayowl:latest
    restart: unless-stopped
    ports:
      - "8790:8790"
    environment:
      DATABASE_URL: postgres://replayowl:replayowl@db:5432/replayowl
    volumes:
      - recordings:/data
    depends_on:
      db:
        condition: service_healthy
  db:
    image: postgres:17
    restart: unless-stopped
    environment:
      POSTGRES_USER: replayowl
      POSTGRES_PASSWORD: replayowl
      POSTGRES_DB: replayowl
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U replayowl -d replayowl"]
      interval: 5s
      retries: 10
volumes:
  recordings:
  pgdata:

2. Start it

docker compose up -d

Open http://127.0.0.1:8790/ and set the admin password. The dashboard stays empty until the first session arrives.

3. Record your site

Add the recorder to your pages, pointing at your server:

<script src="https://your-server/recorder.js" data-endpoint="https://your-server/api/ingest" defer></script>

Websites can only send recordings to a public address, so for real traffic put the server on a public domain behind a reverse proxy with HTTPS.

Before you go to production

  • Set SETUP_TOKEN so nobody else can claim the admin password on a fresh server: it is then asked for together with the first password.
  • Change POSTGRES_PASSWORD and the password in DATABASE_URL together.
  • Recordings stay in the recordings volume. To keep them in S3, R2 or any S3-compatible bucket instead, add the S3_* variables listed in Run on Node and Postgres.

If you already run Postgres, a single container is enough:

docker run -d -p 8790:8790 -v replayowl-data:/data \
  -e DATABASE_URL=postgres://user:pass@host:5432/replayowl \
  replayowl/replayowl:latest