Running the Elastic Distribution of OpenTelemetry (EDOT) Collector in Docker gives observability engineers a disposable collector for checking receiver, processor, and exporter behavior before changing a shared host, gateway, or Kubernetes rollout. The Docker run uses Elastic's elastic-agent image in OpenTelemetry mode and a mounted Collector configuration file, so the test stays close to the supported EDOT packaging without installing a host service.
Elastic's Docker quickstart runs EDOT through the elastic/elastic-agent container image with ELASTIC_AGENT_OTEL=true and a mounted Collector config. For a local smoke test, the Collector listens on OTLP/HTTP port 4318 and sends received traces to the debug exporter instead of using Elastic credentials or a production endpoint.
Use the debug exporter only for a short validation run because detailed output can include service names, attributes, request paths, and other telemetry content. Replace the exporter with the Elastic output path after the local receiver and mounted config behavior are proven, and publish only the listener ports that real clients need.
Steps to run the EDOT Collector in Docker:
- Create a local EDOT Collector config that accepts OTLP/HTTP traces.
- otelcol.yml
receivers: otlp: protocols: http: endpoint: 0.0.0.0:4318 processors: batch: exporters: debug: verbosity: detailed service: pipelines: traces: receivers: [otlp] processors: [batch] exporters: [debug]
The debug exporter prints received telemetry to container logs. Use verbosity: basic when detailed span attributes should not be printed.
Tool: OpenTelemetry Collector Config Generator - Start the EDOT Collector container with the config mounted read-only.
$ docker run --detach --name edot-collector \ --publish 127.0.0.1:4318:4318 \ --env ELASTIC_AGENT_OTEL=true \ --volume "$PWD/otelcol.yml:/etc/otelcol-config.yml:ro" \ elastic/elastic-agent:9.4.2 \ --config /etc/otelcol-config.yml 7b49d38512289eacf6a0d1ef6de4738c1fd93ac2497aee1b8b9f5b0b7de49f64
The 127.0.0.1 host bind keeps the OTLP listener local to the Docker host. Use a broader host bind only when network clients must reach this collector and firewall rules already limit access.
- Check the startup log for the EDOT service and OTLP/HTTP listener.
$ docker logs edot-collector Starting elastic-otel-collector... {"Version": "9.4.2"} Starting HTTP server {"otelcol.component.id": "otlp", "endpoint": "[::]:4318"} Everything is ready. Begin running and processing data.The Collector log shows the listener inside the container as [::]:4318. Docker still restricts host-side access to 127.0.0.1 because of the published port mapping.
- Create a small OTLP/HTTP trace payload.
- otlp-trace.json
{ "resourceSpans": [ { "resource": { "attributes": [ { "key": "service.name", "value": { "stringValue": "edot-docker-demo" } } ] }, "scopeSpans": [ { "scope": { "name": "manual-smoke-test" }, "spans": [ { "traceId": "0af7651916cd43dd8448eb211c80319c", "spanId": "b7ad6b7169203331", "name": "docker-smoke-test", "kind": 1, "startTimeUnixNano": "1718179200000000000", "endTimeUnixNano": "1718179201000000000", "attributes": [ { "key": "http.method", "value": { "stringValue": "GET" } } ] } ] } ] } ] }
The payload uses neutral service and span names so the debug exporter output can be copied into a ticket or runbook without exposing application identifiers.
- Send the trace to the local OTLP/HTTP receiver.
$ curl --silent --show-error \ --output otlp-response.json \ --write-out "%{http_code}\n" \ --header "Content-Type: application/json" \ --data @otlp-trace.json \ http://localhost:4318/v1/traces 200A 200 response confirms that the receiver accepted the OTLP/HTTP request. It does not prove export to Elastic because this local config uses the debug exporter.
- Inspect the collector logs for the exported trace.
$ docker logs edot-collector ##### snipped ##### Traces {"otelcol.component.id": "debug", "otelcol.signal": "traces", "resource spans": 1, "spans": 1} Resource attributes: -> service.name: Str(edot-docker-demo) InstrumentationScope manual-smoke-test Span #0 Trace ID : 0af7651916cd43dd8448eb211c80319c ID : b7ad6b7169203331 Name : docker-smoke-test Kind : Internal Attributes: -> http.method: Str(GET)The trace fields in the debug exporter output prove that Docker port publishing, the mounted config file, the OTLP receiver, and the traces pipeline are all active.
- Remove the temporary collector after the Docker smoke test.
$ docker rm --force edot-collector edot-collector
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.