Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,8 @@ FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04
# hadolint ignore=DL3008
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends \
curl \
wget \
jq \
build-essential \
python3 \
python3-venv \
python3-pip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

RUN mkdir -p /home/vscode/.ssh \
&& chown -R vscode:vscode /home/vscode \
&& chmod 700 /home/vscode/.ssh
24 changes: 6 additions & 18 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,40 @@
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"features": {
"ghcr.io/devcontainers/features/common-utils:2": {
"installZsh": true,
"installZsh": false,
"installOhMyZsh": false,
"configureZshAsDefaultShell": false,
"username": "vscode",
"upgradePackages": false
},
"ghcr.io/devcontainers/features/git:1": {
"version": "os-provided",
"ppa": false
},
"ghcr.io/devcontainers/features/node:1": {
"version": "lts",
"nodeGypDependencies": false,
"installYarnUsingApt": false
},
"ghcr.io/devcontainers/features/docker-in-docker:2": {
"version": "latest",
"moby": true,
"dockerDashComposeVersion": "v2"
},
"ghcr.io/devcontainers/features/github-cli:1": {
"version": "latest"
},
"ghcr.io/devcontainers/features/sshd:1": {
"version": "latest"
}
},
"customizations": {
"vscode": {
"extensions": [
"ms-azuretools.vscode-docker",
"github.copilot",
"github.copilot-chat",
"redhat.vscode-yaml",
"ms-python.python",
"ms-python.vscode-pylance",
"anthropic.claude-code"
"ms-python.vscode-pylance"
],
"settings": {
"editor.formatOnSave": true,
"editor.rulers": [80, 120],
"terminal.integrated.defaultProfile.linux": "zsh",
"files.trimTrailingWhitespace": true,
"editor.bracketPairColorization.enabled": true,
"editor.guides.bracketPairs": true
}
}
},
"postCreateCommand": "npm install -g @anthropic-ai/claude-code opencode-ai && python3 --version && node --version && docker --version && gh --version && claude --version && opencode --version && echo 'Development environment ready'",
"updateContentCommand": "npm install -g opencode-ai",
"postCreateCommand": "opencode --version && echo 'Development environment ready'",
"remoteUser": "vscode"
}
14 changes: 4 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Test devcontainer functionality
uses: devcontainers/ci@v0.3
Expand All @@ -51,19 +49,15 @@ jobs:
runCmd: |
# Test basic tools are available
which python3 || echo "python3 is missing"
which pip3 || echo "pip3 is missing"
which docker || echo "docker is missing"
which gh || echo "gh is missing"
which node || echo "node is missing"
which npm || echo "npm is missing"
which claude || echo "claude is missing"
which gh || echo "gh is missing"
which opencode || echo "opencode is missing"
# Test essential packages
python3 --version
node --version
docker --version
npm --version
gh --version
claude --version
opencode --version
curl --version
jq --version
curl --version | head -1
jq --version
70 changes: 43 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,54 @@ Codespaces and local VS Code Dev Containers.
- Core tooling for general development work:
- Python 3 with `venv` and `pip`
- Node.js LTS with `npm`
- Docker-in-Docker with Docker Compose v2
- GitHub CLI
- Claude Code CLI installed in `postCreateCommand`
- OpenCode TUI installed in `postCreateCommand`
- Zsh and common shell utilities
- Build essentials (`gcc`, `make`, and related packages)
- SSH daemon support via the devcontainer feature
- OpenCode TUI installed via `updateContentCommand` (cached by prebuilds)
- Bash shell with common utilities
- Build essentials (`gcc`, `make`, and related packages) via base image
- VS Code extensions:
- Anthropic Claude Code
- Python and Pylance
- Docker
- GitHub Copilot and Copilot Chat
- YAML

## Performance Optimizations

The devcontainer balances speed with operability:
The devcontainer is tuned for fast Codespaces startup:

- Keeps the image focused on core development tooling
- Avoids full package upgrades during image build to reduce rebuild time
- Uses the devcontainer feature set for Node.js, Git, Docker, GitHub CLI, and SSH
- Uses Ubuntu's packaged Python runtime for a faster base setup
- Installs Claude Code CLI and OpenCode TUI in `postCreateCommand` instead of baking them into the image
- Limits editor customizations to a small, broadly useful extension set
- Minimal feature set: only `common-utils`, `node`, and `github-cli` features
are installed — Docker-in-Docker, sshd, and git features are omitted
- `common-utils` configured with zsh and Oh My Zsh disabled
- No full package upgrades during image build
- `curl`, `wget`, `jq`, and `git` sourced from the base image and
`common-utils` feature — not re-installed in the Dockerfile
- OpenCode TUI installed in `updateContentCommand` instead of `postCreateCommand`,
so it is cached during Codespaces prebuilds and not re-run on every start
- Small, targeted extension set

Estimated startup time: 2-3 minutes, depending on feature downloads and
network speed.
Estimated startup time: **45–75 seconds** without prebuilds,
**10–25 seconds** with prebuilds enabled (see below).

## Speeding Up Codespaces with Prebuilds

Codespaces prebuilds cache the fully built container image, installed features,
and `updateContentCommand` output on GitHub's infrastructure. This is the
single biggest lever for fast cold-starts.

### How to enable

1. Navigate to the repository on GitHub.
2. Go to **Settings → Codespaces**.
3. Click **Set up prebuild configuration**.
4. Select the `main` branch and choose one or more regions closest to your
team.
5. Set the trigger to **"On every push"** (or "On configuration change" for
less frequent rebuilds).
6. Save.

The first prebuild takes roughly 3–5 minutes. After that, every new Codespace
created from `main` will start in approximately **10–25 seconds**.

> **Tip**: Prebuilds are available on GitHub Team and Enterprise plans, and are
> free for public repositories up to a certain storage quota.

## Usage

Expand All @@ -59,8 +80,8 @@ network speed.
## Repository Structure

- `.devcontainer/devcontainer.json`: main devcontainer definition, features,
VS Code extensions, and post-create validation command
- `.devcontainer/Dockerfile`: minimal image customization for extra packages
VS Code extensions, and lifecycle commands
- `.devcontainer/Dockerfile`: minimal image customization for Python packages
- `.github/workflows/ci.yml`: CI checks for Dockerfile linting, secret
scanning, image build, and devcontainer smoke testing

Expand All @@ -86,21 +107,16 @@ Edit `.devcontainer/devcontainer.json` to add features or tools:
"ghcr.io/devcontainers/features/java:1": {
"version": "17"
}
},
"postCreateCommand": "pip install -r requirements.txt"
}
}
```

To add heavier tooling when you actually need it:
To add Docker support when you need it:

```json
{
"features": {
"ghcr.io/devcontainers/features/kubectl-helm-minikube:1": {
"version": "latest",
"helm": "latest",
"minikube": "none"
}
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}
}
}
```
Expand Down
Loading