The Problem

VS Code are the cleanest way to give every contributor on a project an identical environment — same OS, same tool versions, same shell. But that consistency comes at a cost: the first time anyone opens the project, VS Code has to build the container image from scratch. Installing an OS base layer, a language runtime, a shell, and any AI tooling on top of it can take several minutes, and it happens again on every cache-busting change to the Dockerfile.

For teams that also rely on Claude Code inside the container, there's a second layer of friction: getting authentication, shell history, and npm caches to survive a container rebuild requires the same boilerplate devcontainer.json in every repository.

How It Solves It

nerdy-pro-dev-container is a prebuilt, Docker image published to GitHub . Instead of building a dev container image per project, a repository points its devcontainer.json at the published image and VS Code pulls it directly — no build step, no waiting.

The image bundles everything a Node.js-based project needs to start working immediately:

  • Ubuntu 26.04 base (Microsoft's official devcontainers/base image)
  • Node.js LTS, installed via NodeSource
  • Claude Code, installed globally via npm
  • zsh with oh-my-zsh, configured with the git and fzf plugins as the default login shell
  • Common CLI tools — git, curl, wget, jq, gpg, OpenSSH client, fzf
  • Passwordless sudo for the vscode user

It's built for both linux/amd64 and linux/arm64, so the same tag works on Intel/AMD machines and Apple Silicon.

Persistence Across Rebuilds

A container that gets rebuilt on every Dockerfile change is only convenient if state doesn't reset with it. The template wires up four named Docker volumes so nothing is lost between rebuilds:

  • Claude Code configuration and session data (.claude directory, via CLAUDE_CONFIG_DIR)
  • zsh command history (HISTFILE on a persistent volume)
  • npm package cache
  • SSH known_hosts, so git host trust doesn't need re-establishing every time

Git authentication forwards the host's SSH agent into the container, and the host's gitconfig is propagated automatically — commits made inside the container carry the right author identity without any manual setup.

Getting Started

Copy the template into .devcontainer/devcontainer.json:

{
  "name": "my-project",
  "image": "ghcr.io/nerdy-pro/nerdy-pro-dev-container:latest"
}

Reopen the project in a dev container, and Node.js, zsh, and Claude Code are ready with no build step.

Authenticating Claude Code

Claude Code inside the container reads a CLAUDE_CODE_OAUTH_TOKEN environment variable rather than going through an interactive login. Generate a long-lived token on the host with:

claude setup-token

Store it in the host's credential manager — Keychain on macOS, the desktop keyring (secret-tool) on Linux, or DPAPI on Windows — and forward it into the container with a remoteEnv entry in devcontainer.json, so it never has to be typed inside the container itself.

First git operation

The first push or fetch inside a fresh container prompts for host key verification in the terminal — a one-time confirmation that establishes SSH trust for that git host, after which it's cached in the persistent known_hosts volume.

Versioning and Releases

Images are built and published only from GitHub releases, not from every commit — a Dockerfile change on main doesn't affect anyone until a release is cut. Each release publishes four tags:

TagBehavior
1.0.0Pinned — never changes
1.0Updates on patch releases
1Updates on minor and patch releases
latestAlways the newest stable release

That range lets a project pin to an exact version for reproducibility, or track latest to stay current automatically.

License

The Dockerfile, the devcontainer.json template, and the documentation are MIT licensed. Everything installed on top of the base image — Ubuntu, Node.js, zsh, fzf, Claude Code — keeps its own original license.

It's a prebuilt, multi-architecture Docker image for VS Code Dev Containers that bundles Node.js LTS, zsh, and Claude Code, published to GitHub Container Registry as ghcr.io/nerdy-pro/nerdy-pro-dev-container. A project points its devcontainer.json at that image and skips the build step entirely.
No. The image is published to GitHub Container Registry and pulled directly by VS Code. Pointing devcontainer.json at ghcr.io/nerdy-pro/nerdy-pro-dev-container:latest skips the build step entirely.
Ubuntu 26.04, Node.js LTS, Claude Code, zsh with oh-my-zsh (git and fzf plugins), and common CLI tools including git, curl, wget, jq, gpg, and an OpenSSH client.

Run claude setup-token on the host to generate a long-lived token, store it in the host's credential manager, and forward it into the container as the CLAUDE_CODE_OAUTH_TOKEN environment variable via devcontainer.json's remoteEnv.

Yes. Four Docker volumes persist Claude Code configuration, zsh history, the npm cache, and SSH known_hosts across rebuilds, so re-authentication and re-trust aren't needed every time.
The image is built for both linux/amd64 and linux/arm64, so the same tag runs on Intel/AMD machines and Apple Silicon.
Images are published only from GitHub releases. Each release creates four tags — an exact version like 1.0.0, a minor version like 1.0, a major version like 1, and latest — so a project can pin to a specific version or track the newest stable release.