---
title: "Docker branch example"
description: "Run the standard OpenTelemetry Collector in Docker as a branch that forwards to the root on your Mac."
source: "https://getloggerhead.com/docs/collectors/docker-branch-example/"
---

# Docker branch example

> Run the standard OpenTelemetry Collector in Docker as a branch that forwards to the root on your Mac.

A branch is a standard OpenTelemetry Collector that forwards to the root. This example runs the upstream collector image on the same Mac as Loggerhead. The branch receives OpenTelemetry from your apps, drops debug records, stamps its identity, and forwards the rest to the root.

## Before you start

- Loggerhead is open.
- Docker Desktop or OrbStack runs on this Mac.
- You know the effective port. Open **Collectors → Loggerhead receiver → Connection** and copy the gRPC port. See [Ports and the effective port](/docs/getting-started/ports-and-the-effective-port/).

## Step 1: write the branch config

Save this file as `branch-collector.yaml`.

```yaml title="branch-collector.yaml"
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317      # the BRANCH port inside the container
      http:
        endpoint: 0.0.0.0:4318

processors:
  resource:
    attributes:
      - key: loggerhead.collector.id
        value: ${env:LOGGERHEAD_COLLECTOR_ID}
        action: upsert
      # The environment inside the workspace. Records with this tag land in
      # the Staging database. Leave the key out for Local.
      - key: deployment.environment.name
        value: ${env:LOGGERHEAD_ENVIRONMENT}
        action: upsert
  filter:
    error_mode: ignore
    logs:
      log_record:
        - 'severity_number < SEVERITY_NUMBER_INFO'
  batch: {}

exporters:
  otlp:
    endpoint: ${env:LOGGERHEAD_OTLP_ENDPOINT}   # the ROOT, with the effective port
    tls:
      insecure: true

service:
  pipelines:
    logs:
      receivers: [otlp]
      processors: [resource, filter, batch]
      exporters: [otlp]
    metrics:
      receivers: [otlp]
      processors: [resource, batch]
      exporters: [otlp]
    traces:
      receivers: [otlp]
      processors: [resource, batch]
      exporters: [otlp]
```

## Step 2: start the branch

Replace `4317` with the effective port.

```bash
docker network create loggerhead-net   # once

docker run -d --name loggerhead-branch \
  --network loggerhead-net \
  -e LOGGERHEAD_COLLECTOR_ID=docker-branch-1 \
  -e LOGGERHEAD_ENVIRONMENT=staging \
  -e LOGGERHEAD_OTLP_ENDPOINT=host.docker.internal:4317 \
  -v "$PWD/branch-collector.yaml:/etc/otelcol/config.yaml:ro" \
  otel/opentelemetry-collector:latest \
  --config=file:/etc/otelcol/config.yaml
```

The branch publishes no port on the Mac. It listens on **4317** and **4318** inside the network only. Start your apps on `loggerhead-net` and point them at `loggerhead-branch:4317`.

If an application on the Mac itself must reach the branch, add `-p 15317:4317` to the command. Do not publish 4317 and 4318, because the root asks for them.

## The same branch in Compose

```yaml title="compose.yaml"
services:
  loggerhead-branch:
    image: otel/opentelemetry-collector:latest
    command: ["--config=file:/etc/otelcol/config.yaml"]
    # No published port. Containers on this network send to loggerhead-branch:4317.
    expose:
      - "4317"
      - "4318"
    environment:
      LOGGERHEAD_COLLECTOR_ID: docker-branch-1
      LOGGERHEAD_ENVIRONMENT: staging
      LOGGERHEAD_OTLP_ENDPOINT: host.docker.internal:4317   # confirm the effective port
    volumes:
      - ./branch-collector.yaml:/etc/otelcol/config.yaml:ro
```

## Collect every container's logs instead

Use the **contrib** image and mount the Docker socket read-only. The `filelog` and `docker_stats` receivers are in the contrib image only. The app does not open the Docker socket itself, so the branch is the way to read container logs.

## Check the branch

1. `docker logs loggerhead-branch` shows no export error.
2. Send one test record from the network: `docker run --rm --network loggerhead-net curlimages/curl -X POST -H 'Content-Type: application/json' -d @record.json http://loggerhead-branch:4318/v1/logs`.
3. The record appears on the **Logs** page. The branch appears on the **Collectors** page as `docker-branch-1`.

:::note[Validated]
This example ran against `otel/opentelemetry-collector` 0.158.0 on macOS with OrbStack, and against the root receiver on its effective port. The INFO record arrived, the DEBUG record was dropped on the branch, and the branch reported no export error. That run published the branch ports on the Mac. The branch config and the pipeline did not change since.
:::
