Skip to content

refactor: Replace custom Dockerfile with feature-based devcontainer#7

Merged
tablackburn merged 4 commits into
mainfrom
devcontainer-cleanup
Feb 7, 2026
Merged

refactor: Replace custom Dockerfile with feature-based devcontainer#7
tablackburn merged 4 commits into
mainfrom
devcontainer-cleanup

Conversation

@tablackburn
Copy link
Copy Markdown
Owner

@tablackburn tablackburn commented Feb 3, 2026

Summary

  • Replace custom Dockerfile with official devcontainer features (Claude Code, GitHub CLI, common-utils)
  • Switch from Windows-only ${localEnv:USERPROFILE} bind mounts to a cross-platform Docker Compose approach using a generated .env file
  • Update base image from non-existent 7-ubuntu-24.04 tag to floating ubuntu-24.04
  • Remove OTBS formatting preset and unused recommended extensions (GitLens, EditorConfig)

Changes

  • Deleted: .devcontainer/Dockerfile (custom build)
  • Added: .devcontainer/docker-compose.yml — service definition with cross-platform volume mounts using ${CLAUDE_HOST_HOME} from .env
  • Added: .devcontainer/setup-host.ps1initializeCommand script that detects USERPROFILE (Windows) or HOME (macOS/Linux) and writes .devcontainer/.env
  • Updated: .devcontainer/devcontainer.json — switched from image/mounts to dockerComposeFile/service with initializeCommand; added git safe.directory for bind-mounted workspace; removed OTBS formatting preset
  • Updated: .vscode/extensions.json — removed GitLens and EditorConfig recommendations
  • Updated: .gitignore — added .devcontainer/.env

How cross-platform mounts work

  1. initializeCommand runs setup-host.ps1 on the host before container creation
  2. Script detects home directory and workspace path, writes quoted values to .devcontainer/.env
  3. Docker Compose reads .env and substitutes ${CLAUDE_HOST_HOME} in volume mount paths
  4. Container starts with correct bind mounts regardless of host OS

Test plan

  • setup-host.ps1 generates correct .env on Windows
  • docker compose config resolves all volume paths correctly
  • devcontainer build --workspace-folder . succeeds
  • devcontainer up --workspace-folder . succeeds (workspace mount, features, postCreateCommand)

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings February 3, 2026 06:39
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 3, 2026

📝 Walkthrough

Walkthrough

Devcontainer switched from a custom build Dockerfile to an image-plus-docker-compose setup: .devcontainer/Dockerfile was removed, .devcontainer/devcontainer.json now references docker-compose and features, .devcontainer/docker-compose.yml was added, and .devcontainer/setup-host.ps1 generates .devcontainer/.env for bind mounts and volumes. (50 words)

Changes

