Skip to content

Docker networking on your infrastructure

← Overview · Self-hosting · Configuration

The worker runs on your server and makes outbound connections to GitHub, the selected model provider, package registries and services reachable from its Docker network. No incoming port, public URL or webhook endpoint is needed. Normal Docker bridge networking is the default.

flowchart LR
    Scheduler[Your scheduler] --> Worker[Docker worker]
    Worker --> Public[GitHub, model APIs and package registries]
    Worker --> Private[Your private Docker network]
    Private --> Services[Databases, APIs and test services]

Start a worker

From the target repository, with Repo Maintainer checked out beside it:

../repo_maintainer/maintainer init
# Add your task, editable paths and test commands to .maintainer.yml.
# Set CODEX_API_KEY in your shell or the Repo Maintainer checkout's .env.
../repo_maintainer/maintainer check
../repo_maintainer/maintainer run

New configs use version 2: Codex, general project checks and outbound access. agent.allow_paid: true explicitly permits use of the configured account. The initial whitespace check is a starting point; add your repository's tests, lint and build commands before unattended code work.

The default Debian worker includes native Codex, Git, GitHub CLI, Python and build tools. Select your project's tools with MAINTAINER_RUNTIME_IMAGE, for example node:24-bookworm, python:3.13-bookworm, golang:1.26-bookworm or rust:1.89-slim-bookworm. Set the variable in the checkout's .env or shell. The image compiles the maintainer in a separate Rust build stage.

Other containers and private services

Attach the worker to an existing Docker network used by your services:

export MAINTAINER_PRIVATE_NETWORK=my-services
export MAINTAINER_COMPOSE_FILES=compose.private-network.yml
../repo_maintainer/maintainer run

Containers on that network are reachable by their service/network alias, such as database:5432 or http://test-api:8080. The worker also keeps its normal outbound Docker network. The private network must already exist on the same Docker host.

host.docker.internal points to the Docker host gateway, including on Linux. Host services must listen on an interface reachable from that gateway. On Linux, a service bound only to 127.0.0.1 is not reachable through a bridge gateway. Private IPs and VPN routes work when your Docker host routes and permits container traffic to those destinations. The worker does not establish a VPN; attach it to your existing network or use your infrastructure's outbound proxy.

For private DNS, add compose.dns.yml and set a DNS server reachable from the container:

export MAINTAINER_DNS_SERVER=10.0.0.53
export MAINTAINER_COMPOSE_FILES=compose.private-network.yml:compose.dns.yml

Outbound proxies

Set HTTP_PROXY, HTTPS_PROXY, ALL_PROXY and NO_PROXY as needed in the shell or the checkout's .env. Lowercase variants are supported too. These values reach Codex and configured setup/test commands, while model and publisher keys are removed from test environments. Proxy URLs are redacted from worker error reports because they can contain credentials.

Include private service names and domains in NO_PROXY when they should connect directly. Proxy settings do not create access to a private network by themselves. Docker image pulls and Docker build networking are controlled separately by your Docker daemon/build configuration.

Private certificate authorities

Use a PEM bundle containing your private CA and the normal public root CAs. Mount it read-only with the CA overlay:

export MAINTAINER_CA_BUNDLE=/etc/my-company/full-ca-bundle.pem
export MAINTAINER_COMPOSE_FILES=compose.private-network.yml:compose.ca.yml
../repo_maintainer/maintainer run

The overlay sets trust paths for the native HTTP clients, Codex, Git, curl, Python, Node, pip and npm. Certificate verification remains enabled. The bundle must be readable by the container user. Configure daemon trust separately when pulling images from a private registry with a private CA.

MAINTAINER_COMPOSE_FILES is a colon-separated list of overlays, set in the shell that launches the wrapper. Relative names resolve against the Repo Maintainer checkout. Overlay settings such as the private-network name and CA path can be kept in that checkout's .env. Direct Compose invocations use the same files with repeated -f arguments.

Execution boundaries

Compose runs as an unprivileged user with a read-only root filesystem, all Linux capabilities dropped and privilege escalation disabled. The target checkout is read-only; the agent edits a temporary clone and returns its patch/report through /output. Compose gives the selected user a private temporary home for Codex's runtime files. It is discarded when the worker exits. There is no Docker socket mount, privileged mode or inbound listener. Connect only the private networks and services needed for the task: the agent's commands and project tests can use the network access you provide.

For version-2 configs, Compose explicitly sets MAINTENANCE_CODEX_SANDBOX_DEFAULT=danger-full-access: Docker supplies isolation, and Codex can use the container's tools and network without nesting a second user-namespace sandbox. Explicit agent.codex.sandbox settings take precedence. Native runs default to workspace-write. Setting agent.codex.network_access: false also selects that sandbox unless a sandbox is explicitly configured. That network flag applies only to workspace-write; use your container network policy to restrict outbound access in container isolation mode.

To require Codex's additional sandbox in Docker, set agent.codex.sandbox: workspace-write and use a runtime that permits nested user namespaces. A sandbox launch failure stops the run; it never triggers an automatic fallback. See Codex's network configuration.

run produces local proposal artifacts. Use the existing self-hosted PR workflow or separate pipeline stages when your scheduler should also validate and publish PRs. Supply a GitHub write token only to the publishing stage. The self-hosting guide describes scheduling and project-specific runtime setup.