Skip to content

Commit a0ce301

Browse files
committed
Initial commit
0 parents  commit a0ce301

File tree

6 files changed

+412
-0
lines changed

6 files changed

+412
-0
lines changed

.github/workflows/build-image.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Build image
2+
3+
on:
4+
push:
5+
branches: [ "main" ]
6+
7+
env:
8+
REGISTRY: ghcr.io
9+
IMAGE_NAME: ${{ github.repository }}
10+
11+
jobs:
12+
build-and-push:
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: read
16+
packages: write
17+
attestations: write
18+
id-token: write
19+
steps:
20+
- uses: actions/checkout@v4
21+
- name: Log in to ghcr.io
22+
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
23+
with:
24+
registry: ${{ env.REGISTRY }}
25+
username: ${{ github.actor }}
26+
password: ${{ secrets.GITHUB_TOKEN }}
27+
- name: Set up Docker Buildx
28+
uses: docker/setup-buildx-action@v3
29+
- name: Build and push
30+
uses: docker/build-push-action@v6
31+
with:
32+
push: true
33+
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest

Dockerfile

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
FROM ubuntu:24.04
2+
3+
ENV LANG="C.UTF-8"
4+
ENV HOME=/root
5+
6+
### BASE ###
7+
8+
RUN apt-get update \
9+
&& apt-get upgrade -y \
10+
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
11+
binutils \
12+
sudo \
13+
build-essential \
14+
bzr \
15+
curl \
16+
default-libmysqlclient-dev \
17+
dnsutils \
18+
gettext \
19+
git \
20+
git-lfs \
21+
gnupg2 \
22+
inotify-tools \
23+
iputils-ping \
24+
jq \
25+
libbz2-dev \
26+
libc6 \
27+
libc6-dev \
28+
libcurl4-openssl-dev \
29+
libdb-dev \
30+
libedit2 \
31+
libffi-dev \
32+
libgcc-13-dev \
33+
libgcc1 \
34+
libgdbm-compat-dev \
35+
libgdbm-dev \
36+
libgdiplus \
37+
libgssapi-krb5-2 \
38+
liblzma-dev \
39+
libncurses-dev \
40+
libncursesw5-dev \
41+
libnss3-dev \
42+
libpq-dev \
43+
libpsl-dev \
44+
libpython3-dev \
45+
libreadline-dev \
46+
libsqlite3-dev \
47+
libssl-dev \
48+
libstdc++-13-dev \
49+
libunwind8 \
50+
libuuid1 \
51+
libxml2-dev \
52+
libz3-dev \
53+
make \
54+
moreutils \
55+
netcat-openbsd \
56+
openssh-client \
57+
pkg-config \
58+
protobuf-compiler \
59+
python3-pip \
60+
ripgrep \
61+
rsync \
62+
software-properties-common \
63+
sqlite3 \
64+
swig3.0 \
65+
tk-dev \
66+
tzdata \
67+
unixodbc-dev \
68+
unzip \
69+
uuid-dev \
70+
xz-utils \
71+
zip \
72+
zlib1g \
73+
zlib1g-dev \
74+
&& rm -rf /var/lib/apt/lists/*
75+
76+
### PYTHON ###
77+
78+
ARG PYENV_VERSION=v2.5.5
79+
# pyenv commands require the full version, so we specify e.g. 3.11.12 rather than 3.11
80+
ARG PYTHON_VERSION=3.11.12
81+
82+
# Install pyenv
83+
ENV PYENV_ROOT=/root/.pyenv
84+
ENV PATH=$PYENV_ROOT/bin:$PATH
85+
RUN git -c advice.detachedHead=0 clone --branch ${PYENV_VERSION} --depth 1 https://github.com/pyenv/pyenv.git "${PYENV_ROOT}" \
86+
&& echo 'export PYENV_ROOT="$HOME/.pyenv"' >> /etc/profile \
87+
&& echo 'export PATH="$$PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH"' >> /etc/profile \
88+
&& echo 'eval "$(pyenv init - bash)"' >> /etc/profile \
89+
&& cd ${PYENV_ROOT} && src/configure && make -C src \
90+
&& pyenv install 3.10 3.11.12 3.12 3.13 \
91+
&& pyenv global ${PYTHON_VERSION}
92+
# Install pipx for common global package managers (e.g. poetry)
93+
ENV PIPX_BIN_DIR=/root/.local/bin
94+
ENV PATH=$PIPX_BIN_DIR:$PATH
95+
RUN apt-get update && apt-get install -y pipx \
96+
&& pipx install poetry uv
97+
98+
### NODE ###
99+
100+
ARG NVM_VERSION=v0.40.2
101+
ARG NODE_VERSION=22
102+
103+
ENV NVM_DIR=/root/.nvm
104+
# Suppress interactive download prompt
105+
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
106+
RUN git -c advice.detachedHead=0 clone --branch ${NVM_VERSION} --depth 1 https://github.com/nvm-sh/nvm.git "${NVM_DIR}" \
107+
&& echo 'source $NVM_DIR/nvm.sh' >> /etc/profile \
108+
&& . $NVM_DIR/nvm.sh \
109+
&& nvm install 18 \
110+
&& nvm install 20 \
111+
&& nvm install 22 \
112+
&& nvm alias default $NODE_VERSION \
113+
&& corepack enable
114+
115+
### BUN ###
116+
117+
ARG BUN_VERSION=1.2.10
118+
119+
ENV BUN_INSTALL=/root/.bun
120+
ENV PATH="$BUN_INSTALL/bin:$PATH"
121+
122+
RUN mkdir -p "$BUN_INSTALL/bin" \
123+
&& curl -L --fail "https://github.com/oven-sh/bun/releases/download/bun-v${BUN_VERSION}/bun-linux-x64-baseline.zip" \
124+
-o /tmp/bun.zip \
125+
&& unzip -q /tmp/bun.zip -d "$BUN_INSTALL/bin" \
126+
&& mv "$BUN_INSTALL/bin/bun-linux-x64-baseline/bun" "$BUN_INSTALL/bin/bun" \
127+
&& chmod +x "$BUN_INSTALL/bin/bun" \
128+
&& rm -rf "$BUN_INSTALL/bin/bun-linux-x64-baseline" /tmp/bun.zip \
129+
&& echo 'export BUN_INSTALL=/root/.bun' >> /etc/profile \
130+
&& echo 'export PATH="$BUN_INSTALL/bin:$PATH"' >> /etc/profile
131+
132+
### JAVA ###
133+
134+
ARG JAVA_VERSION=21
135+
ARG GRADLE_VERSION=8.14
136+
ARG GRADLE_DOWNLOAD_SHA256=61ad310d3c7d3e5da131b76bbf22b5a4c0786e9d892dae8c1658d4b484de3caa
137+
138+
ENV GRADLE_HOME=/opt/gradle
139+
RUN apt-get update && apt-get install -y --no-install-recommends \
140+
openjdk-${JAVA_VERSION}-jdk \
141+
&& rm -rf /var/lib/apt/lists/* \
142+
&& curl -LO "https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip" \
143+
&& echo "${GRADLE_DOWNLOAD_SHA256} *gradle-${GRADLE_VERSION}-bin.zip" | sha256sum --check - \
144+
&& unzip gradle-${GRADLE_VERSION}-bin.zip \
145+
&& rm gradle-${GRADLE_VERSION}-bin.zip \
146+
&& mv "gradle-${GRADLE_VERSION}" "${GRADLE_HOME}/" \
147+
&& ln -s "${GRADLE_HOME}/bin/gradle" /usr/bin/gradle
148+
149+
### SWIFT ###
150+
151+
ARG SWIFT_VERSION=6.1
152+
153+
# Install swift.
154+
RUN mkdir /tmp/swiftly \
155+
&& cd /tmp/swiftly \
156+
&& curl -O https://download.swift.org/swiftly/linux/swiftly-$(uname -m).tar.gz \
157+
&& tar zxf swiftly-$(uname -m).tar.gz \
158+
&& ./swiftly init --quiet-shell-followup -y \
159+
&& echo '. ~/.local/share/swiftly/env.sh' >> /etc/profile \
160+
&& bash -lc "swiftly install --use ${SWIFT_VERSION}" \
161+
&& rm -rf /tmp/swiftly
162+
163+
### RUBY ###
164+
165+
RUN apt-get update && apt-get install -y --no-install-recommends \
166+
ruby-full
167+
168+
### RUST ###
169+
170+
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
171+
sh -s -- -y --profile minimal \
172+
&& . "$HOME/.cargo/env" \
173+
&& rustup show
174+
175+
### GO ###
176+
177+
ARG GO_VERSION=1.23.8
178+
ARG GO_DOWNLOAD_SHA256=45b87381172a58d62c977f27c4683c8681ef36580abecd14fd124d24ca306d3f
179+
180+
# Go defaults GOROOT to /usr/local/go - we just need to update PATH
181+
ENV PATH=/usr/local/go/bin:$HOME/go/bin:$PATH
182+
RUN mkdir /tmp/go \
183+
&& cd /tmp/go \
184+
&& curl -O https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz \
185+
&& echo "${GO_DOWNLOAD_SHA256} *go${GO_VERSION}.linux-amd64.tar.gz" | sha256sum --check - \
186+
&& tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz \
187+
&& rm -rf /tmp/go
188+
189+
### BAZEL ###
190+
191+
RUN curl -L --fail https://github.com/bazelbuild/bazelisk/releases/download/v1.26.0/bazelisk-linux-amd64 -o /usr/local/bin/bazelisk \
192+
&& chmod +x /usr/local/bin/bazelisk \
193+
&& ln -s /usr/local/bin/bazelisk /usr/local/bin/bazel
194+
195+
### LLVM ###
196+
RUN apt-get update && apt-get install -y --no-install-recommends \
197+
git \
198+
cmake \
199+
ccache \
200+
python3 \
201+
ninja-build \
202+
nasm \
203+
yasm \
204+
gawk \
205+
lsb-release \
206+
wget \
207+
software-properties-common \
208+
gnupg \
209+
&& rm -rf /var/lib/apt/lists/* \
210+
&& bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
211+
212+
### SETUP SCRIPTS ###
213+
214+
COPY setup_universal.sh /opt/codex/setup_universal.sh
215+
RUN chmod +x /opt/codex/setup_universal.sh
216+
217+
COPY entrypoint.sh /opt/entrypoint.sh
218+
RUN chmod +x /opt/entrypoint.sh
219+
220+
ENTRYPOINT ["/opt/entrypoint.sh"]

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 OpenAI
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# codex-universal
2+
3+
`codex-universal` is a development implementation of the base Docker image available in [OpenAI Codex](https://github.com/openai/codex).
4+
5+
This repository is intended to help developers customizing environments in Codex by providing a similar image that can be pulled and run locally. This is not an identical environment but should help for debugging and development.
6+
7+
For docs on environment setup, see [OpenAI Codex](https://github.com/openai/codex).
8+
9+
## Usage
10+
11+
The below script shows how can you approximate the `setup` environment in Codex.
12+
13+
```
14+
docker pull ghcr.io/openai/codex-universal:latest
15+
```
16+
17+
```
18+
docker run --rm -it \
19+
# See below for environment variable options.
20+
-e CODEX_ENV_PYTHON_VERSION=3.12 \
21+
-e CODEX_ENV_NODE_VERSION=20 \
22+
-e CODEX_ENV_RUST_VERSION=1.86.0 \
23+
-e CODEX_ENV_GO_VERSION=1.23.8 \
24+
-e CODEX_ENV_SWIFT_VERSION=6.1 \
25+
# Mount the current directory similar to how it would get cloned in.
26+
-v $(pwd):/workspace/$(basename $(pwd)) -w /workspace/$(basename $(pwd)) \
27+
ghcr.io/openai/codex-universal:latest
28+
```
29+
30+
### Configuring language runtimes
31+
32+
The following env vars can be set to configure runtime installation. Note that a limited subset of versions are supported in the product (indicated in the table below)
33+
34+
| Environment variable | Description | Supported versions | Additional packages |
35+
| -------------------------- | -------------------------- | -------------------------------------- | -------------------------------------------------------------------- |
36+
| `CODEX_ENV_PYTHON_VERSION` | Python version to install | `3.10`, `3.11.12`, `3.12`, `3.13` | `pyenv`, `poetry`, `uv`, `ruff`, `black`, `mypy`, `pyright`, `isort` |
37+
| `CODEX_ENV_NODE_VERSION` | Node.js version to install | `18`, `20`, `22` | `corepack`, `yarn`, `pnpm`, `npm` |
38+
| `CODEX_ENV_RUST_VERSION` | Rust version to install | `1.83.0`, `1.84.1`, `1.85.1`, `1.86.0` | |
39+
| `CODEX_ENV_GO_VERSION` | Go version to install | `1.22.12`, `1.23.8`, `1.24.3` | |
40+
| `CODEX_ENV_SWIFT_VERSION` | Swift version to install | `5.10`, `6.1` | |
41+
42+
## What's included
43+
44+
In addition to the packages specified in the table above, the following packages are also installed:
45+
46+
- `ruby`: 3.2.3
47+
- `bun`: 1.2.10
48+
- `java`: 21
49+
- `bazelisk` / `bazel`
50+
51+
See [Dockerfile](Dockerfile) for the full details of installed packages.

entrypoint.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/bin/bash
2+
3+
echo "=================================="
4+
echo "Welcome to openai/codex-universal!"
5+
echo "=================================="
6+
7+
/opt/codex/setup_universal.sh
8+
9+
echo "Environment ready. Dropping you into a bash shell."
10+
exec bash --login "$@"

0 commit comments

Comments
 (0)