Cohort / File(s) Summary
Removed Dockerfile
.devcontainer/Dockerfile
Removed custom image build and all build-time setup: package installs (git, curl, jq, sudo, ca-certificates, gnupg, less), Node/GitHub/Claude CLI installs, non-root user creation and sudo setup, PowerShell module/history mounts, git safe.directory config, and DEVCONTAINER env vars.
Devcontainer configuration
.devcontainer/devcontainer.json
Switched from build/Dockerfile to docker-compose (dockerComposeFile + service), added features (common-utils, github.cli, claude-code), removed containerEnv and legacy mounts, updated postCreateCommand to set git safe.directory, restricted extensions to ms-vscode.powershell, adjusted PowerShell settings path and removed Linux terminal profiles.
Docker Compose service
.devcontainer/docker-compose.yml
Added devcontainer service using mcr.microsoft.com/powershell:ubuntu-24.04, declared workspace and Claude/GH bind mounts, defined a persistent gh-cli-config volume, and runs a long-lived command (sleep infinity) so VS Code can attach.
Host setup script
.devcontainer/setup-host.ps1
Added host-side initializer that detects host home and workspace paths, normalizes path separators for cross-platform mounts, writes .devcontainer/.env with CLAUDE_HOST_HOME, LOCAL_WORKSPACE_FOLDER, and LOCAL_WORKSPACE_FOLDER_BASENAME for docker-compose interpolation.
Gitignore update
.gitignore
Added .devcontainer/.env to ignore the host-generated env file.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Host as Host (dev machine)
participant Setup as setup-host.ps1
participant Compose as docker-compose
participant Container as devcontainer (image)
participant VSCode as VS Code
Host->>Setup: run .devcontainer/setup-host.ps1
Setup-->>Host: write .devcontainer/.env
Host->>Compose: docker compose up (uses .env)
Compose->>Container: start mcr.microsoft.com/powershell:ubuntu-24.04
Container->>Container: mount workspace, gh-cli-config, claude paths
Container-->>Compose: container running (sleep infinity)
VSCode->>Container: attach to devcontainer

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I nudged the Dockerfile out of sight,
Wrote envs on the host by morning light.
An image hums, volumes tucked in tight,
VS Code hops in — everything's right.
Small paws, big changes, and a joyful bite.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: replacing a custom Dockerfile with feature-based devcontainer configuration, which is reflected across all modified files (Dockerfile removal, devcontainer.json updates with features, docker-compose addition).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch devcontainer-cleanup

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @.devcontainer/devcontainer.json:
- Line 17: The mount in the devcontainer bind string uses ${localEnv:APPDATA}/gh
which is the wrong Windows folder; update the source portion of the bind entry
(the string shown in the diff) to point to the GitHub CLI default folder by
replacing "${localEnv:APPDATA}/gh" with "${localEnv:APPDATA}/GitHub CLI" so the
container mounts the correct Windows config directory and commands like `gh auth
status` work inside the container.
- Line 21: The postCreateCommand currently runs "Install-Module -Name Pester
-Force -SkipPublisherCheck" which relies on implicit scope resolution; update
the command referenced by postCreateCommand to explicitly add "-Scope
CurrentUser" to the Install-Module invocation so Pester is installed for the
vscode/non-elevated user reliably across PowerShellGet versions.

Comment thread .devcontainer/devcontainer.json Outdated
Comment thread .devcontainer/devcontainer.json Outdated
Copy link
Copy Markdown

Copilot AI left a comment

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 refactors the devcontainer configuration to use official devcontainer features instead of a custom Dockerfile, aiming to simplify the setup for Claude Code and PowerShell development.

Changes:

  • Replaced custom 58-line Dockerfile with official devcontainer features (common-utils, github-cli, claude-code)
  • Switched from PowerShell LTS Ubuntu 22.04 to PowerShell 7.5 Ubuntu 24.04 base image
  • Added host config mounts for GitHub CLI and Claude authentication

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
.devcontainer/devcontainer.json Complete refactor to use features-based configuration with simplified setup and new host config mounts
.devcontainer/Dockerfile Removed custom Dockerfile in favor of devcontainer features

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

Comment thread .devcontainer/devcontainer.json Outdated
Comment thread .devcontainer/devcontainer.json Outdated
Comment thread .devcontainer/devcontainer.json
Comment thread .devcontainer/devcontainer.json Outdated
Comment thread .devcontainer/devcontainer.json Outdated
Comment thread .devcontainer/devcontainer.json Outdated
@tablackburn tablackburn force-pushed the devcontainer-cleanup branch 3 times, most recently from 6e5e3d6 to f50388b Compare February 4, 2026 01:23
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @.devcontainer/devcontainer.json:
- Around line 18-19: The devcontainer mount uses the Windows-only environment
variable ${localEnv:USERPROFILE}, which will be empty on macOS/Linux and cause
Docker mount failures; update .devcontainer/devcontainer.json to avoid directly
concatenating HOME and USERPROFILE and instead implement a cross-platform
approach: either document this as Windows-only, or replace the static mount
entries with a conditional solution such as adding an initializeCommand that
detects the host OS and sets a DEV_CONTAINER_CLAUDE_PATH (or similar) env var
before mounts are evaluated, or move the bind logic into a devcontainer feature
or init script that only creates the bind/mount when the resolved host path is
non-empty; reference the existing mount lines using ${localEnv:USERPROFILE} and
${localEnv:HOME} when making the conditional logic so the change targets those
exact variables.

