Skip to content

Add devcontainer for sandboxed Claude Code development#4

Open
RaoulSchaffranek wants to merge 4 commits into
mainfrom
raoul/devcontainer
Open

Add devcontainer for sandboxed Claude Code development#4
RaoulSchaffranek wants to merge 4 commits into
mainfrom
raoul/devcontainer

Conversation

@RaoulSchaffranek

Copy link
Copy Markdown
Member

Provides a containerized dev environment so Claude Code can be run with --dangerously-skip-permissions while providing file system isolation.

  • Base on Microsoft's digest-pinned devcontainers/base:ubuntu24.04
  • The nix flake is the single source of trueth for almost all developer dependencies. The docker container is just a thin wrapper with Claude.
  • The git host identity is shared in read-only mode and exposed through a writable GIT_CONFIG_GLOBAL (~/.gitconfig.local) so every user can git commit and run git config inside the container.
  • Claude Code runs in its normal permission-prompting mode by default; users opt into bypass per session with --dangerously-skip-permission.

Provides a containerized dev environment so Claude Code can be run with
--dangerously-skip-permissions while confining the blast radius to the
container's filesystem.

- Base on Microsoft's digest-pinned devcontainers/base:ubuntu24.04, which
  ships a non-root `vscode` user (UID 1000) with passwordless sudo.
- Install the project toolchain via single-user Nix + direnv/nix-direnv,
  matching the project's flake (python, uv, make, wabt, K Framework).
- Install the Claude Code CLI to a per-user npm prefix.
- init: true for proper PID 1 / zombie reaping.
- Share the host git identity read-only and expose it through a writable
  GIT_CONFIG_GLOBAL (~/.gitconfig.local) so every user can git commit and
  run git config inside the container; openssh-client enables SSH remotes
  via the forwarded host SSH agent.

Claude Code runs in its normal permission-prompting mode by default; users
opt into bypass per session with --dangerously-skip-permissions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a VS Code devcontainer environment intended to run Claude Code inside an isolated container, while using Nix/flake-based tooling and preserving the host Git identity in a safe (read-only) way.

Changes:

  • Add a digest-pinned Ubuntu 24.04 devcontainer image that installs single-user Nix, direnv/nix-direnv, Node.js, and the Claude Code CLI.
  • Add a post-create Git setup script to provide a writable global Git config that includes the host’s identity config.
  • Add devcontainer.json wiring for mounts, environment variables, and initial project bootstrapping (nix develop … uv sync).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
.devcontainer/Dockerfile Defines the devcontainer image, installs/configures Nix + bootstrap tooling + Claude Code CLI.
.devcontainer/devcontainer.json Configures mounts/env/post-create bootstrapping for the devcontainer.
.devcontainer/setup-git.sh Creates/updates a writable global Git config that can include the host .gitconfig.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +20 to +30
if [ -f "${host_gitconfig}" ]; then
# Host provided a ~/.gitconfig (bind-mounted as a regular file): inherit it.
printf '[include]\n\tpath = %s\n' "${host_gitconfig}" > "${local_gitconfig}"
echo "setup-git: global config includes host identity from ${host_gitconfig}"
else
# No host ~/.gitconfig — the missing bind source is materialized as an empty
# directory, which must NOT be included. Leave an empty writable global.
: > "${local_gitconfig}"
echo "setup-git: no host ~/.gitconfig found; created empty ${local_gitconfig}"
echo "setup-git: set your identity with 'git config --global user.name ...' / user.email"
fi
Comment thread .devcontainer/Dockerfile Outdated
Comment on lines +39 to +42
# Single-user Nix install — the variant that works in containers without
# systemd / a running daemon.
RUN curl -fsSL https://nixos.org/nix/install | sh -s -- --no-daemon --no-channel-add

Comment thread .devcontainer/Dockerfile
Comment on lines +45 to +52
# Pin the `nixpkgs` flake to nixos-25.05 (matches the project's flake.nix), then
# install only the container-level bootstrap/runtime tooling via Nix:
# - direnv + nix-direnv → auto-load and cache the flake's `nix develop` shell on
# entry to /workspace; this is what actually provides the
# project toolchain (python, uv, make, wabt, K Framework),
# so those live in flake.nix's devShell, not here.
# - nodejs_22 → host for the Claude Code CLI (run as `claude` from
# anywhere, so it stays globally on PATH, not in the shell)
Comment thread .devcontainer/Dockerfile Outdated
Comment on lines +60 to +63
# Claude Code CLI — installed to a per-user prefix so root isn't required.
RUN . /home/vscode/.nix-profile/etc/profile.d/nix.sh \
&& npm config set prefix /home/vscode/.npm-global \
&& npm install -g @anthropic-ai/claude-code

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pinned to @anthropic-ai/claude-code@2.1.175 in commit 0f3f6f7.

Comment thread .devcontainer/devcontainer.json
The devcontainer loads the project toolchain via direnv + `nix develop`,
so it needs the flake the container provisions:

- flake.nix: add k-framework, wabt, and gnumake to the devShell (the
  toolchain the project's Makefile and integration tests rely on), pin
  UV_LINK_MODE=copy.
- flake.lock: pin all flake inputs for reproducible `nix develop`.
- .envrc: `use flake` so direnv auto-loads the dev shell on entry.
- .gitignore: ignore the .direnv/ cache the container creates.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants