Skip to content

Commit b345208

Browse files
chapterjasonclaude
andcommitted
Flatten to single-image Coder workspace template
Shift away from the nested "outer workspace runs @devcontainers/cli inside a devcontainer with its own sub-agent" model toward a flat one-container-per-workspace design. The workspace container IS the dev environment: one coder_agent, one HOME, one IDE target. Dev tooling is baked into stack-specific images at build time instead of installed at devcontainer-create time. Also repositions the repo from a devcontainer-features collection to a Coder workspace template. Renamed on GitHub to SoureCode/coder-workspaces. ## Workspace images - src/base/Dockerfile — shared foundation: debian:trixie-slim + systemd + dockerd (sysbox-runc runtime) + coder user + dev-kit scripts (nvm, claude-code, rtk, context-mode, web-shell, home-persist). - src/node/Dockerfile — FROM :base; named variant, no additions yet. - src/cpp/Dockerfile — FROM :base + llvm/cmake/sccache + CC/CXX env. - .github/workflows/publish-workspaces.yml — matrix build publishing ghcr.io/sourecode/coder-workspace:{base,node,cpp} (multi-arch). ## Scripts Moved src/<feature>/ → scripts/<name>/. Dropped devcontainer-feature.json files (no longer publishing features). Dropped "feature installer" / "<tool> feature:" wording in comments and error messages. Scripts are now bind-mounted into each Dockerfile at build via --mount=type=bind so their source never enters an image layer. Renamed manifest directory /etc/devcontainer-persist.d → /etc/home-persist.d across scripts, resolver, docs, main.tf. Dropped the build-time \$PATHS block from home-persist/install.sh (replaced by the runtime Coder parameter below). ## main.tf rewrite - data "coder_parameter" "workspace_image" dropdown (base/node/cpp). - data "coder_parameter" "home_persist_paths" for per-workspace extra persistence paths; lifecycle_init writes /etc/home-persist.d/user.json from it before running home-persist-resolve. - Dropped coder_devcontainer + subagent plumbing; every IDE module (code-server, jetbrains, git-clone) attaches to coder_agent.main.id. - Inlined terraform/web-shell module as a coder_app resource — scripts/web-shell/install.sh already installs + supervises via systemd, the module was duplicating that work and conflicting at runtime. - Dropped DEVCONTAINER_* env, rebuild_no_cache parameter + script. - coder_script.lifecycle_init orchestrates home-persist-resolve + context-mode/rtk post-create hooks on start with start_blocks_login=true. - Git identity (coder_env.git_*) + SSH signing (coder_script) moved from the old subagent onto coder_agent.main. ## Removed - Dockerfile.workspace (Ubuntu noble, nested dockerd, @devcontainers/cli) — fully ported into src/base/Dockerfile (Debian trixie, same patterns). - Dockerfile.devcontainer-base + publish-devcontainer-base.yml. - publish-features.yml — features no longer published to GHCR. - docs/migration-guide.md — devcontainer-migration-oriented, obsolete. - terraform/web-shell/ — duplicated scripts/web-shell/install.sh. - scripts/web-shell/README.md — feature-marketing doc, content in README. ## Docs README rewritten as a Coder workspace template with per-stack image matrix, sysbox host setup, push-to-Coder flow, troubleshooting. docs/persistence.md updated for the flat model (coder_script-driven resolver instead of onCreateCommand, new home_persist_paths parameter). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 8f75d5f commit b345208

36 files changed

Lines changed: 735 additions & 1678 deletions

.github/workflows/publish-devcontainer-base.yml

Lines changed: 0 additions & 56 deletions
This file was deleted.

.github/workflows/publish-features.yml

Lines changed: 0 additions & 34 deletions
This file was deleted.
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
name: Publish Workspace Images
2+
3+
on:
4+
push:
5+
branches: [master]
6+
paths:
7+
- "src/**"
8+
- "scripts/**"
9+
- ".github/workflows/publish-workspaces.yml"
10+
tags: ["v*"]
11+
workflow_dispatch:
12+
13+
jobs:
14+
base:
15+
runs-on: ubuntu-24.04
16+
permissions:
17+
contents: read
18+
packages: write
19+
outputs:
20+
short_sha: ${{ steps.sha.outputs.short }}
21+
steps:
22+
- uses: actions/checkout@v6
23+
24+
- name: Compute short sha
25+
id: sha
26+
run: echo "short=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"
27+
28+
- name: Lowercase image name
29+
id: img
30+
run: echo "name=ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/coder-workspace" >> "$GITHUB_OUTPUT"
31+
32+
- uses: docker/setup-qemu-action@v4
33+
- uses: docker/setup-buildx-action@v4
34+
35+
- name: Log in to GHCR
36+
uses: docker/login-action@v4
37+
with:
38+
registry: ghcr.io
39+
username: ${{ github.actor }}
40+
password: ${{ secrets.GITHUB_TOKEN }}
41+
42+
- name: Extract tags
43+
id: meta
44+
uses: docker/metadata-action@v6
45+
with:
46+
images: ${{ steps.img.outputs.name }}
47+
tags: |
48+
type=raw,value=base
49+
type=sha,format=short,prefix=base-
50+
51+
- name: Build and push
52+
uses: docker/build-push-action@v7
53+
with:
54+
context: .
55+
file: ./src/base/Dockerfile
56+
platforms: linux/amd64,linux/arm64
57+
push: true
58+
tags: ${{ steps.meta.outputs.tags }}
59+
labels: ${{ steps.meta.outputs.labels }}
60+
cache-from: type=gha,scope=workspace-base
61+
cache-to: type=gha,mode=max,scope=workspace-base
62+
63+
stacks:
64+
needs: base
65+
runs-on: ubuntu-24.04
66+
permissions:
67+
contents: read
68+
packages: write
69+
strategy:
70+
fail-fast: false
71+
matrix:
72+
stack: [node, cpp]
73+
steps:
74+
- uses: actions/checkout@v6
75+
76+
- name: Lowercase image name
77+
id: img
78+
run: echo "name=ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/coder-workspace" >> "$GITHUB_OUTPUT"
79+
80+
- uses: docker/setup-qemu-action@v4
81+
- uses: docker/setup-buildx-action@v4
82+
83+
- name: Log in to GHCR
84+
uses: docker/login-action@v4
85+
with:
86+
registry: ghcr.io
87+
username: ${{ github.actor }}
88+
password: ${{ secrets.GITHUB_TOKEN }}
89+
90+
- name: Extract tags
91+
id: meta
92+
uses: docker/metadata-action@v6
93+
with:
94+
images: ${{ steps.img.outputs.name }}
95+
tags: |
96+
type=raw,value=${{ matrix.stack }}
97+
type=sha,format=short,prefix=${{ matrix.stack }}-
98+
99+
- name: Build and push
100+
uses: docker/build-push-action@v7
101+
with:
102+
context: .
103+
file: ./src/${{ matrix.stack }}/Dockerfile
104+
platforms: linux/amd64,linux/arm64
105+
push: true
106+
tags: ${{ steps.meta.outputs.tags }}
107+
labels: ${{ steps.meta.outputs.labels }}
108+
build-args: |
109+
BASE_IMAGE=${{ steps.img.outputs.name }}:base-${{ needs.base.outputs.short_sha }}
110+
cache-from: type=gha,scope=workspace-${{ matrix.stack }}
111+
cache-to: type=gha,mode=max,scope=workspace-${{ matrix.stack }}

Dockerfile.devcontainer-base

Lines changed: 0 additions & 37 deletions
This file was deleted.

Dockerfile.workspace

Lines changed: 0 additions & 142 deletions
This file was deleted.

0 commit comments

Comments
 (0)