|
1 | 1 | { |
2 | | - "name": "python_template", |
3 | | - |
4 | 2 | // Uses the template's prebuilt image by default for fast startup. |
5 | 3 | // To build locally: pixi run dev-use-local |
6 | 4 | // To use this repo's own prebuilt image: pixi run dev-use-prebuilt |
|
10 | 8 | // }, |
11 | 9 | "image": "ghcr.io/blooop/python_template/devcontainer:latest", |
12 | 10 |
|
13 | | - "features": { |
14 | | - "./claude-code": {}, |
15 | | - // "ghcr.io/devcontainers/features/docker-in-docker:2": {}, |
16 | | - // "ghcr.io/devcontainers/features/common-utils:2": {} |
17 | | - }, |
| 11 | + // There is deliberately no "features" block. The claude-code feature is |
| 12 | + // already baked into the image above: .devcontainer/ci/devcontainer.json, |
| 13 | + // which is the config CI builds that image from, declares |
| 14 | + // "../claude-code". Declaring it again here made the devcontainer spec |
| 15 | + // build a derived image on the first launch of every branch, reinstalling |
| 16 | + // something the pulled image already carried -- so the "prebuilt image for |
| 17 | + // fast startup" above still paid for a build. With this block gone the |
| 18 | + // launch is a pull and nothing else. |
| 19 | + // |
| 20 | + // Adding a feature back here is allowed and costs that derived build again. |
| 21 | + // If that ever becomes the normal case, the fix is devlaunch's design -- |
| 22 | + // a "build:" block plus customizations.devpod.prebuildRepository, which |
| 23 | + // caches the fully assembled image, features included. That needs CI to |
| 24 | + // publish with `devpod build` rather than the devcontainers/ci action; |
| 25 | + // devpod's prebuild hash is computed from the Dockerfile and build context, |
| 26 | + // so it does not apply to an "image:" config like this one at all. |
18 | 27 |
|
19 | 28 | "initializeCommand": ".devcontainer/claude-code/init-host.sh", |
| 29 | + |
| 30 | + // There is deliberately no "runArgs": ["--network=host"]. |
| 31 | + // |
| 32 | + // A container per branch is the reason these repos are launched with `dl`, |
| 33 | + // and host networking takes it away: the container joins the host's network |
| 34 | + // namespace, so every port a test or dev server binds is a host port and |
| 35 | + // two branches of this repo collide on the first one they share. The |
| 36 | + // default bridge network keeps them apart at no cost -- nothing in this |
| 37 | + // template reaches for the host's network. |
| 38 | + // |
| 39 | + // Two sibling repos keep the flag on purpose and should not be "fixed" to |
| 40 | + // match this file: homeassistant-config (mDNS/discovery needs the host LAN) |
| 41 | + // and colcon-runner (ROS 2 DDS multicast discovery). |
| 42 | + |
20 | 43 | "customizations": { |
21 | 44 | "vscode": { |
22 | 45 | "settings": {}, |
|
31 | 54 | ] |
32 | 55 | } |
33 | 56 | }, |
34 | | - "runArgs": [ |
35 | | - "--network=host" |
36 | | - ], |
| 57 | + |
37 | 58 | "containerEnv": { |
38 | 59 | "CLAUDE_CONFIG_DIR": "/home/vscode/.claude", |
39 | 60 | "XDG_CONFIG_HOME": "/home/vscode/.config", |
40 | 61 | "XDG_CACHE_HOME": "/home/vscode/.cache", |
41 | | - "XDG_DATA_HOME": "/home/vscode/.local/share", |
42 | | - "SSH_AUTH_SOCK": "/home/vscode/.ssh/agent.sock" |
| 62 | + "XDG_DATA_HOME": "/home/vscode/.local/share" |
43 | 63 | }, |
| 64 | + |
| 65 | + // Two mounts, and the two that are gone were removed for reasons rather |
| 66 | + // than tidiness -- both follow the precedent already reasoned out in |
| 67 | + // blooop/wayfinder's devcontainer.json. |
| 68 | + // |
| 69 | + // ~/.config/gh is gone because it never worked: `gh` keeps its token in the |
| 70 | + // system keyring, so the mounted hosts.yml carries no oauth_token and |
| 71 | + // `gh auth status` inside the container reports the token as invalid. |
| 72 | + // GitHub auth arrives as GH_TOKEN instead, which `dl` forwards into every |
| 73 | + // workspace it starts (from GH_TOKEN, GITHUB_TOKEN or `gh auth token`, |
| 74 | + // whichever answers first). Opened by something other than `dl` -- a plain |
| 75 | + // `devpod up`, or VS Code's Reopen in Container -- this container has no |
| 76 | + // `gh` login; export GH_TOKEN yourself for those. |
| 77 | + // |
| 78 | + // ~/.ssh is gone because mounting the directory put entries on the |
| 79 | + // developer's real config that nothing outside the container could honour: |
| 80 | + // devpod running in here writes `Host <id>.devpod` blocks whose |
| 81 | + // ProxyCommand names a binary that exists only inside this container, and |
| 82 | + // those outlived the container they pointed at. It also handed over the |
| 83 | + // private key, which was never load-bearing -- devpod forwards git |
| 84 | + // credentials and can forward an ssh agent, which lends the use of a key |
| 85 | + // without copying it. SSH_AUTH_SOCK is gone from containerEnv with it, |
| 86 | + // rather than being left as a path nothing fills. |
44 | 87 | "mounts": [ |
45 | 88 | "source=${localWorkspaceFolderBasename}-pixi,target=${containerWorkspaceFolder}/.pixi,type=volume", |
46 | | - "source=${localEnv:HOME}/.ssh,target=/home/vscode/.ssh,type=bind", |
47 | | - "source=${localEnv:HOME}/.config/gh,target=/home/vscode/.config/gh,type=bind", |
48 | 89 | "source=${localEnv:HOME}/.claude,target=/home/vscode/.claude,type=bind" |
49 | 90 | ], |
50 | | - "postCreateCommand": "sudo chown vscode .pixi && pixi install && pixi run prek-install" |
| 91 | + |
| 92 | + "postCreateCommand": "sudo chown vscode .pixi && pixi install && pixi run prek-install", |
| 93 | + |
| 94 | + // Last in the file on purpose, and it is the one line here that is load |
| 95 | + // bearing for every repo cut from this template. |
| 96 | + // |
| 97 | + // "name" is the only per-repo value in this file, so it is the only line a |
| 98 | + // child repo edits -- and while it sat on the line above the image/build |
| 99 | + // block, which is the block this template changes most, every |
| 100 | + // `pixi run update-from-template-repo` conflicted on this file. git cannot |
| 101 | + // split adjacent hunks, so the child's one-line name edit collided with the |
| 102 | + // template's block edit every time. Measured against blooop/dbw: reverting |
| 103 | + // only the name made the same merge clean. |
| 104 | + // |
| 105 | + // At the end of the file the two edits are separate hunks and merge without |
| 106 | + // conflict -- the child keeps its name, and template changes to the image, |
| 107 | + // the mounts and postCreateCommand all land on their own. Moving it costs |
| 108 | + // one restructuring conflict per child, once; leaving it here costs a |
| 109 | + // conflict on this file forever. |
| 110 | + "name": "python_template" |
51 | 111 | } |
0 commit comments