This guide explains how to use otel-distro-builder with Docker to build custom OpenTelemetry Collector distributions.
- Docker
- Pull the latest otel-distro-builder image:
docker pull ghcr.io/observiq/otel-distro-builder:main- Create a manifest file (
manifest.yaml) that defines your collector configuration:
dist:
module: github.com/open-telemetry/opentelemetry-collector-releases/core
name: my-otelcol
description: My Custom OpenTelemetry Collector Build
output_path: ./artifacts
extensions:
- # Add your extensions
exporters:
- # Add your exporters
processors:
- # Add your processors
receivers:
- # Add your receivers
connectors:
- # Add your connectors
providers:
- # Add your providers- Run the builder:
docker run --rm \
-v "$(pwd)/manifest.yaml:/manifest.yaml:ro" \
-v "$(pwd)/artifacts:/artifacts" \
ghcr.io/observiq/otel-distro-builder:main \
--manifest /manifest.yaml \
--artifacts /artifactsThe Docker container accepts the following command-line options:
| Option | Description | Default |
|---|---|---|
--manifest |
Path to manifest file | Required |
--artifacts |
Output directory for artifacts | <cwd>/artifacts |
--platforms |
Comma-separated GOOS/GOARCH (e.g. linux/amd64,linux/arm64) | (from manifest) |
--goos |
Target operating system | linux |
--goarch |
Target architecture | amd64 |
--ocb-version |
OpenTelemetry Collector Builder version | 0.122.0 |
--go-version |
Go version to use | 1.24.0 |
--supervisor-version |
Supervisor version | 0.122.0 |
--parallelism |
Number of parallel Goreleaser build tasks (lower to reduce memory) | 4 |
When running the container, mount the manifest file and an artifacts directory:
-
Manifest (read-only): Mount your manifest file into the container.
-v "$(pwd)/manifest.yaml:/manifest.yaml:ro" -
Artifacts: Mount a host directory at
/artifactsso build outputs are written back to the host.-v "$(pwd)/artifacts:/artifacts"
Important: Always pass
--artifacts /artifactsto ensure the builder writes to the mounted volume. Without it, artifacts are written to the container's working directory (/app/artifacts) and will be lost when the container exits.
The builder will generate the following artifacts in your specified output directory:
- Binary distributions (tar.gz)
- Package files (DEB, RPM, APK)
- Docker images
- Configuration files
- Service files
docker run --rm \
-v "$(pwd)/manifest.yaml:/manifest.yaml:ro" \
-v "$(pwd)/artifacts:/artifacts" \
ghcr.io/observiq/otel-distro-builder:main \
--manifest /manifest.yaml \
--artifacts /artifactsUse --platforms with a comma-separated list of GOOS/GOARCH (e.g. linux/amd64, darwin/arm64). This is the recommended way to specify target platforms.
# Single platform: Apple Silicon (darwin/arm64)
docker run --rm \
-v "$(pwd)/manifest.yaml:/manifest.yaml:ro" \
-v "$(pwd)/artifacts:/artifacts" \
ghcr.io/observiq/otel-distro-builder:main \
--manifest /manifest.yaml \
--artifacts /artifacts \
--platforms darwin/arm64
# Linux only: amd64 and arm64
docker run --rm \
-v "$(pwd)/manifest.yaml:/manifest.yaml:ro" \
-v "$(pwd)/artifacts:/artifacts" \
ghcr.io/observiq/otel-distro-builder:main \
--manifest /manifest.yaml \
--artifacts /artifacts \
--platforms linux/amd64,linux/arm64
# Linux + Darwin (common server and Mac targets)
docker run --rm \
-v "$(pwd)/manifest.yaml:/manifest.yaml:ro" \
-v "$(pwd)/artifacts:/artifacts" \
ghcr.io/observiq/otel-distro-builder:main \
--manifest /manifest.yaml \
--artifacts /artifacts \
--platforms linux/amd64,linux/arm64,darwin/amd64,darwin/arm64
# Include Windows (amd64)
docker run --rm \
-v "$(pwd)/manifest.yaml:/manifest.yaml:ro" \
-v "$(pwd)/artifacts:/artifacts" \
ghcr.io/observiq/otel-distro-builder:main \
--manifest /manifest.yaml \
--artifacts /artifacts \
--platforms linux/amd64,linux/arm64,darwin/arm64,windows/amd64Alternatively, use --goos and --goarch to specify target OS and architecture lists (builder builds the Cartesian product):
# ARM64 only (darwin, linux, windows)
docker run --rm \
-v "$(pwd)/manifest.yaml:/manifest.yaml:ro" \
-v "$(pwd)/artifacts:/artifacts" \
ghcr.io/observiq/otel-distro-builder:main \
--manifest /manifest.yaml \
--artifacts /artifacts \
--goos darwin,linux,windows \
--goarch arm64
# AMD64 only
docker run --rm \
-v "$(pwd)/manifest.yaml:/manifest.yaml:ro" \
-v "$(pwd)/artifacts:/artifacts" \
ghcr.io/observiq/otel-distro-builder:main \
--manifest /manifest.yaml \
--artifacts /artifacts \
--goos darwin,linux,windows \
--goarch amd64docker run --rm \
-v "$(pwd)/manifest.yaml:/manifest.yaml:ro" \
-v "$(pwd)/artifacts:/artifacts" \
ghcr.io/observiq/otel-distro-builder:main \
--manifest /manifest.yaml \
--artifacts /artifacts \
--ocb-version 0.121.0 \
--go-version 1.24.0 \
--supervisor-version 0.122.0Use --parallelism to control how many Goreleaser build targets run at once. Lower values reduce peak memory use; higher values can speed up builds when you have enough RAM.
# Reduce memory use (e.g. for constrained environments or to avoid OOM)
docker run --rm \
-v "$(pwd)/manifest.yaml:/manifest.yaml:ro" \
-v "$(pwd)/artifacts:/artifacts" \
ghcr.io/observiq/otel-distro-builder:main \
--manifest /manifest.yaml \
--artifacts /artifacts \
--parallelism 1
# Use more parallelism when you have sufficient memory (default is 4)
docker run --rm \
-v "$(pwd)/manifest.yaml:/manifest.yaml:ro" \
-v "$(pwd)/artifacts:/artifacts" \
ghcr.io/observiq/otel-distro-builder:main \
--manifest /manifest.yaml \
--artifacts /artifacts \
--parallelism 8-
Permission Issues
- Ensure the output directory has the correct permissions
- The container runs as a non-root user (UID 10001)
-
Volume Mount Issues
- Verify the paths are correct and accessible
- Check if SELinux or AppArmor are blocking access
-
Build Failures
- Check the manifest file syntax
- Verify all required components are specified
- Check the logs for specific error messages
-
Goreleaser build killed (signal: killed / OOM)
If the release step fails with errors like
/usr/local/go-versions/go1.x/pkg/tool/linux_arm64/compile: signal: killedwhen building large dependencies (e.g. elasticsearch, datadog, aws-sdk), the Go compiler process was likely killed by the system OOM killer due to memory limits.The builder accepts
--parallelism N(default 4). Use a lower value (e.g.--parallelism 1) to reduce peak memory and avoid OOM. If you still hit OOM:- Docker: Increase memory for the Docker engine (e.g. Docker Desktop → Settings → Resources → Memory). Try at least 4–6 GB for collector builds with many components.
- Local / CI: Ensure the environment has enough RAM; cross-compiling multiple targets with large dependencies can use several GB.
-
Version Pinning
- Always specify exact versions for OCB, Go, and Supervisor
- This ensures reproducible builds
-
Artifact Management
- Use a dedicated artifacts directory
- Clean up old artifacts before new builds
-
Security
- Review your manifest file for security implications
- Use specific versions instead of latest tags
- Consider using Docker's security scanning features