Agentgateway ships a minimal, production-ready container image built on the Chainguard glibc-dynamic base image. A Dockerfile.windows is also provided for Windows containers.
Pre-built images
Pre-built images are published to the GitHub Container Registry:
docker pull ghcr.io/agentgateway/agentgateway:latest
Building the image
Linux / macOS
Linux (musl / static)
Windows
The default Dockerfile uses a multi-stage build. It builds the UI with Node, compiles the Rust binary (optionally with musl for a fully static binary), and copies only the final binary into the minimal runtime image.This is equivalent to:docker build \
--build-arg VERSION=$(git describe --tags --always --dirty) \
--build-arg GIT_REVISION=$(git rev-parse HEAD) \
-t ghcr.io/agentgateway/agentgateway:$(git describe --tags --always --dirty) \
. --progress=plain
To build a fully statically-linked binary using musl, pass BUILDER=musl:This sets --build-arg BUILDER=musl and targets aarch64-unknown-linux-musl or x86_64-unknown-linux-musl depending on the host architecture. The Dockerfile.windows uses Windows Server Core as the builder and Nano Server as the runtime image:On Windows, make docker automatically selects Dockerfile.windows. The entrypoint is C:\app\agentgateway.exe.
Dockerfile walkthrough
The Linux Dockerfile has four stages:
# syntax=docker/dockerfile:1.11
ARG BUILDER=base
# Stage 1: build the UI
FROM docker.io/library/node:23.11.0-bookworm AS node
WORKDIR /app
COPY ui .
RUN --mount=type=cache,target=/app/npm/cache npm install
RUN --mount=type=cache,target=/app/npm/cache npm run build
# Stage 2 (musl variant): install musl toolchain
FROM docker.io/library/rust:1.93.0-trixie AS musl-builder
# ... installs musl-tools and adds the musl Rust target
# Stage 2 (base variant): standard glibc build
FROM docker.io/library/rust:1.93.0-trixie AS base-builder
# Stage 3: compile the binary
FROM ${BUILDER}-builder AS builder
ARG PROFILE=release
WORKDIR /app
COPY Makefile Cargo.toml Cargo.lock ./
COPY --from=node /app/out ./ui/out
RUN cargo build --features ui --target "$(cat /build/target)" --profile ${PROFILE}
# Stage 4: minimal runtime image
FROM cgr.dev/chainguard/glibc-dynamic AS runner
COPY --from=builder /out/agentgateway /app/agentgateway
ENTRYPOINT ["/app/agentgateway"]
Key points:
- Build caches for
npm and Cargo registries are mounted as --mount=type=cache to keep iterative builds fast.
- The runtime image is
cgr.dev/chainguard/glibc-dynamic — a distroless image with no shell, minimal attack surface, and regular security updates.
VERSION and GIT_REVISION build args are embedded in the binary. The build fails if version information is missing (the --version output must not contain "unknown").
Running with Docker
Mount a configuration file
Pass your configuration file into the container as a bind mount and point the binary to it with -f:
docker run \
--rm \
-p 8080:8080 \
-p 15000:15000 \
-v $(pwd)/config.yaml:/config.yaml:ro \
ghcr.io/agentgateway/agentgateway:latest \
-f /config.yaml
Port mappings
| Port | Purpose |
|---|
8080 | MCP / A2A listener (configurable in your config file) |
15000 | Admin UI (http://localhost:15000/ui) |
15020 | Prometheus metrics (/metrics) |
15021 | Readiness probe (/healthz/ready) |
The listener port (default 8080) is defined in your configuration file, not hard-coded. Adjust the -p flag to match whatever port you configure.
Volume mounts
| Path in container | Purpose |
|---|
/config.yaml | Configuration file (mount as read-only) |
/certs/ | TLS certificates referenced from your config |
/manifests/jwt/pub-key | JWT public key (if using local JWKS as in the example config) |
Environment variable configuration
You can override individual settings without modifying the config file by passing environment variables:
docker run \
--rm \
-p 8080:8080 \
-p 15000:15000 \
-e DNS_EDNS0=true \
-v $(pwd)/config.yaml:/config.yaml:ro \
ghcr.io/agentgateway/agentgateway:latest \
-f /config.yaml
Docker Compose examples
Agentgateway with telemetry
The repository includes a docker-compose.yaml in examples/telemetry/ that adds Jaeger and an OpenTelemetry collector alongside Agentgateway:
examples/telemetry/docker-compose.yaml
services:
jaeger:
container_name: jaeger
restart: unless-stopped
image: jaegertracing/all-in-one:latest
ports:
- "127.0.0.1:16686:16686"
- "127.0.0.1:14268:14268"
environment:
- COLLECTOR_OTLP_ENABLED=true
otel-collector:
container_name: otel-collector
image: otel/opentelemetry-collector-contrib:0.146.0
volumes:
- ./otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml
ports:
- "127.0.0.1:4317:4317"
depends_on:
- jaeger
To run Agentgateway alongside these services, add a service entry pointing to the OTLP endpoint in your config:
config:
tracing:
otlpEndpoint: "http://otel-collector:4317"
otlpProtocol: grpc
randomSampling: "0.1"
Agentgateway with an OpenAPI backend
The examples/openapi/docker-compose.yaml shows a petstore backend service running alongside the gateway:
examples/openapi/docker-compose.yaml
services:
openapi-petstore:
image: swaggerapi/petstore3:1.0.27
ports:
- "8080:8080"
Health checks
Add a Docker health check so that container orchestrators can detect when Agentgateway is ready:
services:
agentgateway:
image: ghcr.io/agentgateway/agentgateway:latest
command: ["-f", "/config.yaml"]
ports:
- "8080:8080"
- "15000:15000"
- "15020:15020"
- "15021:15021"
volumes:
- ./config.yaml:/config.yaml:ro
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:15021/healthz/ready"]
interval: 10s
timeout: 5s
retries: 3
start_period: 5s
The Chainguard runtime image has no shell. Use wget or curl (if present) for health check commands, or prefer a TCP-based check. Do not use sh -c or bash-based health checks.
Windows containers
A Dockerfile.windows is provided for environments that require native Windows containers. It uses Windows Server Core (ltsc2022) as the build image and Nano Server as the runtime:
FROM mcr.microsoft.com/windows/servercore:ltsc2022 AS builder
# Installs Chocolatey, then: rust-ms protoc make nodejs cmake nasm
# Installs VS 2022 Build Tools with MSVC and Windows 11 SDK
FROM mcr.microsoft.com/windows/nanoserver:ltsc2022 AS runner
COPY --from=builder C:/out/agentgateway.exe C:/app/agentgateway.exe
ENTRYPOINT ["C:\\app\\agentgateway.exe"]
Build and run:
make docker # selects Dockerfile.windows automatically on Windows
docker run --rm -p 8080:8080 -v ${PWD}/config.yaml:C:/config.yaml `
ghcr.io/agentgateway/agentgateway:latest -f C:/config.yaml