Skip to content

Commit 64d31b5

Browse files
committed
Add prebuilt devcontainer image support via GHCR
- Add CI workflow to build and publish devcontainer image to ghcr.io on changes to .devcontainer/ files (with PR validation builds) - Create .devcontainer/ci/ config for CI image builds with features baked in - Update devcontainer.json to pull prebuilt image instead of building locally (local build instructions preserved as comments) - Absorb claude-code feature runtime config (mount, extension) into devcontainer.json since features are pre-baked in the image - Add docker ecosystem to dependabot for base image update tracking https://claude.ai/code/session_01P15jZtANbd9QQm4SiY3Nzh
1 parent 03794b1 commit 64d31b5

4 files changed

Lines changed: 83 additions & 15 deletions

File tree

.devcontainer/ci/devcontainer.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "python_template-build",
3+
"build": {
4+
"dockerfile": "../Dockerfile",
5+
"context": "../.."
6+
},
7+
"features": {
8+
"../claude-code": {}
9+
}
10+
}

.devcontainer/devcontainer.json

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
{
22
"name": "python_template",
3-
"build": {
4-
"dockerfile": "Dockerfile",
5-
"context": ".."
6-
},
3+
4+
// Prebuilt image from GHCR (built by .github/workflows/devcontainer.yml)
5+
// Features (including claude-code) are baked into this image.
6+
"image": "ghcr.io/blooop/python_template/devcontainer:latest",
7+
8+
// To build locally instead of using the prebuilt image, comment out "image" above
9+
// and uncomment the "build" and "features" blocks below:
10+
// "build": {
11+
// "dockerfile": "Dockerfile",
12+
// "context": ".."
13+
// },
14+
// "features": {
15+
// "./claude-code": {}
16+
// },
17+
718
"initializeCommand": ".devcontainer/claude-code/init-host.sh",
819
"customizations": {
920
"vscode": {
@@ -14,17 +25,10 @@
1425
"jjjermiah.pixi-vscode",
1526
"charliermarsh.ruff",
1627
"tamasfe.even-better-toml",
17-
"mhutchie.git-graph"
18-
]
28+
"mhutchie.git-graph",
29+
"anthropic.claude-code"
30+
]
1931
}
20-
},
21-
"features": {
22-
"./claude-code": {}
23-
24-
// "ghcr.io/devcontainers/features/docker-in-docker:2": {}
25-
// "ghcr.io/devcontainers/features/common-utils:2": {},
26-
// "ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {},
27-
// "ghcr.io/jsburckhardt/devcontainer-features/codex:latest": {}
2832
},
2933
"runArgs": [
3034
"--network=host"
@@ -39,7 +43,8 @@
3943
"mounts": [
4044
"source=${localWorkspaceFolderBasename}-pixi,target=${containerWorkspaceFolder}/.pixi,type=volume",
4145
"source=${localEnv:HOME}/.ssh,target=/home/vscode/.ssh,type=bind",
42-
"source=${localEnv:HOME}/.config/gh,target=/home/vscode/.config/gh,type=bind"
46+
"source=${localEnv:HOME}/.config/gh,target=/home/vscode/.config/gh,type=bind",
47+
"source=${localEnv:HOME}/.claude,target=/home/vscode/.claude,type=bind"
4348
],
4449
"postCreateCommand": "sudo chown vscode .pixi && pixi install"
4550
}

.github/dependabot.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ updates:
2525
#try to group all third party library updates into a single pr
2626
patterns:
2727
- "*"
28+
- package-ecosystem: "docker"
29+
directory: "/.devcontainer"
30+
schedule:
31+
interval: "monthly"
2832
- package-ecosystem: github-actions
2933
directory: /
3034
schedule:

.github/workflows/devcontainer.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Devcontainer Image
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
paths:
7+
- ".devcontainer/**"
8+
- ".github/workflows/devcontainer.yml"
9+
pull_request:
10+
branches: ["main"]
11+
paths:
12+
- ".devcontainer/**"
13+
- ".github/workflows/devcontainer.yml"
14+
workflow_dispatch:
15+
16+
permissions:
17+
contents: read
18+
packages: write
19+
20+
jobs:
21+
build-and-push:
22+
runs-on: ubuntu-latest
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v4
26+
27+
- name: Log in to GHCR
28+
uses: docker/login-action@v3
29+
with:
30+
registry: ghcr.io
31+
username: ${{ github.actor }}
32+
password: ${{ secrets.GITHUB_TOKEN }}
33+
34+
- name: Set image metadata
35+
id: meta
36+
run: |
37+
SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7)
38+
DATE=$(date +%Y-%m-%d)
39+
echo "short_sha=$SHORT_SHA" >> "$GITHUB_OUTPUT"
40+
echo "date=$DATE" >> "$GITHUB_OUTPUT"
41+
42+
- name: Build and push devcontainer image
43+
uses: devcontainers/ci@v0.3
44+
with:
45+
configFile: .devcontainer/ci/devcontainer.json
46+
imageName: ghcr.io/${{ github.repository }}/devcontainer
47+
imageTag: latest,sha-${{ steps.meta.outputs.short_sha }},${{ steps.meta.outputs.date }}
48+
cacheFrom: ghcr.io/${{ github.repository }}/devcontainer:latest
49+
push: ${{ github.event_name != 'pull_request' && 'always' || 'never' }}

0 commit comments

Comments
 (0)