container-superposition 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/README.md +3 -1
  2. package/dist/scripts/init.js +24 -4
  3. package/dist/scripts/init.js.map +1 -1
  4. package/dist/tool/commands/adopt.d.ts +3 -2
  5. package/dist/tool/commands/adopt.d.ts.map +1 -1
  6. package/dist/tool/commands/adopt.js +378 -67
  7. package/dist/tool/commands/adopt.js.map +1 -1
  8. package/dist/tool/commands/doctor.d.ts +3 -0
  9. package/dist/tool/commands/doctor.d.ts.map +1 -1
  10. package/dist/tool/commands/doctor.js +932 -69
  11. package/dist/tool/commands/doctor.js.map +1 -1
  12. package/dist/tool/commands/explain.d.ts.map +1 -1
  13. package/dist/tool/commands/explain.js +9 -0
  14. package/dist/tool/commands/explain.js.map +1 -1
  15. package/dist/tool/questionnaire/composer.d.ts.map +1 -1
  16. package/dist/tool/questionnaire/composer.js +212 -11
  17. package/dist/tool/questionnaire/composer.js.map +1 -1
  18. package/dist/tool/schema/overlay-loader.d.ts.map +1 -1
  19. package/dist/tool/schema/overlay-loader.js +1 -0
  20. package/dist/tool/schema/overlay-loader.js.map +1 -1
  21. package/dist/tool/schema/project-config.d.ts +3 -1
  22. package/dist/tool/schema/project-config.d.ts.map +1 -1
  23. package/dist/tool/schema/project-config.js +164 -13
  24. package/dist/tool/schema/project-config.js.map +1 -1
  25. package/dist/tool/schema/types.d.ts +85 -11
  26. package/dist/tool/schema/types.d.ts.map +1 -1
  27. package/dist/tool/utils/merge.d.ts.map +1 -1
  28. package/dist/tool/utils/merge.js +9 -0
  29. package/dist/tool/utils/merge.js.map +1 -1
  30. package/docs/adopt.md +20 -14
  31. package/docs/creating-overlays.md +151 -2
  32. package/docs/overlay-imports.md +125 -102
  33. package/docs/overlays.md +59 -6
  34. package/docs/quick-reference.md +99 -0
  35. package/docs/specs/002-superposition-config-file/plan.md +6 -1
  36. package/docs/specs/002-superposition-config-file/spec.md +6 -0
  37. package/docs/specs/002-superposition-config-file/tasks.md +2 -0
  38. package/docs/specs/003-mkdocs2-overlay/spec.md +114 -0
  39. package/docs/specs/004-doctor-fix/spec.md +70 -0
  40. package/docs/specs/005-cuda-overlay/spec.md +101 -0
  41. package/docs/specs/006-rocm-overlay/spec.md +109 -0
  42. package/docs/team-workflow.md +7 -1
  43. package/docs/workflows.md +3 -0
  44. package/features/cross-distro-packages/README.md +18 -0
  45. package/features/cross-distro-packages/devcontainer-feature.json +3 -3
  46. package/features/cross-distro-packages/install.sh +49 -7
  47. package/overlays/.shared/README.md +80 -21
  48. package/overlays/.shared/compose/common-healthchecks.md +60 -0
  49. package/overlays/.shared/vscode/recommended-extensions.json +15 -11
  50. package/overlays/alertmanager/setup.sh +4 -19
  51. package/overlays/alertmanager/verify.sh +8 -9
  52. package/overlays/all/README.md +43 -0
  53. package/overlays/all/devcontainer.patch.json +6 -0
  54. package/overlays/all/overlay.yml +14 -0
  55. package/overlays/amp/setup.sh +5 -0
  56. package/overlays/bun/setup.sh +10 -1
  57. package/overlays/bun/verify.sh +6 -1
  58. package/overlays/claude-code/setup.sh +5 -0
  59. package/overlays/cloudflared/setup.sh +9 -12
  60. package/overlays/codex/README.md +9 -6
  61. package/overlays/codex/devcontainer.patch.json +7 -1
  62. package/overlays/codex/setup.sh +5 -0
  63. package/overlays/codex/verify.sh +8 -0
  64. package/overlays/commitlint/setup.sh +5 -0
  65. package/overlays/cuda/README.md +179 -0
  66. package/overlays/cuda/devcontainer.patch.json +7 -0
  67. package/overlays/cuda/overlay.yml +17 -0
  68. package/overlays/cuda/setup.sh +32 -0
  69. package/overlays/cuda/verify.sh +38 -0
  70. package/overlays/devcontainer-cli/README.md +50 -0
  71. package/overlays/devcontainer-cli/devcontainer.patch.json +13 -0
  72. package/overlays/devcontainer-cli/overlay.yml +16 -0
  73. package/overlays/devcontainer-cli/setup.sh +14 -0
  74. package/overlays/direnv/devcontainer.patch.json +6 -0
  75. package/overlays/direnv/setup.sh +7 -6
  76. package/overlays/dotnet/setup.sh +14 -7
  77. package/overlays/duckdb/devcontainer.patch.json +1 -2
  78. package/overlays/gcloud/devcontainer.patch.json +0 -6
  79. package/overlays/gcloud/setup.sh +51 -0
  80. package/overlays/gemini-cli/setup.sh +5 -0
  81. package/overlays/git-helpers/devcontainer.patch.json +2 -1
  82. package/overlays/go/setup.sh +15 -14
  83. package/overlays/jaeger/overlay.yml +2 -0
  84. package/overlays/just/setup.sh +5 -17
  85. package/overlays/keycloak/docker-compose.yml +6 -4
  86. package/overlays/keycloak/verify.sh +4 -3
  87. package/overlays/kind/devcontainer.patch.json +1 -2
  88. package/overlays/kind/setup.sh +8 -17
  89. package/overlays/minio/setup.sh +10 -18
  90. package/overlays/mkdocs/overlay.yml +2 -1
  91. package/overlays/mkdocs2/README.md +135 -0
  92. package/overlays/mkdocs2/devcontainer.patch.json +19 -0
  93. package/overlays/mkdocs2/overlay.yml +17 -0
  94. package/overlays/mkdocs2/setup.sh +67 -0
  95. package/overlays/mkdocs2/verify.sh +35 -0
  96. package/overlays/modern-cli-tools/devcontainer.patch.json +7 -1
  97. package/overlays/modern-cli-tools/setup.sh +21 -71
  98. package/overlays/mongodb/devcontainer.patch.json +0 -6
  99. package/overlays/mongodb/setup.sh +59 -0
  100. package/overlays/mysql/verify.sh +4 -3
  101. package/overlays/nats/.env.example +1 -1
  102. package/overlays/nats/README.md +1 -1
  103. package/overlays/nats/docker-compose.yml +1 -1
  104. package/overlays/ngrok/setup.sh +9 -6
  105. package/overlays/nodejs/setup.sh +5 -0
  106. package/overlays/openapi-tools/devcontainer.patch.json +1 -2
  107. package/overlays/openapi-tools/setup.sh +9 -8
  108. package/overlays/opencode/setup.sh +5 -0
  109. package/overlays/otel-collector/overlay.yml +2 -0
  110. package/overlays/otel-collector/setup.sh +3 -16
  111. package/overlays/otel-demo-nodejs/verify.sh +8 -9
  112. package/overlays/otel-demo-python/verify.sh +16 -10
  113. package/overlays/pandoc/README.md +286 -0
  114. package/overlays/pandoc/devcontainer.patch.json +18 -0
  115. package/overlays/pandoc/overlay.yml +19 -0
  116. package/overlays/pandoc/setup.sh +293 -0
  117. package/overlays/pandoc/verify.sh +25 -0
  118. package/overlays/playwright/devcontainer.patch.json +3 -1
  119. package/overlays/playwright/setup.sh +37 -0
  120. package/overlays/postgres/docker-compose.yml +6 -0
  121. package/overlays/powershell/setup.sh +49 -13
  122. package/overlays/pre-commit/setup.sh +12 -3
  123. package/overlays/prometheus/overlay.yml +2 -0
  124. package/overlays/promtail/verify.sh +16 -10
  125. package/overlays/pulumi/devcontainer.patch.json +1 -1
  126. package/overlays/python/setup.sh +28 -9
  127. package/overlays/python/verify.sh +4 -2
  128. package/overlays/redpanda/docker-compose.yml +3 -5
  129. package/overlays/rocm/README.md +227 -0
  130. package/overlays/rocm/devcontainer.patch.json +4 -0
  131. package/overlays/rocm/overlay.yml +17 -0
  132. package/overlays/rocm/setup.sh +45 -0
  133. package/overlays/rocm/verify.sh +47 -0
  134. package/overlays/rust/setup.sh +11 -18
  135. package/overlays/spec-kit/setup.sh +7 -3
  136. package/overlays/sqlite/setup.sh +14 -14
  137. package/overlays/sqlserver/docker-compose.yml +3 -3
  138. package/overlays/sqlserver/verify.sh +22 -5
  139. package/overlays/tempo/verify.sh +16 -10
  140. package/overlays/tilt/devcontainer.patch.json +1 -2
  141. package/overlays/tilt/setup.sh +14 -4
  142. package/overlays/windsurf-cli/setup.sh +27 -4
  143. package/overlays/windsurf-cli/verify.sh +13 -3
  144. package/package.json +2 -1
  145. package/templates/scripts/setup-utils.sh +228 -0
  146. package/tool/schema/config.schema.json +110 -8
  147. package/tool/schema/overlay-manifest.schema.json +5 -0
  148. package/overlays/.shared/compose/common-healthchecks.yml +0 -38
  149. /package/overlays/otel-demo-nodejs/{Dockerfile-otel-demo-nodejs → Dockerfile} +0 -0
  150. /package/overlays/otel-demo-nodejs/{package-otel-demo-nodejs.json → package.json} +0 -0
  151. /package/overlays/otel-demo-nodejs/{server-otel-demo-nodejs.js → server.js} +0 -0
  152. /package/overlays/otel-demo-nodejs/{tracing-otel-demo-nodejs.js → tracing.js} +0 -0
  153. /package/overlays/otel-demo-python/{Dockerfile-otel-demo-python → Dockerfile} +0 -0
  154. /package/overlays/otel-demo-python/{app-otel-demo-python.py → app.py} +0 -0
  155. /package/overlays/otel-demo-python/{requirements-otel-demo-python.txt → requirements.txt} +0 -0
