This document details the construction of the development container base image, including the selection of the Node.js base image, installation of system packages, shell environment configuration, and Claude Code application setup. This page covers the contents of the Dockerfile and the tooling installed within the container. For information about the network security configuration applied during container initialization, see Network Security & Firewall. For the overall DevContainer configuration and lifecycle management, see DevContainer Configuration.
Sources: .devcontainer/Dockerfile1-92
The development container is built from the official node:20 Docker image, providing the Node.js runtime required for Claude Code execution. The build process accepts several arguments for customization:
| Build Argument | Default | Purpose |
|---|---|---|
CLAUDE_CODE_VERSION | latest | Specifies which version of @anthropic-ai/claude-code to install |
TZ | (none) | Sets the container timezone |
GIT_DELTA_VERSION | 0.18.2 | Version of git-delta to install |
ZSH_IN_DOCKER_VERSION | 1.2.0 | Version of zsh-in-docker installer |
USERNAME | node | Non-root user for development |
The CLAUDE_CODE_VERSION argument allows pinning to specific releases or using the latest tag for development purposes.
Sources: .devcontainer/Dockerfile1-6 .devcontainer/Dockerfile34 .devcontainer/Dockerfile51 .devcontainer/Dockerfile72
Diagram: Dockerfile Build Sequence
The Dockerfile constructs the container environment through a series of sequential stages, each building upon the previous layer. The process begins with base image setup, proceeds through system package installation, configures the user environment, and concludes with Claude Code installation and security script setup.
Sources: .devcontainer/Dockerfile1-92
The container installs a comprehensive set of system packages via apt-get, organized by functional category:
| Category | Packages | Purpose |
|---|---|---|
| Core Utilities | less, procps, sudo, man-db, unzip | Basic system utilities for process management and file operations |
| Version Control | git, gh | Git version control and GitHub CLI for repository operations |
| Shell Enhancements | zsh, fzf | Enhanced shell with fuzzy finder for improved developer experience |
| Text Editors | nano, vim | Command-line text editors for file editing |
| Network Tools | iptables, ipset, iproute2, dnsutils | Network firewall management and DNS utilities |
| Data Processing | jq, aggregate | JSON processing and IP aggregation tools |
| Security | gnupg2 | GPG encryption utilities |
The --no-install-recommends flag minimizes image size by installing only essential package dependencies. Package lists are cleaned via apt-get clean && rm -rf /var/lib/apt/lists/* to reduce the final image size.
Sources: .devcontainer/Dockerfile9-28
Diagram: Container Directory Structure
The container creates several key directories with specific ownership and purposes:
| Directory | Owner | Purpose |
|---|---|---|
/usr/local/share/npm-global | node:node | npm global package installation directory |
/commandhistory | node | Persistent shell history storage |
/commandhistory/.bash_history | node | Bash history file |
/workspace | node:node | Source code workspace (mounted from host) |
/home/node/.claude | node:node | Claude Code configuration directory |
All directories are owned by the node user to ensure the non-root development environment can write to necessary locations. The /commandhistory directory is typically mounted as a persistent volume by the DevContainer configuration.
Sources: .devcontainer/Dockerfile31-32 .devcontainer/Dockerfile37-40 .devcontainer/Dockerfile46-47
The container follows Docker best practices by running processes as the non-root node user:
Diagram: User Transition and npm Configuration
The build process performs operations as root until line 58, then switches to the node user for all subsequent operations. This includes:
NPM_CONFIG_PREFIX environment variable points to /usr/local/share/npm-global .devcontainer/Dockerfile61PATH .devcontainer/Dockerfile62node user receives passwordless sudo access specifically for /usr/local/bin/init-firewall.sh .devcontainer/Dockerfile89-90This configuration allows the node user to install global npm packages and execute the firewall initialization script without requiring root privileges for normal development operations.
Sources: .devcontainer/Dockerfile58 .devcontainer/Dockerfile61-62 .devcontainer/Dockerfile87-91
The container configures zsh as the default shell with enhanced capabilities:
| Environment Variable | Value | Purpose |
|---|---|---|
SHELL | /bin/zsh | Default shell for interactive sessions |
EDITOR | nano | Default text editor for command-line operations |
VISUAL | nano | Visual editor for full-screen editing |
DEVCONTAINER | true | Flag indicating execution within DevContainer |
Sources: .devcontainer/Dockerfile43 .devcontainer/Dockerfile65 .devcontainer/Dockerfile68-69
The zsh-in-docker installation script (version 1.2.0) configures an enhanced zsh environment with plugins and custom configuration:
Diagram: zsh-in-docker Configuration Parameters
The installation script is invoked with the following parameters:
-p git: Installs git plugin for repository awareness-p fzf: Installs fuzzy finder plugin for interactive searching-a "source /usr/share/doc/fzf/examples/key-bindings.zsh": Adds fzf key bindings-a "source /usr/share/doc/fzf/examples/completion.zsh": Adds fzf completion support-a "export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history": Configures persistent history-x: Skips powerlevel10k theme installation for faster buildsThe persistent history configuration ensures that shell history is written immediately (history -a) and stored in the mounted /commandhistory directory.
Sources: .devcontainer/Dockerfile72-79
The container installs git-delta version 0.18.2, a syntax-highlighting pager for git, diff, and grep output. The installation process uses architecture detection to download the appropriate Debian package:
Diagram: git-delta Installation Process
The installation dynamically selects the correct architecture (e.g., amd64, arm64) and downloads the corresponding .deb package from the GitHub releases page. The package file is removed after installation to minimize image size.
Sources: .devcontainer/Dockerfile51-55
The Claude Code application is installed globally via npm as the final step of the user-space configuration:
Key aspects of this installation:
-g flag installs Claude Code globally, making the claude-code executable available in the PATH${CLAUDE_CODE_VERSION} build argument allows pinning to specific versions or using latest/usr/local/share/npm-global due to the NPM_CONFIG_PREFIX configurationnode user, ensuring appropriate permissionsThe installed executable becomes available at /usr/local/share/npm-global/bin/claude-code, which is accessible via the modified PATH.
Sources: .devcontainer/Dockerfile82 .devcontainer/Dockerfile61-62
The final build stage copies the init-firewall.sh script into the container and configures sudo access:
Diagram: Firewall Script Setup Sequence
The setup process:
init-firewall.sh from the build context to /usr/local/bin/root user for permission configurationchmod +xnode user to execute the script without a password0440 (read-only for root and sudo group)node user for the final container stateThe sudoers configuration allows the DevContainer's postStartCommand to execute the firewall initialization script with elevated privileges. For details on the firewall rules and network security implementation, see Network Security & Firewall.
Sources: .devcontainer/Dockerfile86-91
The final container environment includes these key variables:
| Variable | Value | Source |
|---|---|---|
TZ | Build argument | .devcontainer/Dockerfile4 |
DEVCONTAINER | true | .devcontainer/Dockerfile43 |
NPM_CONFIG_PREFIX | /usr/local/share/npm-global | .devcontainer/Dockerfile61 |
PATH | $PATH:/usr/local/share/npm-global/bin | .devcontainer/Dockerfile62 |
SHELL | /bin/zsh | .devcontainer/Dockerfile65 |
EDITOR | nano | .devcontainer/Dockerfile68 |
VISUAL | nano | .devcontainer/Dockerfile69 |
These variables configure the container for Claude Code development with appropriate timezone handling, npm package management, shell environment, and text editor defaults.
Sources: .devcontainer/Dockerfile4 .devcontainer/Dockerfile43 .devcontainer/Dockerfile61-62 .devcontainer/Dockerfile65 .devcontainer/Dockerfile68-69
The Dockerfile follows several Docker best practices for optimal image size and build performance:
RUN statements with && operatorsapt-get clean && rm -rf /var/lib/apt/lists/* removes package manager metadata--no-install-recommends flag reduces unnecessary package installationThese practices result in a smaller final image size while maintaining all necessary development tooling.
Sources: .devcontainer/Dockerfile9-28 .devcontainer/Dockerfile52-55
Refresh this wiki