Skip to content
Learni
View all tutorials
Observabilité

How to Deploy Jaeger for Distributed Tracing in 2026

18 minINTERMEDIATE
Lire en français

Introduction

Jaeger is an open source distributed tracing system designed to monitor complex microservices architectures. It lets you visualize the complete journey of a request across multiple services and identify latency issues and bottlenecks. In 2026, its integration with OpenTelemetry makes it the go-to tool for observability. This tutorial walks you through deploying a production-ready instance, instrumenting your applications, and configuring advanced sampling. You will learn how to avoid common pitfalls and optimize trace storage costs.

Prerequisites

  • Docker and Docker Compose installed
  • Basic knowledge of Kubernetes (optional)
  • Instrumentable Node.js or Python application
  • Access to a cluster or local environment
  • Basic understanding of OpenTelemetry

Deployment with Docker Compose

docker-compose.yml
version: '3.8'
services:
  jaeger-all-in-one:
    image: jaegertracing/all-in-one:1.53
    ports:
      - "16686:16686"
      - "14268:14268"
      - "4317:4317"
      - "4318:4318"
    environment:
      - COLLECTOR_OTLP_ENABLED=true
    restart: unless-stopped

This file deploys the Jaeger all-in-one image with OTLP ports enabled to receive OpenTelemetry traces. It exposes the UI on port 16686 and the collector on ports 4317/4318.

Collector Configuration

jaeger-collector-config.yaml
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318
processors:
  batch:
    timeout: 1s
    send_batch_size: 1024
exporters:
  jaeger:
    endpoint: jaeger-collector:14250
    tls:
      insecure: true
service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [jaeger]

This configuration enables the OTLP receiver, applies batching to optimize exports, and sends data to Jaeger storage. Batching reduces network load and storage costs.

OpenTelemetry Node.js Instrumentation

tracing.ts
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';

const exporter = new OTLPTraceExporter({
  url: 'http://localhost:4317',
});
const sdk = new NodeSDK({
  traceExporter: exporter,
  instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();

This code initializes the OpenTelemetry SDK with the gRPC exporter to Jaeger. It enables automatic instrumentation of common Node.js modules without manual changes to business logic.

Python Instrumentation

tracing.py
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
provider = TracerProvider()
processor = BatchSpanProcessor(OTLPSpanExporter(endpoint="http://localhost:4317"))
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)

This Python script configures the trace provider and uses the batch processor to send spans to the Jaeger collector via gRPC. Batching is essential in production.

Kubernetes Deployment

jaeger-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: jaeger
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jaeger
  template:
    metadata:
      labels:
        app: jaeger
    spec:
      containers:
      - name: jaeger
        image: jaegertracing/all-in-one:1.53
        env:
        - name: COLLECTOR_OTLP_ENABLED
          value: "true"
        ports:
        - containerPort: 16686

This Kubernetes manifest deploys Jaeger in all-in-one mode. For production, separate the collector, agent, and query service with persistent volumes for trace storage.

Best Practices

  • Always enable batch processing to reduce network load
  • Configure appropriate sampling rates (probabilistic or rate limiting)
  • Use consistent tags and attributes to simplify searches
  • Monitor collector metrics (queue size, export errors)
  • Separate dev and prod environments with distinct instances

Common Mistakes to Avoid

  • Forgetting to enable COLLECTOR_OTLP_ENABLED in production
  • Not configuring trace retention limits (unlimited storage)
  • Instrumenting without propagating trace context between services
  • Ignoring collector connection errors (silent trace loss)

Going Further

Deepen your skills with our dedicated observability and distributed tracing courses at Learni Group.