If you find this add-on useful, please star it on GitHub — stars show appreciation and help maintainers know their work matters.
This add-on installs the OpenAI Codex CLI in a dedicated DDEV sidecar. The sidecar uses the project’s built web image, so it has the same PHP, Composer, Node.js, and project-specific tools as the web container. It supports AMD64 and ARM64 hosts.
This ddev addon has been written with codex assistance.
ddev add-on get ptmkenny/ddev-codex
ddev restart
Commit the generated files under .ddev, including .ddev/codex/.gitignore.
Codex state and credentials within .ddev/codex/ will be ignored.
If you have a ChatGPT subscription, enable device code authorization in your ChatGPT security settings and run:
ddev codex login --device-auth
Open the displayed URL in a browser and enter the one-time code. Codex stores
the resulting credentials in .ddev/codex/, where they persist across DDEV
restarts.
To use an API key instead, pipe it to Codex from your host environment:
printf '%s' "$OPENAI_API_KEY" | ddev codex login --with-api-key
Treat .ddev/codex/auth.json as a secret. Do not commit or share it.
# Start an interactive session in the project root.
ddev codex
# Show CLI help or the installed version.
ddev codex --help
ddev codex --version
# Run a prompt directly.
ddev codex "explain this project"
The sidecar starts with the project and mounts the same project filesystem as the web container. This includes DDEV’s Mutagen volume when Mutagen is enabled, so Codex does not use a second, slower project bind mount. Commands such as PHPCS, PHPStan, Composer, and Drush run directly in the sidecar:
ddev exec --service codex vendor/bin/phpcs
ddev exec --service codex vendor/bin/phpstan analyse
ddev exec --service codex drush status
The add-on also installs Bubblewrap and Python Pillow in the shared project
image. Pillow supports Codex image-generation helper scripts that need the
PIL Python package.
The latest Codex release is installed by default. To pin a release, create
.ddev/.env.codex:
CODEX_VERSION=0.152.1
Then rebuild the project image without its Docker cache:
ddev restart --no-cache
Use the same command to update a project that follows latest.
Codex’s Linux sandbox uses Bubblewrap and nested user and mount namespaces.
Docker’s default seccomp, AppArmor, and protected-system-path settings block
operations Bubblewrap needs. Only the Codex sidecar disables those three outer
restrictions with seccomp=unconfined, apparmor=unconfined, and
systempaths=unconfined. The web and database containers retain their normal
Docker security profiles. This is the same three-option configuration
Moby documents for a rootless sandbox running inside Docker.
The sidecar also drops all Linux capabilities and enables
no-new-privileges. It is not privileged and does not mount the Docker socket
or DDEV SSH agent. Codex can modify the project and connect to DDEV services by
their Compose names, such as web and db, but it cannot use Docker to inspect
or execute commands inside those containers.
systempaths=unconfined removes Docker’s masks from sensitive /proc and
/sys paths inside the sidecar. This is necessary for Bubblewrap to create its
inner mount layout, but it weakens the sidecar’s outer Docker boundary. Keep the
sidecar non-root and do not add capabilities or host-level mounts.
DDEV injects variables from .ddev/.env and .ddev/.env.local into every
project service, including this sidecar. Put web-only secrets in a targeted
file such as .ddev/.env.web.local when Codex should not receive them.
The idle sidecar runs only a keepalive process. It reuses the already-built web image and DDEV project mount, so the steady-state CPU impact is negligible and the main additional cost is one small container process and its writable layer.
SSH agent access is disabled by default. To opt in, add
.ddev/docker-compose.codex-ssh-agent.yaml:
services:
codex:
environment:
- SSH_AUTH_SOCK=/home/.ssh-agent/socket
volumes:
- ddev-ssh-agent_socket_dir:/home/.ssh-agent
volumes:
ddev-ssh-agent_socket_dir:
external: true
ddev add-on remove codex
DDEV preserves .ddev/codex/ when it contains Codex state. Remove that
directory manually if you also want to delete the stored credentials and
configuration.
This add-on was inspired by
Gonzalo2683/ddev-codex.
Patrick Kenny maintains this implementation at
ptmkenny/ddev-codex.
Apache License 2.0. See LICENSE.
If you find this add-on useful, please star it on GitHub — stars show appreciation and help maintainers know their work matters.