Codex Docker Environment Template
A hardened Docker/devcontainer setup for running OpenAI’s Codex CLI with predictable tooling, locked-down permissions, and resource quotas. Drop it into any repository to spin up an isolated workspace that still has everything you need (git, zsh, gh, fzf, delta, etc.) to collaborate with Codex comfortably.
Why this exists
- Keep Codex sessions contained: only the project folder is mounted and Linux capabilities are dropped.
- Provide a consistent toolbox: Node.js 20 base image plus common CLI utilities and Zsh defaults.
- Make auth easy but safe: a loopback-only
socatsidecar forwards the Codex port so the CLI can talk to OpenAI without exposing extra surfaces. - Encourage reproducibility: ship the…
Codex Docker Environment Template
A hardened Docker/devcontainer setup for running OpenAI’s Codex CLI with predictable tooling, locked-down permissions, and resource quotas. Drop it into any repository to spin up an isolated workspace that still has everything you need (git, zsh, gh, fzf, delta, etc.) to collaborate with Codex comfortably.
Why this exists
- Keep Codex sessions contained: only the project folder is mounted and Linux capabilities are dropped.
- Provide a consistent toolbox: Node.js 20 base image plus common CLI utilities and Zsh defaults.
- Make auth easy but safe: a loopback-only
socatsidecar forwards the Codex port so the CLI can talk to OpenAI without exposing extra surfaces. - Encourage reproducibility: ship the exact Dockerfile/compose combo you can bring to any project.
What’s included
| File | Purpose |
|---|---|
Dockerfile.codex | Builds the dev image from node:20, installs CLI tools, configures Zsh, sets up persistent history, and installs @openai/codex. |
docker-compose.codex.yaml | Defines the dev workspace container and a proxy service (Alpine socat) that forwards TCP/1455 back to Codex. |
api.http | Scratchpad for Codex HTTP requests (handy when testing API calls). |
Prerequisites
- Docker Engine 20.10+ and the Docker Compose v2 plugin.
- Access to the OpenAI Codex CLI (login happens from inside the container).
- Optionally, GNU Make or task runners if you want to wrap the compose commands.
Quick start
Clone or copy this template
git clone https://github.com/mkloubert/codex-docker-env codex-env
cd codex-env
Build and start the workspace
docker compose -f docker-compose.codex.yaml up --build -d dev
Attach to the container shell
docker compose -f docker-compose.codex.yaml exec dev zsh
Authenticate Codex
codex login
The CLI will open a device-code flow. Once authenticated you can run codex chat, codex task, etc. inside /workspace.
1.
Stop the stack when finished
docker compose -f docker-compose.codex.yaml down
Using this in your own project
- Copy
Dockerfile.codexanddocker-compose.codex.yamlinto the root of your repo. - Adjust paths under
volumesif your project lives somewhere other than./. - (Optional) Create a
.envfile withTZ,CODEX_CODE_VERSION, or other args you want to pin. - Run the same compose commands from within your repo—your source tree will be mounted into
/workspace.
Because the compose file only exposes port 1455 internally (via the proxy service) you can safely run multiple projects by giving each stack a distinct project name:
COMPOSE_PROJECT_NAME=myapp-codex docker compose -f docker-compose.codex.yaml up -d dev
Customization hints
- Resource limits: tweak
deploy.resourcesto raise/lower CPU and memory for Codex sessions. - Network isolation: set
network_mode: nonein thedevservice to go fully offline (Codex CLI features that hit the network will stop working). - User mapping: uncomment the
user:line and passUID/GIDbuild args so container file ownership matches the host. - Tooling: extend the
apt-get installlist or add extra global npm packages after theRUN npm install -g @openai/codex@...line.
Security posture
cap_drop: [ALL]andsecurity_opt: ["no-new-privileges:true"]prevent accidental privilege escalation.- Only
./is mounted, so Codex cannot see files outside your project. - The proxy binds to
127.0.0.1, keeping the Codex port off your LAN. - Shell history is stored under
/commandhistoryinside the container; remove the volume if you prefer stateless sessions.
Troubleshooting
- Landlock/Sandbox errors: If you see
error running landlockwhen running commands outside Docker (for example, in Codex sandbox environments), rerun with elevated permissions or execute from within the container where the filesystem is writable. - Auth loops: Run
codex logoutthencodex logininside the container to refresh tokens. - Port conflicts: If 1455 is in use on your host, change the
socat TCP-LISTENport and thecodexCLI--hostflag accordingly.
License
MIT — see LICENSE for details.