Apollo Router
OverviewGet StartedRequest Lifecycle
Configuration
Features

Security

Observability

Performance and Scaling

Client Features

Query Planning

Customization

Deployment
Releases
GraphOS Integration
Reference

Deploying only GraphOS Router in Docker

Deploy router-only container image


This guide provides the following examples of running an Apollo Router container image in Docker:

  • Running a basic example with default configuration.

  • Choosing between the published image flavors.

  • Customizing your configuration to override the default configuration.

  • Debugging your containerized router.

  • Manually specifying a supergraph for your router.

  • Building your own router Docker image.

The documentation for the docker run command is a helpful reference for the examples in this guide.

The exact image version to use depends on which release you wish to use. In the following examples, replace <image version> with your chosen version, for example v1.32.0.

note
The Apollo Router Core source code and all its distributions are made available under the Elastic License v2.0 (ELv2) license.

note
This container image only contains the router. Apollo recommends using the Apollo Runtime container, which contains all Apollo runtime services.

note
If your organization uses a corporate proxy with TLS inspection, add your proxy's root certificate to the container.

Basic example running router in Docker

To run the router, set the APOLLO_GRAPH_REF and APOLLO_KEY environment variables in your Docker container to your graph ref and API key.

Below is a basic example of running a router image with Docker, either with docker run or docker compose. It downloads your supergraph schema from Apollo and uses a default configuration that listens for connections on port 4000.

You can use docker run with the following example command:

Bash
Docker
1docker run -p 4000:4000 \
2  --env APOLLO_GRAPH_REF="<your-graph-ref>" \
3  --env APOLLO_KEY="<your-graph-api-key>" \
4  --rm \
5  ghcr.io/apollographql/router:<router-image-version>

You can also use docker compose with the following example compose.yaml:

YAML
compose.yaml
1services:
2  apollo-router:
3    image: ghcr.io/apollographql/router:<router-image-version>
4    ports:
5      - "4000:4000"
6    environment:
7      APOLLO_GRAPH_REF: "<your-graph-ref>"
8      APOLLO_KEY: "<your-graph-api-key>"

Whether you use docker run or docker compose, make sure to replace <router-image-version> with whichever version you want to use, and <your-graph-ref> and <your-graph-api-key> with your graph reference and API key, respectively.

For more complex configurations, such as overriding subgraph URLs or propagating headers, see Router Configuration.

Image flavors

Every router release publishes the same router binary in three image flavors, which differ only in their base image:

TagBase imageWhen to use it
<image version>debian:trixie-slimThe default. Includes a shell and a package manager.
<image version>-distrolessdistroless/ccFor deployments that want a smaller attack surface. About half the size of the Debian image, with no shell, package manager, or other userland.
<image version>-debugdebian:trixie-slimFor investigating memory usage. Runs the router under heaptrack, as described in Running the debug container.

Configuration, environment variables, command-line arguments, and the paths you mount over (/dist/config/router.yaml and /dist/schema) are the same in all three, and all three run as the router user (uid and gid 1000), so switching between the images requires only changing the tag.

What the distroless image doesn't have

A distroless image contains the router, the shared libraries it links against, CA certificates, and time zone data, and nothing else. As a result:

  • There is no shell, so the debugging techniques that rely on one (--entrypoint=bash, docker exec <container> sh) have nothing to run. Reproduce the problem with the Debian image when you need to look around inside a container.

  • Container probes that shell out, such as a Kubernetes exec probe running curl, won't work. Use the router's HTTP health check endpoint with an httpGet probe instead.

  • There is no distroless equivalent of the -debug flavor, because heaptrack and its tooling need a userland to run in.

Override the configuration

Apollo's default Docker images include a basic router configuration. Inside the container, this file is located at /dist/config/router.yaml.

If you wish to override the default configuration, it is important to preserve aspects of the default configuration. In particular, it is generally important for the router to bind to and listen on the special address of 0.0.0.0 (for all interfaces) to ensure it's exposed on a network interface that's accessible outside of the local container. Without this configuration, the router will only listen on localhost.

You can provide your own configuration from the host environment to the router by mounting your configuration to /dist/config/router.yaml as follows:

Bash
1docker run -p 4000:4000 \
2  --env APOLLO_GRAPH_REF="<your-graph-ref>" \
3  --env APOLLO_KEY="<your-graph-api-key>" \
4  --mount "type=bind,source=/home/user/router.yaml,target=/dist/config/router.yaml" \
5  --rm \
6  ghcr.io/apollographql/router:<router-image-version>
note
Both local and container paths must be specified as absolute paths.

In this example we are mounting a file from the host system (/home/user/router.yaml) in place of the default configuration provided in the image at /dist/config/router.yaml.

Passing command-line arguments to the router binary

By default, the router command invoked inside the published container doesn't set any of the available command-line options. To set them, append the desired option(s) to the docker run command.

For example, to start the router using the --log debug option, use the following docker run command with the option added at the end:

