doc/user/duo_agent_platform/flows/execution/images.md
{{< details >}}
{{< /details >}}
Flows that run with CI/CD execute inside a Docker image. By default, GitLab provides an image that includes the tools and network protection flows need. You can replace the default image with a custom or hardened image to add project dependencies, meet compliance requirements, or run flows in an offline environment.
All flows executed with CI/CD use a Docker image provided by GitLab.
This Docker image uses Anthropic Sandbox Runtime (srt)
to automatically include network protection.
You can change the Docker image if you have a complex project with specific dependencies or tools.
To change the default Docker image, in the agent-config.yml file, add the following configuration:
image: YOUR_DOCKER_IMAGE
For example:
{{< tabs >}}
{{< tab title="Python project" >}}
image: python:3.11-slim
{{< /tab >}}
{{< tab title="Node.js project" >}}
image: node:20-alpine
{{< /tab >}}
{{< /tabs >}}
To use network protection in your image, add srt to your
Docker image with your preferred version:
# Install srt sandboxing with cache clearing and verification
ARG SANDBOX_RUNTIME_VERSION=0.0.20
RUN npm cache clean --force && \
npm install -g @anthropic-ai/sandbox-runtime@${SANDBOX_RUNTIME_VERSION} && \
test -s "$(npm root -g)/@anthropic-ai/sandbox-runtime/package.json" && \
srt --version
For more information about SRT and how to install it on a custom image, see remote execution environment sandbox.
If you use a custom Docker image, ensure that the following commands are available for the agent to function correctly:
gitnpm with a Node.js version compatible with @gitlab/duo-cli. For more information, see GitLab Duo CLI prerequisites.Most base images include these commands by default. However, minimal images (like alpine variants)
might require you to install them explicitly. If needed, you can install missing commands in the
setup script configuration.
[!note] In GitLab 18.9 and earlier, there is a known issue (587996) where flows might fail with newer versions of
gitin custom images. This issue is resolved in@gitlab/duo-cliversion 8.71.0.If you are on
@gitlab/duo-cliversion 8.71.0 or earlier, to avoid flows failing with newer Git versions, you can do either of the following:
- Use Git version
2.43.7or earlier in your custom image- Use
@gitlab/duo-cliversion 8.71.0.
Additionally, depending on the tool calls made by agents during flow execution, other common utilities might be required.
For example, if you use an Alpine-based image:
image: python:3.11-alpine
setup_script:
- apk add --update git nodejs npm
When you use a custom Docker image, the environment sandbox is only applied when Anthropic Sandbox Runtime (SRT) is included in your custom image. If SRT is not included, your flow can access any domain reachable from the runner and the full file system.
If you require network isolation with custom images, install SRT on your image and configure a network policy, or configure network-level controls on your runner (for example, firewall rules or network policies).
To reduce job startup time by approximately 15-20 seconds, include the
@gitlab/duo-cli npm package and the glab CLI in your custom image.
The hardened image pre-installs both tools.
In offline environments where runners cannot reach external
registries, you can prebuild a custom executor image that includes
@gitlab/duo-cli. When the GitLab Duo CLI is already in the image, the
flow startup skips the npm download step.
Prerequisites:
To configure flows for an offline environment:
On an online machine, build a custom image with the GitLab Duo CLI:
FROM registry.gitlab.com/gitlab-org/duo-workflow/default-docker-image/workflow-generic-image:v0.0.6
RUN npm install -g @gitlab/[email protected]
Alternatively, to avoid npm entirely, download the standalone binary from the GitLab package registry:
FROM registry.gitlab.com/gitlab-org/duo-workflow/default-docker-image/workflow-generic-image:v0.0.6
COPY duo-linux-x64 /usr/bin/duo
RUN chmod +x /usr/bin/duo
To download the standalone binary, run the following command:
curl --location "https://gitlab.com/api/v4/projects/46519181/packages/generic/duo-cli/8.86.0/duo-linux-x64" \
--output duo-linux-x64
Transfer the image to your offline environment. For example, with Docker, run the following commands:
# On an online machine
docker save my-duo-executor:latest -o duo-executor.tar
# Transfer `duo-executor.tar` to the offline environment
# On an offline machine
docker load -i duo-executor.tar
Push the image to your internal container registry.
Set the custom image registry:
registry.internal.example.com).In the top bar, select Search or go to and find your project.
To use the custom image, update the agent-config.yml file:
image: registry.internal.example.com/duo-executor:latest
{{< history >}}
{{< /history >}}
GitLab provides a hardened, minimal image variant based on Red Hat Universal Base Image (UBI) 9 Minimal.
Use the hardened image when your environment requires:
The hardened image is published at
registry.gitlab.com/gitlab-org/duo-workflow/default-docker-image/workflow-generic-image-hardened
It is built for both linux/amd64 and linux/arm64, and uses the following tag scheme:
:<short-sha> for each build:<git-tag> for each releasePrerequisites:
To use the hardened image, set it in your agent-config.yml:
image: registry.gitlab.com/gitlab-org/duo-workflow/default-docker-image/workflow-generic-image-hardened:<tag>
For the authoritative and up-to-date list of all components and pinned versions,
see the runtime inventory in the default-docker-image README.
The following table lists the current pinned versions:
| Component | Version or source |
|---|---|
| Base image | Red Hat UBI 9 Minimal (ubi9-minimal:9.7-1776833838) |
git | 2.47.x (UBI 9 stock) |
git-lfs | UBI 9 stock |
| Node.js | 20 (UBI 9 module stream nodejs:20) |
npm | Bundled with Node.js 20 |
@gitlab/duo-cli | 8.109.0 |
glab (GitLab CLI) | 1.107.0 |
@anthropic-ai/sandbox-runtime (SRT) | 0.0.20 (via npm) |
bwrap (bubblewrap) | AlmaLinux 9 EPEL (plain binary, userns-based sandboxing) |
socat | AlmaLinux 9 EPEL |
rg (ripgrep) | AlmaLinux 9 EPEL |
unshare | UBI 9 (util-linux-core) |
| Runtime user | Non-root, UID 1001 (duo-runner) |
The image includes @gitlab/duo-cli and glab. Outbound access to registry.npmjs.org or registry.gitlab.com
is not needed at flow execution time.
The hardened image runs as UID 1001 (duo-runner). The setup_script in your agent-config.yml
also runs as this non-root user, so it cannot install system packages with microdnf.
To add language runtimes or system packages:
Extend the image with your own FROM layer:
FROM registry.gitlab.com/gitlab-org/duo-workflow/default-docker-image/workflow-generic-image-hardened:<tag>
USER root
RUN microdnf install -y python3.12 python3.12-pip && microdnf clean all
USER 1001
Use setup_script for project dependencies that do not require root access. For example, pip install --user or npm install.