@@ -0,0 +1,179 @@
1
+ # CUDA (NVIDIA GPU) Overlay
2
+
3
+ Enables NVIDIA GPU passthrough for containerized ML, inference, and CUDA compute workloads.
4
+
5
+ ## Features
6
+
7
+ - **GPU passthrough** - `--gpus=all` added to container `runArgs` so all host GPUs are available
8
+ - **VS Code devcontainer GPU hint** - `hostRequirements.gpu = true` signals that a GPU is needed
9
+ - **Setup check** - `setup.sh` verifies `nvidia-smi` on container start and prints actionable guidance when GPU access is unavailable
10
+ - **Doctor integration** - `verify.sh` asserts `nvidia-smi` exits 0 for `container-superposition doctor` checks
11
+
12
+ ## Prerequisites (host-side — out of scope for this overlay)
13
+
14
+ This overlay configures the _container_ side of GPU passthrough. The host must be prepared independently:
15
+
16
+ 1. **Supported NVIDIA GPU** — Pascal (GTX 10xx) or newer recommended
17
+ 2. **NVIDIA drivers** — Install the appropriate driver for your OS from [https://www.nvidia.com/drivers](https://www.nvidia.com/drivers)
18
+ 3. **NVIDIA Container Toolkit** — Install and configure following the [official guide](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html):
19
+ ```bash
20
+ # Example for Ubuntu
21
+ curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
22
+ curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
23
+ sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
24
+ sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
25
+ sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
26
+ ```
27
+ 4. **Configure the Docker runtime** — Run once after installing the toolkit:
28
+ ```bash
29
+ sudo nvidia-ctk runtime configure --runtime=docker
30
+ sudo systemctl restart docker
31
+ ```
32
+
33
+ > ⚠️ **This overlay cannot install or replace host drivers.** Version alignment between the CUDA user-space libraries inside the container and the host kernel module is the user's responsibility.
34
+
35
+ ## How It Works
36
+
37
+ The overlay patches `devcontainer.json` with two settings:
38
+
39
+ ```json
40
+ {
41
+ "runArgs": ["--gpus=all"],
42
+ "hostRequirements": {
43
+ "gpu": true
44
+ }
45
+ }
46
+ ```
47
+
48
+ - **`runArgs: ["--gpus=all"]`** — Passes all host GPUs into the container via the NVIDIA Container Runtime.
49
+ - **`hostRequirements.gpu: true`** — Tells VS Code that the host must have a GPU. VS Code will warn the user when opening the repo if no GPU is detected.
50
+
51
+ The container image itself does **not** need to be an official NVIDIA CUDA image for the passthrough to work; however, CUDA libraries (e.g., `libcuda.so`) must exist inside the image to use CUDA APIs. See [Base Image](#base-image) below.
52
+
53
+ ## Base Image
54
+
55
+ For GPU workloads you typically want a CUDA-capable base image. Popular choices:
56
+
57
+ | Image | Use case |
58
+ | ----------------------------------------- | --------------------------- |
59
+ | `nvidia/cuda:12.x.x-runtime-ubuntu22.04` | Runtime-only (inference) |
60
+ | `nvidia/cuda:12.x.x-devel-ubuntu22.04` | Full toolkit (compilation) |
61
+ | `nvcr.io/nvidia/pytorch:24.xx-py3` | PyTorch + CUDA pre-built |
62
+ | `nvcr.io/nvidia/tensorflow:24.xx-tf2-py3` | TensorFlow + CUDA pre-built |
63
+
64
+ Browse all tags at [hub.docker.com/r/nvidia/cuda](https://hub.docker.com/r/nvidia/cuda) and [catalog.ngc.nvidia.com](https://catalog.ngc.nvidia.com).
65
+
66
+ To use a CUDA image, set the `image` field in your `.devcontainer/devcontainer.json` (for plain stack) or configure the appropriate service's `image` (or its `build`/`dockerfile`) in your compose-based devcontainer setup (for compose stack).
67
+
68
+ ## Common Commands
69
+
70
+ ### Check GPU availability
71
+
72
+ ```bash
73
+ # List GPUs and driver version
74
+ nvidia-smi
75
+
76
+ # Compact GPU list
77
+ nvidia-smi -L
78
+
79
+ # Watch GPU utilisation (refreshes every second)
80
+ nvidia-smi dmon -s u
81
+ ```
82
+
83
+ ### Query CUDA version
84
+
85
+ ```bash
86
+ # CUDA runtime version (requires libcuda / nvidia-smi)
87
+ nvidia-smi | grep "CUDA Version"
88
+
89
+ # CUDA toolkit version (if nvcc is installed in the image)
90
+ nvcc --version
91
+ ```
92
+
93
+ ### Python / PyTorch smoke test
94
+
95
+ ```python
96
+ import torch
97
+ print(torch.cuda.is_available()) # True
98
+ print(torch.cuda.get_device_name(0)) # e.g. "NVIDIA GeForce RTX 4090"
99
+ ```
100
+
101
+ ### TensorFlow smoke test
102
+
103
+ ```python
104
+ import tensorflow as tf
105
+ print(tf.config.list_physical_devices('GPU'))
106
+ ```
107
+
108
+ ## Use Cases
109
+
110
+ - **Model inference** — Run LLM or CV model inference with GPU acceleration
111
+ - **Training** — Train deep learning models without leaving the dev container
112
+ - **CUDA compute** — General-purpose GPU programming with CUDA C/C++ or PyCUDA
113
+ - **Jupyter notebooks** — GPU-accelerated data science with Jupyter (combine with the `jupyter` overlay)
114
+ - **CI parity** — Reproduce GPU CI failures locally inside the same container image
115
+
116
+ **Integrates well with:**
117
+
118
+ - `python` — Python runtime for ML workloads
119
+ - `jupyter` — Interactive GPU notebooks
120
+
121
+ ## Troubleshooting
122
+
123
+ ### `nvidia-smi: command not found`
124
+
125
+ The container cannot see the GPU. Work through this checklist:
126
+
127
+ 1. Verify host drivers: `nvidia-smi` should work on the _host_ before it works inside the container.
128
+ 2. Verify NVIDIA Container Toolkit is installed: `nvidia-ctk --version`.
129
+ 3. Verify Docker is configured to use the NVIDIA runtime:
130
+ ```bash
131
+ docker info | grep -i runtime
132
+ # Should list: nvidia
133
+ ```
134
+ 4. Rebuild the dev container after configuring the toolkit.
135
+
136
+ ### `Failed to initialize NVML: Driver/library version mismatch`
137
+
138
+ The CUDA user-space library version inside the image does not match the host kernel module. Solutions:
139
+
140
+ - Use a container image whose CUDA version matches (or is older than) the driver's supported CUDA version (`nvidia-smi` shows the maximum supported CUDA version on the host).
141
+ - Update the host NVIDIA driver.
142
+
143
+ ### `--gpus` flag not recognised by Docker
144
+
145
+ Your Docker version is older than 19.03 or the NVIDIA runtime is not configured as the default. Run:
146
+
147
+ ```bash
148
+ sudo nvidia-ctk runtime configure --runtime=docker
149
+ sudo systemctl restart docker
150
+ ```
151
+
152
+ Or pass the runtime explicitly (not needed if the overlay's `runArgs` is picked up):
153
+
154
+ ```bash
155
+ docker run --runtime=nvidia --gpus all nvidia/cuda:12.0-base nvidia-smi
156
+ ```
157
+
158
+ ### GPU not visible in GitHub Codespaces / cloud dev environments
159
+
160
+ Cloud hosted dev environments (GitHub Codespaces, Gitpod) typically do not provide GPU pass-through. Use a GPU-enabled cloud VM (AWS p-instances, GCP A100, Azure NCv3) and run VS Code Remote SSH or a self-hosted Codespace runner with GPU support.
161
+
162
+ ## Security Considerations
163
+
164
+ `--gpus=all` grants the container access to all host GPUs. This is appropriate for development but should not be used in untrusted or multi-tenant environments without additional isolation.
165
+
166
+ ## References
167
+
168
+ - [NVIDIA Container Toolkit — install guide](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html)
169
+ - [NVIDIA CUDA Docker images](https://hub.docker.com/r/nvidia/cuda)
170
+ - [NVIDIA NGC catalogue](https://catalog.ngc.nvidia.com)
171
+ - [devcontainer spec — hostRequirements](https://containers.dev/implementors/json_reference/#general-properties)
172
+
173
+ **Related Overlays:**
174
+
175
+ - `python` — Python runtime for ML workloads
176
+ - `jupyter` — GPU-accelerated interactive notebooks
177
+ - `docker-in-docker` / `docker-sock` — Build GPU-enabled container images from within the dev container
178
+
179
+ > 🔜 **ROCm (AMD GPU)** support is tracked in a separate overlay (`rocm`). When that overlay is added it must declare `cuda` in its `conflicts` to satisfy the bidirectional conflict requirement.
@@ -0,0 +1,7 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.base.schema.json",
3
+ "runArgs": ["--gpus=all"],
4
+ "hostRequirements": {
5
+ "gpu": true
6
+ }
7
+ }
@@ -0,0 +1,17 @@
1
+ id: cuda
2
+ name: CUDA (NVIDIA GPU)
3
+ description: NVIDIA CUDA libraries and GPU passthrough for containerized ML/inference workloads
4
+ category: dev
5
+ supports: []
6
+ requires: []
7
+ suggests: []
8
+ conflicts:
9
+ - rocm
10
+ tags:
11
+ - dev
12
+ - gpu
13
+ - cuda
14
+ - nvidia
15
+ - ml
16
+ - inference
17
+ ports: []
@@ -0,0 +1,32 @@
1
+ #!/bin/bash
2
+ # CUDA overlay setup script
3
+ # Checks that nvidia-smi is reachable inside the container and prints
4
+ # a helpful message when the host is not configured for GPU passthrough.
5
+
6
+ set -e
7
+
8
+ echo "🖥️ Setting up CUDA (NVIDIA GPU) overlay..."
9
+
10
+ if nvidia-smi -L >/dev/null 2>&1; then
11
+ echo "✓ nvidia-smi found: $(nvidia-smi --query-gpu=name --format=csv,noheader 2>/dev/null | head -n1 || nvidia-smi -L 2>/dev/null | head -n1 || echo 'GPU detected')"
12
+ echo "✓ CUDA overlay is ready"
13
+ else
14
+ echo ""
15
+ echo "⚠️ nvidia-smi is installed but failed to run inside the container."
16
+ echo ""
17
+ echo " GPU passthrough requires the following on the host:"
18
+ echo " 1. A supported NVIDIA GPU"
19
+ echo " 2. NVIDIA drivers installed on the host"
20
+ echo " 3. NVIDIA Container Toolkit installed and configured:"
21
+ echo " https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html"
22
+ echo " 4. Docker configured to use the NVIDIA runtime:"
23
+ echo " nvidia-ctk runtime configure --runtime=docker"
24
+ echo ""
25
+ echo " This overlay adds '--gpus=all' to the container's runArgs and sets"
26
+ echo " hostRequirements.gpu = true in devcontainer.json, but it cannot"
27
+ echo " install or replace host drivers."
28
+ echo ""
29
+ echo " Once the host is configured, rebuild the dev container."
30
+ echo ""
31
+ echo "ℹ️ CUDA overlay setup complete (nvidia-smi not functioning on this host)"
32
+ fi
@@ -0,0 +1,38 @@
1
+ #!/bin/bash
2
+ # Verification script for CUDA overlay
3
+ # Asserts nvidia-smi exits 0 (used by the doctor command)
4
+
5
+ set -e
6
+
7
+ echo "🔍 Verifying CUDA (NVIDIA GPU) overlay..."
8
+ echo ""
9
+
10
+ echo "1️⃣ Checking nvidia-smi..."
11
+ if command -v nvidia-smi &> /dev/null; then
12
+ if nvidia-smi --query-gpu=name,driver_version,memory.total --format=csv,noheader 2>/dev/null; then
13
+ echo " ✅ nvidia-smi is available and GPU is accessible"
14
+ elif nvidia-smi -L; then
15
+ echo " ✅ nvidia-smi is available and GPU is accessible"
16
+ else
17
+ echo " ❌ nvidia-smi is installed but failed to query GPU information"
18
+ echo ""
19
+ echo " Possible causes:"
20
+ echo " - NVIDIA driver is not loaded or mismatched with the container CUDA version"
21
+ echo " - Insufficient permissions to access the GPU from this container"
22
+ echo " - NVIDIA Container Toolkit / runtime is misconfigured"
23
+ echo ""
24
+ echo " Resolve the above issues and retry the CUDA overlay verification."
25
+ exit 1
26
+ fi
27
+ else
28
+ echo " ❌ nvidia-smi not found"
29
+ echo ""
30
+ echo " Ensure the host has:"
31
+ echo " - NVIDIA drivers installed"
32
+ echo " - NVIDIA Container Toolkit installed and configured"
33
+ echo " - Docker runtime configured for NVIDIA (nvidia-ctk runtime configure)"
34
+ exit 1
35
+ fi
36
+
37
+ echo ""
38
+ echo "✅ CUDA overlay verification complete"
@@ -0,0 +1,50 @@
1
+ # Dev Container CLI Overlay
2
+
3
+ Installs the [official devcontainer CLI](https://github.com/devcontainers/cli) (`@devcontainers/cli`) for building, running, and testing devcontainer configurations from the command line.
4
+
5
+ Useful for projects that generate or verify devcontainer configurations programmatically — including container-superposition itself.
6
+
7
+ ## Features
8
+
9
+ - **`devcontainer` CLI** — Build, run, and test devcontainer configurations from the command line
10
+ - **Node.js LTS** — Required runtime (included if not already present)
11
+ - **VS Code Extension:** Dev Containers (ms-vscode-remote.remote-containers)
12
+
13
+ ## How It Works
14
+
15
+ The setup script installs `@devcontainers/cli` as a global npm package. Node.js LTS is included via a devcontainer feature if not already available in the environment.
16
+
17
+ ## Common Commands
18
+
19
+ ```bash
20
+ # Build a devcontainer image
21
+ devcontainer build --workspace-folder .
22
+
23
+ # Start a devcontainer
24
+ devcontainer up --workspace-folder .
25
+
26
+ # Run a command inside the devcontainer
27
+ devcontainer exec --workspace-folder . -- bash -c "echo hello"
28
+
29
+ # Check the CLI version
30
+ devcontainer --version
31
+ ```
32
+
33
+ ## Use Cases
34
+
35
+ - **CI/CD validation** — Build and test devcontainer configurations in pipelines
36
+ - **Container-superposition development** — Verify generated `.devcontainer/` outputs actually build
37
+ - **Toolchain testing** — Ensure devcontainer features and overlays compose correctly
38
+
39
+ ## Requires Docker
40
+
41
+ The devcontainer CLI needs a Docker daemon to build containers. Pair with one of:
42
+
43
+ - [`docker-sock`](../docker-sock/README.md) — bind-mount host Docker socket (simpler, works everywhere)
44
+ - [`docker-in-docker`](../docker-in-docker/README.md) — isolated Docker daemon (better for nested containers)
45
+
46
+ ## References
47
+
48
+ - [devcontainers/cli on GitHub](https://github.com/devcontainers/cli)
49
+ - [Dev Containers specification](https://containers.dev/)
50
+ - [devcontainer CLI npm package](https://www.npmjs.com/package/@devcontainers/cli)
@@ -0,0 +1,13 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.base.schema.json",
3
+ "features": {
4
+ "ghcr.io/devcontainers/features/node:1": {
5
+ "version": "lts"
6
+ }
7
+ },
8
+ "customizations": {
9
+ "vscode": {
10
+ "extensions": ["ms-vscode-remote.remote-containers"]
11
+ }
12
+ }
13
+ }
@@ -0,0 +1,16 @@
1
+ id: devcontainer-cli
2
+ name: Dev Container CLI
3
+ description: Official devcontainer CLI for building and testing devcontainer configurations
4
+ category: dev
5
+ supports: []
6
+ requires: []
7
+ suggests:
8
+ - docker-sock
9
+ - docker-in-docker
10
+ conflicts: []
11
+ tags:
12
+ - dev
13
+ - devcontainer
14
+ - cli
15
+ - testing
16
+ ports: []
@@ -0,0 +1,14 @@
1
+ #!/bin/bash
2
+ # Dev Container CLI setup script - Install @devcontainers/cli globally
3
+
4
+ set -e
5
+
6
+ # Source shared setup utilities (provides load_nvm)
7
+ # shellcheck source=setup-utils.sh
8
+ source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
9
+ load_nvm
10
+
11
+ echo "📦 Installing @devcontainers/cli..."
12
+ npm install -g @devcontainers/cli
13
+
14
+ echo "✓ devcontainer CLI installed: $(devcontainer --version)"
@@ -1,5 +1,11 @@
1
1
  {
2
2
  "$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.base.schema.json",
3
+ "features": {
4
+ "./features/cross-distro-packages": {
5
+ "apt": "direnv",
6
+ "apk": "direnv"
7
+ }
8
+ },
3
9
  "remoteEnv": {
4
10
  "DIRENV_LOG_FORMAT": ""
5
11
  }
@@ -5,15 +5,11 @@ set -e
5
5
 
6
6
  echo "🔐 Setting up direnv..."
7
7
 
8
- # Install direnv from package manager
9
- sudo apt-get update -qq
10
- sudo apt-get install -y direnv
11
-
12
- # Verify installation
8
+ # Verify installation (installed via cross-distro-packages feature)
13
9
  if command -v direnv &> /dev/null; then
14
10
  echo "✓ direnv installed: $(direnv version)"
15
11
  else
16
- echo "✗ direnv installation failed"
12
+ echo "✗ direnv not found — check cross-distro-packages feature"
17
13
  exit 1
18
14
  fi
19
15
 
@@ -80,6 +76,11 @@ EOF
80
76
  echo "✓ .envrc pre-allowed (run 'direnv deny' to disable)"
81
77
  fi
82
78
 
79
+ # Ensure any pre-existing .envrc is also allowed (idempotent re-runs)
80
+ if [ -f .envrc ]; then
81
+ direnv allow .envrc 2>/dev/null || true
82
+ fi
83
+
83
84
  # Create sample .env file if it doesn't exist
84
85
  if [ ! -f .env ] && [ ! -f .env.example ]; then
85
86
  cat > .env.example << 'EOF'
@@ -3,6 +3,15 @@
3
3
 
4
4
  set -e
5
5
 
6
+ # Source shared setup utilities (provides run_spinner)
7
+ # shellcheck source=setup-utils.sh
8
+ source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
9
+
10
+ # Suppress the .NET SDK first-run welcome banner and telemetry noise
11
+ export DOTNET_NOLOGO=1
12
+ export DOTNET_CLI_TELEMETRY_OPTOUT=1
13
+ export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
14
+
6
15
  # Extract overlay name from script filename (setup-<overlay>.sh -> <overlay>)
7
16
  OVERLAY_NAME=$(basename "$0" | sed 's/setup-//;s/\.sh$//')
8
17
 
@@ -21,20 +30,18 @@ if [ -f ".devcontainer/global-tools-${OVERLAY_NAME}.txt" ]; then
21
30
  if [[ "$line" =~ ^(.+)::(.+)$ ]]; then
22
31
  tool="${BASH_REMATCH[1]}"
23
32
  version="${BASH_REMATCH[2]}"
24
- echo " Installing $tool version $version..."
25
- dotnet tool install --global "$tool" --version "$version" || echo " ⚠️ $tool already installed or failed"
33
+ run_spinner "$tool@$version" dotnet tool install --global "$tool" --version "$version" || true
26
34
  else
27
35
  tool="$line"
28
- echo " Installing $tool..."
29
- dotnet tool install --global "$tool" || echo " ⚠️ $tool already installed or failed"
36
+ run_spinner "$tool" dotnet tool install --global "$tool" || true
30
37
  fi
31
38
  done < ".devcontainer/global-tools-${OVERLAY_NAME}.txt"
32
39
  else
33
40
  # Fallback to hardcoded list
34
41
  echo "📦 Installing default .NET global tools..."
35
- dotnet tool install --global dotnet-ef || echo "dotnet-ef already installed"
36
- dotnet tool install --global dotnet-format || echo "dotnet-format already installed"
37
- dotnet tool install --global dotnet-outdated-tool || echo "dotnet-outdated-tool already installed"
42
+ run_spinner "dotnet-ef" dotnet tool install --global dotnet-ef || true
43
+ run_spinner "dotnet-format" dotnet tool install --global dotnet-format || true
44
+ run_spinner "dotnet-outdated-tool" dotnet tool install --global dotnet-outdated-tool || true
38
45
  fi
39
46
 
40
47
  # Verify installations
@@ -5,6 +5,5 @@
5
5
  "apt": "wget unzip",
6
6
  "apk": "wget unzip"
7
7
  }
8
- },
9
- "postCreateCommand": "bash .devcontainer/scripts/setup-duckdb.sh"
8
+ }
10
9
  }
@@ -1,11 +1,5 @@
1
1
  {
2
2
  "$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.base.schema.json",
3
- "features": {
4
- "ghcr.io/devcontainers/features/google-cloud-cli:1": {
5
- "version": "latest",
6
- "installGkeGcloudAuthPlugin": true
7
- }
8
- },
9
3
  "customizations": {
10
4
  "vscode": {
11
5
  "extensions": ["googlecloudtools.cloudcode"]
@@ -0,0 +1,51 @@
1
+ #!/bin/bash
2
+ # Google Cloud CLI setup script
3
+
4
+ set -e
5
+
6
+ echo "☁️ Setting up Google Cloud CLI..."
7
+
8
+ # Source shared setup utilities
9
+ # shellcheck source=setup-utils.sh
10
+ source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
11
+
12
+ if command -v apk >/dev/null 2>&1; then
13
+ # Alpine Linux — no official gcloud apt repo; install via tarball
14
+ apk add --no-cache python3 curl
15
+ curl -sSL https://sdk.cloud.google.com | CLOUDSDK_CORE_DISABLE_PROMPTS=1 bash -s -- --disable-prompts --install-dir=/usr/local
16
+ ln -sf /usr/local/google-cloud-sdk/bin/gcloud /usr/local/bin/gcloud
17
+ ln -sf /usr/local/google-cloud-sdk/bin/gsutil /usr/local/bin/gsutil
18
+ elif command -v apt-get >/dev/null 2>&1; then
19
+ # Debian/Ubuntu — add Google Cloud apt repo using modern signed-by method
20
+ # The Google Cloud key is already in binary (non-armored) format — write directly.
21
+ sudo mkdir -p /usr/share/keyrings /etc/apt/sources.list.d
22
+ curl -fsSL "https://packages.cloud.google.com/apt/doc/apt-key.gpg" \
23
+ | sudo tee /usr/share/keyrings/cloud.google.gpg >/dev/null
24
+ echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" \
25
+ | sudo tee /etc/apt/sources.list.d/google-cloud-sdk.list >/dev/null
26
+
27
+ # Single lock acquisition: install prereqs + add repo + install gcloud in one pass
28
+ acquire_apt_lock
29
+ # Pass env vars explicitly — sudo strips them by default.
30
+ sudo DEBIAN_FRONTEND=noninteractive TERM=dumb apt-get update -qq
31
+ sudo DEBIAN_FRONTEND=noninteractive TERM=dumb apt-get install -y -qq --no-install-recommends apt-transport-https ca-certificates gnupg curl
32
+ # apt index already fresh — install gcloud packages without a second apt-get update
33
+ sudo DEBIAN_FRONTEND=noninteractive TERM=dumb apt-get install -y -qq --no-install-recommends \
34
+ google-cloud-cli \
35
+ google-cloud-cli-gke-gcloud-auth-plugin
36
+ sudo apt-get clean
37
+ sudo rm -rf /var/lib/apt/lists/*
38
+ release_apt_lock
39
+ else
40
+ echo "⚠️ Unsupported package manager, skipping gcloud installation"
41
+ exit 0
42
+ fi
43
+
44
+ if command -v gcloud >/dev/null 2>&1; then
45
+ echo "✓ gcloud installed: $(gcloud --version | head -1)"
46
+ else
47
+ echo "✗ gcloud installation failed"
48
+ exit 1
49
+ fi
50
+
51
+ echo "✓ gcloud setup complete"
@@ -3,6 +3,11 @@
3
3
 
4
4
  set -e
5
5
 
6
+ # Source shared setup utilities (provides load_nvm)
7
+ # shellcheck source=setup-utils.sh
8
+ source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
9
+ load_nvm
10
+
6
11
  echo "📦 Installing Google Gemini CLI..."
7
12
 
8
13
  # Install @google/gemini-cli globally
@@ -6,7 +6,8 @@
6
6
  "version": "os-provided"
7
7
  },
8
8
  "ghcr.io/devcontainers/features/git-lfs:1": {
9
- "version": "latest"
9
+ "version": "latest",
10
+ "autoPull": false
10
11
  },
11
12
  "ghcr.io/devcontainers/features/github-cli:1": {
12
13
  "version": "latest"
@@ -3,25 +3,26 @@
3
3
 
4
4
  set -e
5
5
 
6
- echo "🔧 Setting up Go development environment..."
6
+ # Source shared setup utilities
7
+ # shellcheck source=setup-utils.sh
8
+ source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
7
9
 
8
- # Install common Go tools
10
+ echo "🔧 Setting up Go development environment..."
9
11
  echo "📦 Installing Go development tools..."
10
12
 
11
- # gopls (Language Server)
12
- go install golang.org/x/tools/gopls@latest || echo "⚠️ gopls installation failed"
13
-
14
- # delve (Debugger)
15
- go install github.com/go-delve/delve/cmd/dlv@latest || echo "⚠️ delve installation failed"
13
+ run_spinner "gopls (language server)" go install golang.org/x/tools/gopls@latest
14
+ run_spinner "delve (debugger)" go install github.com/go-delve/delve/cmd/dlv@latest
16
15
 
17
- # golangci-lint (Linter) - install via go install for security
18
- go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest || echo "⚠️ golangci-lint installation failed"
19
-
20
- # gofumpt (Formatter)
21
- go install mvdan.cc/gofumpt@latest || echo "⚠️ gofumpt installation failed"
16
+ # golangci-lint use official installer to avoid gold linker issues on arm64
17
+ if ! command -v golangci-lint &>/dev/null; then
18
+ run_spinner "golangci-lint" \
19
+ bash -c 'curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "$(go env GOPATH)/bin"'
20
+ else
21
+ echo " ℹ️ golangci-lint already installed: $(golangci-lint version --short 2>/dev/null || true)"
22
+ fi
22
23
 
23
- # staticcheck (Static analyzer)
24
- go install honnef.co/go/tools/cmd/staticcheck@latest || echo "⚠️ staticcheck installation failed"
24
+ run_spinner "gofumpt (formatter)" go install mvdan.cc/gofumpt@latest
25
+ run_spinner "staticcheck (analyzer)" go install honnef.co/go/tools/cmd/staticcheck@latest
25
26
 
26
27
  # Install project dependencies if go.mod exists
27
28
  if [ -f "go.mod" ]; then
@@ -30,3 +30,5 @@ ports:
30
30
  description: Jaeger HTTP receiver
31
31
  onAutoForward: ignore
32
32
  order: 1
33
+ imports:
34
+ - .shared/otel/instrumentation.env
@@ -9,31 +9,19 @@ echo "⚡ Setting up just task runner..."
9
9
  JUST_VERSION="1.25.2"
10
10
  ARCH=$(uname -m)
11
11
 
12
- # SHA256 checksums for just v1.25.2
13
- if [ "$ARCH" = "x86_64" ]; then
14
- ARCH="x86_64"
15
- CHECKSUM="6804798c3744fd1ce563840ee9fe14ae53c74b3cc7b8536da3f87751d7f85501"
16
- elif [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
12
+ if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
17
13
  ARCH="aarch64"
18
- CHECKSUM="f287a95846131ce8de65181b0b1ec0a0b7db4f6f8d393b3b548f70fcb5a4b0ee"
14
+ elif [ "$ARCH" = "x86_64" ]; then
15
+ ARCH="x86_64"
19
16
  else
20
- echo "⚠️ Unsupported architecture: $ARCH"
17
+ echo "⚠️ Unsupported architecture: $ARCH, falling back to x86_64"
21
18
  ARCH="x86_64"
22
- CHECKSUM="6804798c3744fd1ce563840ee9fe14ae53c74b3cc7b8536da3f87751d7f85501"
23
19
  fi
24
20
 
25
21
  echo "📦 Downloading just v${JUST_VERSION} for ${ARCH}..."
26
- curl -L "https://github.com/casey/just/releases/download/${JUST_VERSION}/just-${JUST_VERSION}-${ARCH}-unknown-linux-musl.tar.gz" \
22
+ curl -fsSL "https://github.com/casey/just/releases/download/${JUST_VERSION}/just-${JUST_VERSION}-${ARCH}-unknown-linux-musl.tar.gz" \
27
23
  -o /tmp/just.tar.gz
28
24
 
29
- # Verify checksum
30
- echo "🔐 Verifying checksum..."
31
- echo "${CHECKSUM} /tmp/just.tar.gz" | sha256sum -c - || {
32
- echo "✗ Checksum verification failed"
33
- rm /tmp/just.tar.gz
34
- exit 1
35
- }
36
-
37
25
  # Extract and install
38
26
  tar -xzf /tmp/just.tar.gz -C /tmp
39
27
  sudo mv /tmp/just /usr/local/bin/