---
title: "Deploy Jaeger"
description: "Jaeger 2.21 OpenTelemetry tracing with Badger storage and auth gateway."
category: "Observability"
url: https://railway.com/deploy/jaeger-1
---

# Deploy Jaeger

Jaeger 2.21 OpenTelemetry tracing with Badger storage and auth gateway.

**[Deploy Jaeger on Railway](https://railway.com/template/jaeger-1)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/jaeger-1/manifest.json

- **Creator:** Agaz Self-Host
- **Category:** Observability

## Template content

### jaeger https://raw.githubusercontent.com/jaegertracing/jaeger-ui/v2.21.0/packages/jaeger-ui/src/img/jaeger-logo.svg

- **Image:** jaegertracing/jaeger:2.21.0
- **Start command:** `/cmd/jaeger/jaeger-linux --config env:JAEGER_CONFIG`
- **Health check:** /

### gateway https://raw.githubusercontent.com/caddyserver/website/5c921006aae4feb2184782ae528c2bb09a07e04f/src/resources/images/favicon.png

- **Image:** caddy:2.11.4-alpine
- **Start command:** `sh -c 'export JAEGER_UI_PASSWORD_HASH="$(caddy hash-password --plaintext "$JAEGER_UI_PASSWORD")" && printf "%s\n" "$CADDYFILE" > /tmp/Caddyfile && exec caddy run --config /tmp/Caddyfile --adapter caddyfile'`
- **Health check:** /healthz
- **Public domain:** Yes

## Documentation

# Deploy and Host Jaeger on Railway

Jaeger is an open-source, CNCF-graduated distributed tracing platform. It collects OpenTelemetry traces from your services and lets you search them, follow requests across services and find slow or failing calls. Jaeger v2 is built on the OpenTelemetry Collector, so any OpenTelemetry SDK can send traces to it directly.

## About Hosting Jaeger

This template deploys Jaeger v2.21.0 with persistent Badger storage on a volume, plus a Caddy gateway that is the only public entry point. The Jaeger UI is protected by a username and a generated password. OTLP/HTTP trace ingestion at `/v1/traces` requires a generated bearer token. Services on Railway can instead send traces over the private network with OTLP gRPC (4317) or HTTP (4318), with no token. Traces are kept for 7 days by default. Disk use grows with trace volume, so watch the volume size on the Hobby plan (5 GB). Jaeger is a single node and runs as root so it can write to the volume.

## Common Use Cases

- Tracing requests across microservices on Railway to find latency and errors
- Debugging slow API endpoints, database calls and queue consumers with OpenTelemetry auto-instrumentation
- A self-hosted, low-cost tracing backend for staging or small production systems

## Dependencies for Jaeger Hosting

- `jaegertracing/jaeger:2.21.0` (official image) with a volume for Badger storage
- `caddy:2.11.4-alpine` (official image) as the authenticated public gateway
- An OpenTelemetry SDK or Collector in your application

### Deployment Dependencies

- [Jaeger documentation](https://www.jaegertracing.io/docs/latest/)
- [Jaeger v2.21.0 release notes](https://github.com/jaegertracing/jaeger/releases/tag/v2.21.0)
- [OpenTelemetry OTLP exporter configuration](https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/)
- [Railway volumes](https://docs.railway.com/reference/volumes)

### Implementation Details

| Service | Image | Networking | Storage |
| --- | --- | --- | --- |
| jaeger | `jaegertracing/jaeger:2.21.0` | private only: OTLP 4317/4318, UI 16686 | volume at `/badger` |
| gateway | `caddy:2.11.4-alpine` | public domain on port 8080 | none |

Send traces from a service on Railway (private network, no token):

```env
OTEL_EXPORTER_OTLP_ENDPOINT=${{jaeger.JAEGER_OTLP_HTTP_ENDPOINT}}
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_SERVICE_NAME=my-service
```

Send traces from outside Railway (through the gateway, with the token):

```env
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https:///v1/traces
OTEL_EXPORTER_OTLP_TRACES_HEADERS=Authorization=Bearer 
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
```

| Variable | Service | Default | Purpose |
| --- | --- | --- | --- |
| `JAEGER_UI_USERNAME` | gateway | `admin` | UI login |
| `JAEGER_UI_PASSWORD` | gateway | generated secret | UI password (hashed with bcrypt at startup) |
| `OTLP_INGEST_TOKEN` | gateway | generated secret | Bearer token for public OTLP/HTTP ingestion |
| `JAEGER_SPAN_TTL` | jaeger | `168h` | How long traces are kept |
| `JAEGER_CONFIG` | jaeger | Badger config | Full Jaeger v2 YAML config, loaded with `--config env:JAEGER_CONFIG` |
| `CADDYFILE` | gateway | gateway config | Caddy config for auth and routing |

Notes:

- The gateway only routes OTLP/HTTP (`/v1/traces`). OTLP gRPC (4317) is available on the private network only.
- The Jaeger UI has no login of its own, which is why it is kept private behind the Caddy gateway.
- Jaeger runs with `RAILWAY_RUN_UID=0` because the image user cannot write to Railway's root-owned volume.
- Jaeger v2.21.0 removed the old v1 HTTP query endpoints. Use the UI, or the `/api/v3/...` endpoints through the gateway.
- For larger or multi-node setups, switch `JAEGER_CONFIG` to an Elasticsearch, OpenSearch, Cassandra or ClickHouse backend.

This is a community-maintained deployment package and does not imply affiliation with or endorsement by the Jaeger project or the CNCF.

## Why Deploy Jaeger 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 Jaeger 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.


## Similar templates

- [Rootprint](https://railway.com/deploy/rootprint-1) — Open-source logs and traces with full-text search on object-storage.
- [Pyroscope profiling](https://railway.com/deploy/pyroscope-profiling) — Protected continuous profiling with durable Pyroscope storage.
- [SigOnly](https://railway.com/deploy/sigonly) — Deploy SigNoz with a working demo app & config in one click

Open this page in a browser: https://railway.com/deploy/jaeger-1