Comment thread .devcontainer/devcontainer.json Outdated
Replace custom Dockerfile with feature-based approach:
- Use official ghcr.io/anthropics/devcontainer-features/claude-code
- Mount host Claude and GitHub CLI configs for seamless auth
- Simplify to PowerShell 7.5 base image with devcontainer features

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @.devcontainer/devcontainer.json:
- Around line 2-3: The devcontainer "image" entry currently uses the
non-existent tag "mcr.microsoft.com/powershell:7-ubuntu-24.04"; update the
"image" property value to a valid PowerShell tag such as
"mcr.microsoft.com/powershell:7-ubuntu-22.04" or
"mcr.microsoft.com/powershell:latest" so the container can be pulled
successfully, leaving the rest of .devcontainer/devcontainer.json unchanged.

Comment thread .devcontainer/devcontainer.json Outdated
Replace Windows-only ${localEnv:USERPROFILE} mounts with a Docker
Compose approach that works on Windows, macOS, and Linux. An
initializeCommand runs setup-host.ps1 to detect the host home
directory (USERPROFILE or HOME) and writes a .env file that Docker
Compose uses for volume mount variable substitution.

Also updates the PowerShell base image tag from the non-existent
7-ubuntu-24.04 to the floating ubuntu-24.04 tag, and adds a git
safe.directory config for the bind-mounted workspace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @.devcontainer/docker-compose.yml:
- Line 8: The docker-compose entry uses the named volume gh-cli-config which
prevents host GitHub CLI credentials from being shared into the container;
either replace the named volume gh-cli-config with a bind mount of the host GH
CLI config (e.g. host ~/.config/gh -> container /home/vscode/.config/gh) if you
want host auth available, or keep the named volume but update docs/README to
state users must run gh auth login inside the devcontainer; locate the volume
reference gh-cli-config in the .devcontainer docker-compose service and change
to a bind mount or add documentation accordingly.

In @.devcontainer/setup-host.ps1:
- Around line 21-28: The .env values written via the $envContent here-string are
unquoted which breaks docker-compose when paths contain spaces; update the
$envContent generation (the here-string assigned to $envContent) to wrap each
variable value in quotes (e.g., CLAUDE_HOST_HOME="...") and ensure any internal
double quotes in $claudeHome/$workspace/$workspaceName are escaped before
writing, then continue to write to $envPath with Set-Content as before.
🧹 Nitpick comments (1)
.devcontainer/devcontainer.json (1)

6-6: initializeCommand requires pwsh on the host machine.

This command runs before the container is created, so the host must have PowerShell 7+ (pwsh) installed. Since this is a PowerShell module template, that's a reasonable assumption — but contributors on a Linux/macOS machine without pwsh will get an opaque error. Consider adding a note in the repo README or a fallback.

Comment thread .devcontainer/docker-compose.yml
Comment thread .devcontainer/setup-host.ps1
tablackburn and others added 2 commits February 6, 2026 22:07
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Drop powershell.codeFormatting.preset to use the default, remove
gitlens and editorconfig from recommended extensions (no .editorconfig
file exists in the repo).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tablackburn tablackburn changed the title refactor: Use official Anthropic devcontainer feature for Claude Code refactor: Replace custom Dockerfile with feature-based devcontainer Feb 7, 2026
@tablackburn tablackburn merged commit 009efce into main Feb 7, 2026
3 checks passed
@tablackburn tablackburn deleted the devcontainer-cleanup branch February 7, 2026 03:33
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.

2 participants