Bash
1docker run -p 4000:4000 \
2  --env APOLLO_GRAPH_REF="<your-graph-ref>" \
3  --env APOLLO_KEY="<your-graph-api-key>" \
4  --rm \
5  ghcr.io/apollographql/router:<router-image-version> --log debug

Debugging your container

You can debug your container by setting the entrypoint in a docker run command:

Bash
1docker run -p 4000:4000 \
2  --env APOLLO_GRAPH_REF="<your graph>" \
3  --env APOLLO_KEY="<your key>" \
4  --mount "type=bind,source=/router.yaml,target=/dist/config/router.yaml" \
5  --rm \
6  --interactive \
7  --tty \
8  --entrypoint=bash \
9  ghcr.io/apollographql/router:<image version>
10dist# pwd
11/dist
12dist# ls
13config	router	schema
14dist# exit
15exit

In this example, we've added both interactive and tty flags, and we've changed the entrypoint of the image to be a bash shell.

Running the debug container to investigate memory issues

Bash
1docker run -p 4000:4000 \
2  --env APOLLO_GRAPH_REF="<your graph>" \
3  --env APOLLO_KEY="<your key>" \
4  --mount "type=bind,source=/data,target=/dist/data"
5  --rm \
6  ghcr.io/apollographql/router:<image version>-debug

The router runs under the control of heaptrack. The heaptrack output is saved to the /data directory. The output can be analyzed directly using heaptrack_gui or heaptrack_print or shared with Apollo support.

Specifying the supergraph

If you don't want to automatically update your supergraph via Apollo Uplink, or you don't have connectivity to access Apollo Uplink from your environment, you have two options:

Using a local supergraph file

You can manually specify the details of your supergraph in a docker run command:

Bash
1docker run -p 4000:4000 \
2  --mount "type=bind,source=/docker.graphql,target=/dist/schema/local.graphql" \
3  --rm \
4  ghcr.io/apollographql/router:<image version> -c config/router.yaml -s schema/local.graphql

In this example, we have to mount the local definition of the supergraph into our image, and specify the location of the file. It doesn't have to be mounted in the /dist/schema directory, but it's a reasonable location to use. We must specify the configuration file location as well, since overriding the default params will override our default config file location. In this case, since we don't want to change our router configuration but want to make sure it's used, we just specify the default location of the default configuration.

Using a graph artifact reference

Set the APOLLO_GRAPH_ARTIFACT_REFERENCE environment variable to use the supergraph schema from a graph artifact:

Bash
1docker run -p 4000:4000 \
2  --env APOLLO_KEY="<your-graph-api-key>" \
3  --env APOLLO_GRAPH_ARTIFACT_REFERENCE="<your-graph-artifact-reference>" \
4  --rm \
5  ghcr.io/apollographql/router:<router-image-version>

When you set this option, the router uses the schema from the specified graph artifact instead of Apollo Uplink. The router also fetches its entitlement from the same registry when the graph artifact manifest carries an entitlement identifier; persisted queries still come from Uplink.

For more information on graph artifacts, see the Router CLI Configuration Reference.

Building your own container

note
This section is aimed at developers familiar with tooling such as docker and git who wish to make their own DIY container images. The script documented here is not a part of the router product, but an illustrative example of what's involved in making your own images.

In the dockerfiles/diy directory, we now provide a script, build_docker_image.sh which illustrates how to build your own docker images from either our released tarballs or from a git commit hash or tag. Here's how to use it:

Bash
1% ./build_docker_image.sh -h
2Usage: build_docker_image.sh [-b [-r <repo>]] [-d] [<release>]
3	-b build docker image from the default repo, if not present build from a released version
4	-d build debug image, router will run under control of heaptrack
5	-r build docker image from a specified repo, only valid with -b flag
6	<release> a valid release. If [-b] is specified, this is optional
7	Example 1: Building HEAD from the repo
8		build_docker_image.sh -b
9	Example 2: Building HEAD from a different repo
10		build_docker_image.sh -b -r /Users/anon/dev/router
11	Example 3: Building tag from the repo
12		build_docker_image.sh -b v0.9.1
13	Example 4: Building commit hash from the repo
14		build_docker_image.sh -b 7f7d223f42af34fad35b898d976bc07d0f5440c5
15	Example 5: Building tag v0.9.1 from the released version
16		build_docker_image.sh v0.9.1
17	Example 6: Building a debug image with tag v0.9.1 from the released version
18		build_docker_image.sh -d v0.9.1

The example uses the debian:trixie-slim image for the final image build. Modify the script to use images that better suit your needs. When you use the -d flag, ensure a heaptrack package is available to install.

note
Because this script compiles the router from source using the stock rust Docker Hub image, binaries it produces link against that image's glibc and are not guaranteed to run on older glibc-based hosts such as RHEL 8. The officially released binaries and images are built on an older-glibc environment specifically to support those targets. If you need a self-built image for an old-glibc host, use an older build base (or a static musl target) rather than this script as-is.