Deploy Grafana Faro Receiver
Ingest browser and mobile RUM into your OpenTelemetry pipeline.
Just deployed
Deploy and Host Grafana Faro Receiver on Railway
Grafana Faro is the web SDK for frontend observability, capturing JavaScript exceptions, Core Web Vitals, user sessions, and browser traces. This template runs the receiver side: a Grafana Alloy service that accepts Faro's payloads over HTTP, normalizes them to OpenTelemetry, and forwards them to a collector or gateway you already operate.
About Hosting Grafana Faro Receiver
Hosting the Faro receiver means running one stateless Alloy service with a public domain, since browsers post to it directly. Alloy is used rather than the OpenTelemetry Collector because the Faro Web SDK sends its own JSON payload, and faro.receiver is the only component that accepts it — no collector build can serve /collect.
On Railway the service needs no volume and no database. It exposes an API key check, a CORS allowlist, a payload cap, and per-app rate limiting on that public write path, then forwards everything upstream over OTLP with basic auth. Railway handles TLS, the domain, and lifecycle; you supply the upstream endpoint and credentials.
Common Use Cases
- Add browser RUM to an existing LGTM or OpenTelemetry stack without changing the backends
- Capture Core Web Vitals, JavaScript exceptions, and session data from SPAs and PWAs
- Collect telemetry from native mobile shells — Capacitor and Ionic webviews post the same payloads
Dependencies for Grafana Faro Receiver Hosting
- An OTLP endpoint to forward to — an OpenTelemetry Collector, a Grafana Alloy gateway, or any OTLP-compatible backend
- The Faro Web SDK installed in the frontend you want to instrument
Deployment Dependencies
- Grafana Alloy: https://grafana.com/docs/alloy/latest/
- Alloy
faro.receiver: https://grafana.com/docs/alloy/latest/reference/components/faro/faro.receiver/ - Grafana Faro Web SDK: https://github.com/grafana/faro-web-sdk
- OpenTelemetry Collector: https://opentelemetry.io/docs/collector/
Implementation Details
The service listens on three ports. Route the public domain to 12347, the Faro receiver — not to Alloy's own HTTP server:
PORT=12345 # Alloy's HTTP server; Railway probes this for health
12347 # faro.receiver — point the public domain here
Ingest is gated. FARO_API_KEY is sent by clients as x-api-key; the CORS list is what actually stops other sites writing into your logs, and origins must include the scheme:
FARO_API_KEY="${{ secret(32) }}"
FARO_CORS_ALLOWED_ORIGINS="https://app.example.com,http://localhost:3000"
Forwarding upstream, with its own credential line so it can be rotated independently:
OTEL_EXPORTER_OTLP_ENDPOINT="http://${{OpenTelemetry Collector.RAILWAY_PRIVATE_DOMAIN}}:4318"
OTEL_UPSTREAM_USERNAME="faro"
OTEL_UPSTREAM_PASSWORD="${{ secret(32) }}"
Point the Faro SDK at the service domain's /collect path with the API key as x-api-key. Logs arrive tagged service.namespace="faro", giving you one selector for retention rules and dashboards.
Why Deploy Grafana Faro Receiver on Railway?
Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.
By deploying Grafana Faro Receiver on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.
Template Content
OTEL_UPSTREAM_PASSWORD
Password for that line. Must match the gateway's htpasswd.
OTEL_UPSTREAM_USERNAME
Username for the gateway's htpasswd. Give Alloy its own line so it can be rotated alone.
OTEL_EXPORTER_OTLP_ENDPOINT
The gateway to forward to. In the combined template, http://opentelemetry-collector.railway.internal:4318; in the standalone template, ask the user.
