From d3e9b4e424b6862b158a4db116e4d294dba4a1f2 Mon Sep 17 00:00:00 2001 From: Junya Morioka Date: Wed, 2 Sep 2026 04:45:11 +0900 Subject: [PATCH 1/7] feat: install pinned Codex in dev containers - build from the Ubuntu 24.04 devcontainer base image - verify and install the standalone Codex 0.121.0 release for amd64 and arm64 - import AGENTS.md from a regular CLAUDE.md file --- template/.devcontainer/Dockerfile | 24 ++++++++++++++++++++++++ template/.devcontainer/devcontainer.json | 10 ++++++---- template/CLAUDE.md | 2 +- 3 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 template/.devcontainer/Dockerfile mode change 120000 => 100644 template/CLAUDE.md diff --git a/template/.devcontainer/Dockerfile b/template/.devcontainer/Dockerfile new file mode 100644 index 0000000..b11c3d8 --- /dev/null +++ b/template/.devcontainer/Dockerfile @@ -0,0 +1,24 @@ +FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04 + +ARG CODEX_VERSION=0.121.0 +ARG CODEX_SHA256_AMD64=f053ac81e9c6769920f9ee3566abad47ab0856eb7ee792428681664ece113430 +ARG CODEX_SHA256_ARM64=9ce5edd5524898ad2e95b59f278977e312726e0587957d1f10ee389070fe5034 + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +RUN apt-get update \ + && apt-get install -y --no-install-recommends ca-certificates curl \ + && case "$(uname -m)" in \ + x86_64) codex_target="x86_64-unknown-linux-gnu"; codex_sha256="${CODEX_SHA256_AMD64}" ;; \ + aarch64 | arm64) codex_target="aarch64-unknown-linux-gnu"; codex_sha256="${CODEX_SHA256_ARM64}" ;; \ + *) echo "Unsupported architecture: $(uname -m)" >&2; exit 1 ;; \ + esac \ + && curl -fsSL \ + "https://github.com/openai/codex/releases/download/rust-v${CODEX_VERSION}/codex-${codex_target}.tar.gz" \ + -o /tmp/codex.tar.gz \ + && echo "${codex_sha256} /tmp/codex.tar.gz" | sha256sum --check --strict \ + && tar -xzf /tmp/codex.tar.gz -C /tmp \ + && install -m 0755 "/tmp/codex-${codex_target}" /usr/local/bin/codex \ + && rm -f /tmp/codex.tar.gz "/tmp/codex-${codex_target}" \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* diff --git a/template/.devcontainer/devcontainer.json b/template/.devcontainer/devcontainer.json index 850173d..1b0bf75 100644 --- a/template/.devcontainer/devcontainer.json +++ b/template/.devcontainer/devcontainer.json @@ -1,6 +1,9 @@ { "name": "python-devcontainer", - "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "build": { + "dockerfile": "Dockerfile", + "context": ".." + }, "containerEnv": { "DISPLAY": "${localEnv:DISPLAY}", "PYTHONUNBUFFERED": "1", @@ -18,12 +21,11 @@ "configureZshAsDefaultShell": true }, "ghcr.io/rocker-org/devcontainer-features/apt-packages:1": { - "packages": "curl,wget,git,jq,ca-certificates,build-essential,ripgrep,fd-find" + "packages": "wget,git,jq,build-essential,ripgrep,fd-find" }, "ghcr.io/va-h/devcontainers-features/uv:1": { "shellAutocompletion": true }, - "ghcr.io/devcontainers/features/node:1": {}, "ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {} }, "runArgs": [ @@ -58,6 +60,6 @@ "source=${localEnv:HOME}/.codex,target=/home/vscode/.codex,type=bind", "source=${localEnv:HOME}/.codex/config.toml,target=/home/vscode/.codex/config.toml,type=bind" ], - "postCreateCommand": "npm install -g @openai/codex@latest && uv sync --locked", + "postCreateCommand": "uv sync --locked", "postStartCommand": "uv run pre-commit install" } diff --git a/template/CLAUDE.md b/template/CLAUDE.md deleted file mode 120000 index 47dc3e3..0000000 --- a/template/CLAUDE.md +++ /dev/null @@ -1 +0,0 @@ -AGENTS.md \ No newline at end of file diff --git a/template/CLAUDE.md b/template/CLAUDE.md new file mode 100644 index 0000000..43c994c --- /dev/null +++ b/template/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md From 8a8943e7aed4823fd4ffcaa818f9a6d083db70d2 Mon Sep 17 00:00:00 2001 From: Junya Morioka Date: Wed, 2 Sep 2026 04:48:36 +0900 Subject: [PATCH 2/7] fix: test the current template revision - make Copier render HEAD instead of the latest release tag - ensure pull request changes are included in generated project checks --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7c56a87..d1013f3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,6 +33,7 @@ jobs: - name: Copy Template run: | uvx copier copy \ + --vcs-ref HEAD \ ./ \ /tmp/test-copier \ -d project_name=test-copier \ From 48af91e4a5f6384107d6ddb69cb7cbb66a242d05 Mon Sep 17 00:00:00 2001 From: Junya Morioka Date: Wed, 2 Sep 2026 09:25:02 +0900 Subject: [PATCH 3/7] refactor: simplify dev container mounts - persist the uv cache in a dedicated named volume - share Claude and Codex host directories without redundant nested mounts --- template/.devcontainer/devcontainer.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/template/.devcontainer/devcontainer.json b/template/.devcontainer/devcontainer.json index 1b0bf75..9717bbf 100644 --- a/template/.devcontainer/devcontainer.json +++ b/template/.devcontainer/devcontainer.json @@ -52,13 +52,12 @@ }, "remoteUser": "vscode", "containerUser": "vscode", - "initializeCommand": "mkdir -p ${localEnv:HOME}/.claude ${localEnv:HOME}/.codex && touch ${localEnv:HOME}/.claude/CLAUDE.md ${localEnv:HOME}/.codex/config.toml", + "initializeCommand": "mkdir -p ${localEnv:HOME}/.claude ${localEnv:HOME}/.codex", "mounts": [ "source=shell_history-${devcontainerId},target=/shell_history,type=volume", + "source=uv-cache-${devcontainerId},target=/home/vscode/.cache/uv,type=volume", "source=${localEnv:HOME}/.claude,target=/home/vscode/.claude,type=bind", - "source=${localEnv:HOME}/.claude/CLAUDE.md,target=/home/vscode/.claude/CLAUDE.md,type=bind", - "source=${localEnv:HOME}/.codex,target=/home/vscode/.codex,type=bind", - "source=${localEnv:HOME}/.codex/config.toml,target=/home/vscode/.codex/config.toml,type=bind" + "source=${localEnv:HOME}/.codex,target=/home/vscode/.codex,type=bind" ], "postCreateCommand": "uv sync --locked", "postStartCommand": "uv run pre-commit install" From 8b4b68db29ca84edd4601a88ca11773d7352c904 Mon Sep 17 00:00:00 2001 From: Junya Morioka Date: Wed, 2 Sep 2026 09:32:31 +0900 Subject: [PATCH 4/7] fix: initialize the uv cache volume ownership Grant the vscode user write access before dependency synchronization. Keep the persistent uv cache usable on first container creation. --- template/.devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/.devcontainer/devcontainer.json b/template/.devcontainer/devcontainer.json index 9717bbf..692300c 100644 --- a/template/.devcontainer/devcontainer.json +++ b/template/.devcontainer/devcontainer.json @@ -59,6 +59,6 @@ "source=${localEnv:HOME}/.claude,target=/home/vscode/.claude,type=bind", "source=${localEnv:HOME}/.codex,target=/home/vscode/.codex,type=bind" ], - "postCreateCommand": "uv sync --locked", + "postCreateCommand": "sudo chown -R vscode:vscode /home/vscode/.cache/uv && uv sync --locked", "postStartCommand": "uv run pre-commit install" } From 93586b187aefe1c025030f8b1cf61e634b347b0f Mon Sep 17 00:00:00 2001 From: Junya Morioka Date: Wed, 2 Sep 2026 09:36:36 +0900 Subject: [PATCH 5/7] fix: make the dev container cache writable Initialize the parent cache directory ownership before dependency synchronization. Allow pre-commit to create its cache beside the mounted uv cache. --- template/.devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/.devcontainer/devcontainer.json b/template/.devcontainer/devcontainer.json index 692300c..38f189f 100644 --- a/template/.devcontainer/devcontainer.json +++ b/template/.devcontainer/devcontainer.json @@ -59,6 +59,6 @@ "source=${localEnv:HOME}/.claude,target=/home/vscode/.claude,type=bind", "source=${localEnv:HOME}/.codex,target=/home/vscode/.codex,type=bind" ], - "postCreateCommand": "sudo chown -R vscode:vscode /home/vscode/.cache/uv && uv sync --locked", + "postCreateCommand": "sudo chown -R vscode:vscode /home/vscode/.cache && uv sync --locked", "postStartCommand": "uv run pre-commit install" } From c46bdfdce266afae77854e655c0cf4d5a1e7920b Mon Sep 17 00:00:00 2001 From: Junya Morioka Date: Thu, 3 Sep 2026 06:21:16 +0900 Subject: [PATCH 6/7] feat: install the latest Codex release - replace pinned release assets with the official standalone installer - resolve the latest stable Codex version during image builds --- template/.devcontainer/Dockerfile | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/template/.devcontainer/Dockerfile b/template/.devcontainer/Dockerfile index b11c3d8..19d311c 100644 --- a/template/.devcontainer/Dockerfile +++ b/template/.devcontainer/Dockerfile @@ -1,24 +1,12 @@ FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04 -ARG CODEX_VERSION=0.121.0 -ARG CODEX_SHA256_AMD64=f053ac81e9c6769920f9ee3566abad47ab0856eb7ee792428681664ece113430 -ARG CODEX_SHA256_ARM64=9ce5edd5524898ad2e95b59f278977e312726e0587957d1f10ee389070fe5034 - -SHELL ["/bin/bash", "-o", "pipefail", "-c"] - RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates curl \ - && case "$(uname -m)" in \ - x86_64) codex_target="x86_64-unknown-linux-gnu"; codex_sha256="${CODEX_SHA256_AMD64}" ;; \ - aarch64 | arm64) codex_target="aarch64-unknown-linux-gnu"; codex_sha256="${CODEX_SHA256_ARM64}" ;; \ - *) echo "Unsupported architecture: $(uname -m)" >&2; exit 1 ;; \ - esac \ - && curl -fsSL \ - "https://github.com/openai/codex/releases/download/rust-v${CODEX_VERSION}/codex-${codex_target}.tar.gz" \ - -o /tmp/codex.tar.gz \ - && echo "${codex_sha256} /tmp/codex.tar.gz" | sha256sum --check --strict \ - && tar -xzf /tmp/codex.tar.gz -C /tmp \ - && install -m 0755 "/tmp/codex-${codex_target}" /usr/local/bin/codex \ - && rm -f /tmp/codex.tar.gz "/tmp/codex-${codex_target}" \ + && curl -fsSL https://github.com/openai/codex/releases/latest/download/install.sh -o /tmp/install-codex.sh \ + && CODEX_INSTALL_DIR=/usr/local/bin \ + CODEX_HOME=/opt/codex \ + CODEX_NON_INTERACTIVE=1 \ + sh /tmp/install-codex.sh \ + && rm -f /tmp/install-codex.sh \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* From c7f24f8067ed51ccf2ee7e53a9e29aa7c8d3ec2a Mon Sep 17 00:00:00 2001 From: Junya Morioka Date: Thu, 3 Sep 2026 07:02:42 +0900 Subject: [PATCH 7/7] refactor: manage dev container packages in Dockerfile - consolidate apt packages with the Codex installation layer - cache apt metadata and packages with locked BuildKit mounts - remove the redundant third-party apt packages Feature --- template/.devcontainer/Dockerfile | 22 +++++++++++++++++----- template/.devcontainer/devcontainer.json | 3 --- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/template/.devcontainer/Dockerfile b/template/.devcontainer/Dockerfile index 19d311c..ead3dd3 100644 --- a/template/.devcontainer/Dockerfile +++ b/template/.devcontainer/Dockerfile @@ -1,12 +1,24 @@ +# syntax=docker/dockerfile:1 + FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04 -RUN apt-get update \ - && apt-get install -y --no-install-recommends ca-certificates curl \ +RUN rm -f /etc/apt/apt.conf.d/docker-clean \ + && echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + apt-get update \ + && apt-get install -y --no-install-recommends \ + build-essential \ + ca-certificates \ + curl \ + fd-find \ + git \ + jq \ + ripgrep \ + wget \ && curl -fsSL https://github.com/openai/codex/releases/latest/download/install.sh -o /tmp/install-codex.sh \ && CODEX_INSTALL_DIR=/usr/local/bin \ CODEX_HOME=/opt/codex \ CODEX_NON_INTERACTIVE=1 \ sh /tmp/install-codex.sh \ - && rm -f /tmp/install-codex.sh \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* + && rm -f /tmp/install-codex.sh diff --git a/template/.devcontainer/devcontainer.json b/template/.devcontainer/devcontainer.json index 38f189f..957260a 100644 --- a/template/.devcontainer/devcontainer.json +++ b/template/.devcontainer/devcontainer.json @@ -20,9 +20,6 @@ "ghcr.io/devcontainers/features/common-utils:2": { "configureZshAsDefaultShell": true }, - "ghcr.io/rocker-org/devcontainer-features/apt-packages:1": { - "packages": "wget,git,jq,build-essential,ripgrep,fd-find" - }, "ghcr.io/va-h/devcontainers-features/uv:1": { "shellAutocompletion": true },