Skip to content
Docs menu · Overview & requirements

Self-hosting

Self-Hosting AnyReplay: Overview and Requirements

What a self-hosted AnyReplay deployment looks like: the services, host requirements, storage sizing, TLS, backups and how the SDKs point at your own ingest.

AnyReplay can run on infrastructure you control, so recordings never leave it. Self-hosted ingest is available on the Enterprise plan — talk to us about running AnyReplay on your own infrastructure. This page summarises what the deployment guide that ships with the source (deploy/README.md) asks for, so you can judge the effort before you start.

The shape of a deployment

The reference deployment runs everything on one host behind nginx. The split is by service, so moving ingest to its own machine later is a move, not a rewrite.

ComponentWhat it doesReference port
Dashboard (Next.js)The web app your team signs in to7100
API (NestJS)Accounts, projects, sessions, translation, retention sweeps7101
Ingest (Fastify)Receives recordings from the SDKs; also serves the recorder bundle7102
PostgreSQLEverything except the recordings themselves5432
Chunk storageThe recordings, on the filesystem—

Ingest is a separate service because its load is the opposite of the dashboard's: high-volume, unauthenticated writes from every visitor of every site you record. It holds no JWT secrets and no translation key.

Requirements

  • Operating system: the guide is written for Ubuntu 24.04.
  • Node.js 20.19 or newer (the guide installs a private Node 22 so other applications on the host are untouched) and pnpm 10.
  • PostgreSQL, with an ordinary, non-superuser role and its own database. The schema is created on first boot; there is no separate migration step.
  • nginx in front of the three services, with TLS. The reference setup sits behind Cloudflare with an Origin CA certificate.
  • Memory for builds: the Next.js build wants roughly 2 GB. Add swap if the host is tight.
  • Disk for recordings: a session is roughly 100–500 KB, so ten thousand live sessions is a few gigabytes. Retention sweeps keep it from growing without bound.

Hostnames

HostnameRouted to
Dashboard, e.g. replay.example.comDashboard
API, e.g. api.replay.example.comAPI
Ingest, e.g. in.replay.example.comIngest — this is your ingestUrl
Recorder, e.g. cdn.replay.example.comIngest, which serves /v1/ar.min.js

Pointing the SDKs at it

anyreplay('init', {
  projectKey: 'YOUR_PROJECT_KEY',
  ingestUrl: 'https://in.replay.example.com',
});

The dashboard's setup page generates snippets with your own ingest and recorder URLs, as long as they were set when the dashboard was built — see configuration. Remember to list those hosts in your Content Security Policy.

Operations the guide covers

  • Services: systemd units for the three services, installed and restarted by the deployment workflow.
  • Visitor IP and firewall: real client addresses from the proxy, so ingest's per-address rate limit means something, and an origin that only accepts traffic from the proxy.
  • Backups: a script that dumps PostgreSQL and the recordings, encrypts them on the host and uploads one file per run to an off-site bucket, with a weekly job that restores the latest backup into a throwaway database to prove it works.
  • Deployments: a CI workflow that runs the test suite, builds on the host, restarts the services and checks each health endpoint.
  • Health: GET /health on the API and on ingest.

Same code, same defaults

A self-hosted deployment runs the same code as the hosted service: the same masking, including the fields that are never recorded whatever you configure, the allowed-domain check that makes a public key safe, the sandboxed replay iframe, retention sweeps and the audit trail. What changes is who holds the keys and the disk. For the reasoning behind self-hosting, see self-hosted session replay.