Add devcontainer definition for reproducible Linux dev environment - #236
Merged
Conversation
Provides a Docker-based devcontainer so Claude Code remote sessions and local contributors get a consistent environment with all dependencies pre-installed. - Base image: mcr.microsoft.com/devcontainers/base:ubuntu-24.04 (vscode user with passwordless sudo, git, curl pre-installed) - Baked into image: GitHub CLI, .NET 10 SDK, PowerShell, Node.js LTS, Claude Code CLI, Playwright OS-level Chromium deps, Python ML venv at /opt/ml-env with numpy/pandas/tensorflow/dvc - ~/.claude mounted as named volume (survives container rebuilds; first Claude Code login is interactive, subsequent starts reuse credentials) - GITHUB_TOKEN forwarded from host environment so gh works without interactive login - post-create.sh: dotnet restore → dotnet build → playwright.ps1 install chromium --with-deps (version-matched to Microsoft.Playwright NuGet pin) - ml/requirements.txt added alongside devcontainer so Dockerfile COPY works from the repo-root build context Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019jmGA95hGTRu4aZ4yL45NL
Builds the Docker image on every push/PR that touches devcontainer files or ml/requirements.txt, then runs a smoke test inside the built container to verify .NET, gh, Node.js, Python, and the ML venv packages are all present and importable. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019jmGA95hGTRu4aZ4yL45NL
Test Results401 tests ±0 401 ✅ ±0 2m 34s ⏱️ +29s Results for commit a246452. ± Comparison against base commit d2636b6. This pull request removes 3 and adds 2 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a Docker-based devcontainer definition (plus CI validation) to provide a consistent Linux development environment for contributors/remote sessions, including preinstalled .NET/Node/Python tooling and a post-create bootstrap script.
Changes:
- Added
.devcontainer/definition (Dockerfile +devcontainer.json) and apost-create.shscript to restore/build and install Playwright Chromium. - Added a GitHub Actions workflow to build the devcontainer image and run a basic smoke test for installed tooling.
- Added
ml/requirements.txtto support baking ML Python dependencies into the devcontainer image.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
ml/requirements.txt |
Introduces pip requirements used during devcontainer image build. |
.github/workflows/devcontainer-build.yml |
Adds CI job to build the devcontainer image and smoke test key tools/packages. |
.devcontainer/post-create.sh |
Adds post-create bootstrap steps (restore/build + Playwright browser install). |
.devcontainer/Dockerfile |
Defines the devcontainer image and preinstalls developer dependencies. |
.devcontainer/devcontainer.json |
Configures devcontainer build, mounts, env vars, and editor settings/extensions. |
On Debian/Ubuntu, python3-venv is a separate package from python3 and must be explicitly installed before python3 -m venv will work. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019jmGA95hGTRu4aZ4yL45NL
jodavis
approved these changes
Jun 23, 2026
- Dockerfile: replace curl|bash NodeSource install with explicit GPG keyring + pinned node_24.x repo for auditability and reproducibility - devcontainer.json: forward GH_TOKEN alongside GITHUB_TOKEN (gh CLI checks both env vars depending on how the host is configured) - post-create.sh: export ~/.dotnet/tools to PATH in the fallback branch before calling playwright, since global tool installs land there and it is not on PATH by default; fix quality gate script names to include the .sh extension - ml/requirements.txt: pin to versions validated by the CI build (numpy 2.5.0, pandas 3.0.3, tensorflow 2.21.0, dvc 3.67.1) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019jmGA95hGTRu4aZ4yL45NL
jodavis
enabled auto-merge (squash)
June 23, 2026 12:20
jodavis
disabled auto-merge
June 23, 2026 12:20
jodavis
enabled auto-merge (rebase)
June 23, 2026 12:20
jodavis
disabled auto-merge
June 23, 2026 12:20
…ials Docker initialises a named volume from the image's directory at the mount point. If the directory doesn't exist in the image, Docker creates a root-owned entry and the vscode user cannot write to it — causing the 'login succeeds in browser but shows as not logged in' symptom. Creating ~/.claude as the vscode user in the Dockerfile ensures the volume is initialised with UID 1000 ownership on first use. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019jmGA95hGTRu4aZ4yL45NL
…racking, code style, and documentation standards.
…istry github.repository expands to jodavis/AdaptiveRemote (uppercase A) which Docker rejects — registry names must be all lowercase. Add a step that pipes the repository name through tr to produce the lowercase image name, then reference it via step output in imageName and cacheFrom. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019jmGA95hGTRu4aZ4yL45NL
Was pointing at /home/vscode/.claude/settings.json (the volume target, same as CLAUDE_SETTINGS). Should point at /home/vscode/.claude-defaults/ settings.json where the Dockerfile bakes the template. In CI the named volume is always fresh so the source never exists and cp fails. Locally this is masked because returning developers already have settings in the persistent volume and the if-block is skipped. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
validate.sh calls validate-build.sh and validate-tests.sh directly (no bash prefix), so they must be executable. Without the execute bit the devcontainer CI run fails with exit code 126 (permission denied) when validate.sh reaches line 20. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
jodavis
approved these changes
Jun 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Provides a Docker-based devcontainer so Claude Code remote sessions and
local contributors get a consistent environment with all dependencies
pre-installed.
user with passwordless sudo, git, curl pre-installed)
Claude Code CLI, Playwright OS-level Chromium deps, Python ML venv
at /opt/ml-env with numpy/pandas/tensorflow/dvc
Claude Code login is interactive, subsequent starts reuse credentials)
interactive login
chromium --with-deps (version-matched to Microsoft.Playwright NuGet pin)
works from the repo-root build context
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_019jmGA95hGTRu4aZ4yL45NL