Developers

Building containers

Images are already created as part of this repo’s GitHub Actions – see How are the images created?. But if you want to build your own custom containers or do other development work, here is how to build them yourself.

1. Build the podman image

This assumes you are successfully running Codex from a container, which means you have Podman Desktop installed and running.

The Dockerfile is where the build is specified, so modifying that will most likely be your entrypoint for customization.

Build once initially, then rebuild whenever you want updated tooling:

./build.py

If your network uses TLS interception, the first build may fail because the container does not yet trust the enterprise certificates. See Enterprise TLS certificates for how to download a local PEM CA bundle and make it available via --certs or LLM_DEVCONTAINER_CERTS.

When running build.py:

  • The default image name is llm-devcontainer. Change it with --image-name.

  • The default platform is linux/amd64. On ARM64 macOS this runs under emulation, which is usually acceptable because CPU is not the bottleneck. Change it with --arch.

  • Cache is used by default. To force a fresh rebuild, use --no-cache.

  • If you do not pass explicit tool versions, the image installs the latest available Claude Code, Codex, and Pi releases.

Tip

Test with refresh.py to refresh credentials, followed by launch.py --image-name llm-devcontainer codex (see launch.py for all options). This starts the container, mounts the current directory to the same path inside the container, and immediately starts Codex. Use !-prefixed shell commands such as ! ls ~ to verify that other host directories are not mounted.

2. Convert to Singularity image

Create a tarball of the Podman image:

podman save -o llm-image.tar --format docker-archive llm-devcontainer

Transport it to a machine with Singularity installed:

rsync -arv --progress llm-image.tar user@hostname:/path/on/remote/llm-image.tar

On the remote host, with Singularity installed, convert to SIF:

singularity build llm.sif docker-archive:/path/on/remote/llm-image.tar

Adding a new agent

Steps to support a new agent in the container and launch.py:

  • Install it in Dockerfile

  • Add credential paths to CREDENTIAL_PATHS in launch.py (see launch.py for current defaults)

  • Add command and credentials reference to SUBCOMMAND_CONFIG in launch.py

  • Append credentials to shell section of SUBCOMMAND_CONFIG as well

  • Document credential and config files in Configuration and credential files

  • If using Bedrock, add a detection method to Launcher._bedrock_enabled(). Make up a new env var if needed

  • Pass thru Launcher._host_env_with_prefixes() if relevant

  • Document