Getting started: Codex¶
Note
NIH-specific At NIH, it is more straightforward to get up and running with Codex. This is due to how login works. So this section will walk you through a progression of setting up Codex locally on your Mac laptop, then running it locally in a Podman container, then running it on a remote system in a Singularity container.
Later, once Codex is up and running, you can explore using AWS Bedrock with Claude Code or Pi harnesses.
Step 1: Codex locally (“native” installation)¶
The minimal first step is to confirm that the Codex CLI works locally, without a container. This is the the so-called “native” installation. Even if you are planning on only calling models from Codex inside a container, this native version still needs to be set up because we need to use it when refreshing login credentials.
Install Codex CLI on your local machine.
Navigate to a directory you are comfortable letting Codex see (not your home directory!)
Run
codexfrom the terminal.When Codex starts, select the first login option, Sign in with ChatGPT. A web browser will open for single sign-on.
After successful login, the running Codex instance detects the login automatically. Allow permission to work in the current directory.
Type in a prompt (even just the word “testing”). It’s working if the model responds.
Ctrl-C twice, or
/exitto quit.Start Codex again. This time you should not need to log in, and submitting a test prompt should again work.
Tip
You know it worked when you can start Codex from the command line without needing to log in again, send a prompt, and get a response.
What did this do?
Choosing “Sign in with ChatGPT” opened your web browser to a specific
website. Logging in through the website triggered a redirect back to your
computer, which the listening Codex saw. It took the payload from that
redirect and created (or updated) the file ~/.codex/auth.json.
This file contains your credentials. We will be transporting this file into containers and to the remote host to authenticate in Codex instances running there. Treat this file like a password because it allows Codex to authenticate as you. See official Codex documentation on auth.json for more.
Step 2: Codex locally (podman container)¶
Running Codex natively as above still can allow read access to your entire computer. While updates to Codex are improving the sandboxing, running in a container helps isolate further by only mounting what is needed into the container. That is, we create a so-called “allow list” of what the model can see. By default, this is only the working directory from which you start the container.
Since we are using the container as our isolation mechanism, we can then run Codex with more permissive settings when inside the container (in fact, the Codex sandbox doesn’t work inside a container).
After confirming you have a local native instance of Codex working as described above, do the following:
Install Podman Desktop and ensure it is running. NOTE: only tested on a Mac.
Download the
launch.pyscript from this repo (see How to get the scripts for details on this).Navigate to a directory your are comfortable letting Codex see
Run the following; it may take a few seconds the first time because it needs to download and prepare the container:
launch.py codexSimilar to above, submit a prompt to confirm that the model replies.
Ctrl-C twice, or
/exitto quit.
Tip
You know it worked when you can run launch.py codex and it behaves
similarly to the native installation in the first section, except this time
it was through a Podman container.
What did this do?
launch.pydetected you’re running on a Mac and that Podman is the appropriate container runtime.Podman downloaded the image that was previously created and hosted by this repo, which already has Codex installed
Podman started up the image to create a container
During this creation process, we automatically mounted the current working directory into the container (done automatically by default by the launch script)
We also automatically mounted your
~/.codex/auth.jsoninto the container so that the isolated Codex instance in the container could log in (also done by the launch script). This is how the instance of Codex running inside the container knows it’s you.We started Codex in the running container. Codex was started with the
--sandbox danger-full-accessargument, effectively disabling Codex’s sandbox because we are using the container for isolation.Exiting Codex automatically exited the container.
Warning
If you are on VPN, or otherwise on a network that is intercepting your SSL/TLS traffic, you may get connection errors inside the container. See Enterprise TLS certificates for how to fix this.
It involves downloading your enterprise certificate bundle and passing it to
launch.py with --certs or LLM_DEVCONTAINER_CERTS.
For other connection issues, see Troubleshooting.
Step 3: Remote Codex (Singularity)¶
Next, we’ll run Codex on a remote system (like NIH’s Biowulf HPC).
Download the
refresh.pyscript from this repo locally; it is most convenient to put it on your PATH. As above, see How to get the scripts for more info on this.Run it like this; in this example we’re using NIH’s Biowulf as the hostname and connecting as our current username; modify as appropriate for your situation:
refresh.py --kind codex --remote biowulf.nih.gov
Log in to the remote system. If using NIH’s Biowulf, get an interactive node and load the Singularity module:
ssh biowulf.nih.gov # log in sinteractive # allocate interactive node module load singularity # make Singularity available
Download the
launch.pyscript from this repo to the remote. If you want a one-liner, this will put it in your home directory (~/launch.py) but you may want to put it somewhere on your PATH for convenience.curl -fSsL -o ~/launch.py https://github.com/nichd-bspc/llm/launch.py
Run the following, and test like you did above for the native version and the local container version.
launch.py codex
Tip
You know it works when you run launch.py codex on the remote system
using Singularity and it behaves similarly to the Podman and native versions
above.
What did this do?
The refresh script checked to see if you were logged in to Codex on the local machine. If not, it ran
codex login(using the native local installation from above) to refresh the~/.codex/auth.jsonfileThen it used rsync to transport the local copy of
~/.codex/auth.jsonto the remote systemWe need the launcher script on the other system, hence needing to download it there as well.
Running
launch.py codexon the remote machine identified that we were on a Linux host so that we should use Singularity. It downloaded the Singularity image, disabled Singularity’s default behavior of mounting your entire home directory, mounted~/.codexinto the container (which includes theauth.jsoncredentials), and started Codex.
Step 4: Configure Codex¶
See Configure Codex for configuration.
Step 5: Routine usage¶
Each time you start the container with launch.py on a local Mac or
a remote system, you will use the latest built image for the harness you are
launching.
Periodically, your credentials stored in ~/.codex/auth.json will
expire. Use the refresh.py script to update them and push to a remote.
Each time you start the container, you will use the latest built image for the
harness you are launching: ghcr.io/nichd-bspc/llm:codex-latest for podman or
oras://ghcr.io/nichd-bspc/llm-sif:codex-latest for Singularity. These
per-harness tags only move when Codex itself changes version, so you are not
pulling a fresh image every day when Codex is unchanged.
If you don’t want this behavior you can use the --image-name argument to
launch.py to pin to a particular version: e.g.,
--image-name ghcr.io/nichd-bspc/llm:codex-0.125.0, or other tags listed on
the images page. You can also
pass --tag to choose a tag without retyping the full image name, e.g.
--tag latest to use the latest overall image, or --tag codex-0.125.0 to
pin a version.
From these docs:
launch.py for more advanced ways of calling
launch.pyRunning agents in containers for more details on containers
Tips for working with agents in general
From official Codex docs: