container-superposition 0.1.7 → 0.1.9

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 (242) hide show
  1. package/README.md +24 -15
  2. package/dist/scripts/init.js +1 -1537
  3. package/dist/scripts/init.js.map +1 -1
  4. package/dist/tool/cli/args.d.ts +20 -0
  5. package/dist/tool/cli/args.d.ts.map +1 -0
  6. package/dist/tool/cli/args.js +325 -0
  7. package/dist/tool/cli/args.js.map +1 -0
  8. package/dist/tool/cli/run.d.ts +2 -0
  9. package/dist/tool/cli/run.d.ts.map +1 -0
  10. package/dist/tool/cli/run.js +318 -0
  11. package/dist/tool/cli/run.js.map +1 -0
  12. package/dist/tool/commands/adopt.js +1 -1
  13. package/dist/tool/commands/adopt.js.map +1 -1
  14. package/dist/tool/commands/doctor.d.ts +1 -0
  15. package/dist/tool/commands/doctor.d.ts.map +1 -1
  16. package/dist/tool/commands/doctor.js +1510 -78
  17. package/dist/tool/commands/doctor.js.map +1 -1
  18. package/dist/tool/commands/explain.d.ts.map +1 -1
  19. package/dist/tool/commands/explain.js +9 -0
  20. package/dist/tool/commands/explain.js.map +1 -1
  21. package/dist/tool/commands/migrate.d.ts +7 -0
  22. package/dist/tool/commands/migrate.d.ts.map +1 -0
  23. package/dist/tool/commands/migrate.js +52 -0
  24. package/dist/tool/commands/migrate.js.map +1 -0
  25. package/dist/tool/questionnaire/answers.d.ts +16 -0
  26. package/dist/tool/questionnaire/answers.d.ts.map +1 -0
  27. package/dist/tool/questionnaire/answers.js +102 -0
  28. package/dist/tool/questionnaire/answers.js.map +1 -0
  29. package/dist/tool/questionnaire/composer.d.ts +6 -4
  30. package/dist/tool/questionnaire/composer.d.ts.map +1 -1
  31. package/dist/tool/questionnaire/composer.js +778 -45
  32. package/dist/tool/questionnaire/composer.js.map +1 -1
  33. package/dist/tool/questionnaire/presets.d.ts +60 -0
  34. package/dist/tool/questionnaire/presets.d.ts.map +1 -0
  35. package/dist/tool/questionnaire/presets.js +165 -0
  36. package/dist/tool/questionnaire/presets.js.map +1 -0
  37. package/dist/tool/questionnaire/questionnaire.d.ts +10 -0
  38. package/dist/tool/questionnaire/questionnaire.d.ts.map +1 -0
  39. package/dist/tool/questionnaire/questionnaire.js +582 -0
  40. package/dist/tool/questionnaire/questionnaire.js.map +1 -0
  41. package/dist/tool/schema/manifest-migrations.d.ts +5 -0
  42. package/dist/tool/schema/manifest-migrations.d.ts.map +1 -1
  43. package/dist/tool/schema/manifest-migrations.js +45 -0
  44. package/dist/tool/schema/manifest-migrations.js.map +1 -1
  45. package/dist/tool/schema/overlay-loader.d.ts.map +1 -1
  46. package/dist/tool/schema/overlay-loader.js +24 -0
  47. package/dist/tool/schema/overlay-loader.js.map +1 -1
  48. package/dist/tool/schema/project-config.d.ts +13 -1
  49. package/dist/tool/schema/project-config.d.ts.map +1 -1
  50. package/dist/tool/schema/project-config.js +188 -10
  51. package/dist/tool/schema/project-config.js.map +1 -1
  52. package/dist/tool/schema/target-rules.d.ts +78 -0
  53. package/dist/tool/schema/target-rules.d.ts.map +1 -0
  54. package/dist/tool/schema/target-rules.js +367 -0
  55. package/dist/tool/schema/target-rules.js.map +1 -0
  56. package/dist/tool/schema/types.d.ts +42 -3
  57. package/dist/tool/schema/types.d.ts.map +1 -1
  58. package/dist/tool/utils/parameters.d.ts +76 -0
  59. package/dist/tool/utils/parameters.d.ts.map +1 -0
  60. package/dist/tool/utils/parameters.js +125 -0
  61. package/dist/tool/utils/parameters.js.map +1 -0
  62. package/dist/tool/utils/paths.d.ts +2 -0
  63. package/dist/tool/utils/paths.d.ts.map +1 -0
  64. package/dist/tool/utils/paths.js +31 -0
  65. package/dist/tool/utils/paths.js.map +1 -0
  66. package/docs/deployment-targets.md +88 -56
  67. package/docs/examples.md +20 -17
  68. package/docs/filesystem-contract.md +5 -0
  69. package/docs/minimal-and-editor.md +65 -5
  70. package/docs/overlay-imports.md +92 -14
  71. package/docs/overlays.md +231 -135
  72. package/docs/specs/001-verbose-plan-graph/spec.md +5 -12
  73. package/docs/specs/002-superposition-config-file/spec.md +5 -12
  74. package/docs/specs/003-mkdocs2-overlay/spec.md +2 -9
  75. package/docs/specs/004-doctor-fix/spec.md +1 -8
  76. package/docs/specs/005-cuda-overlay/spec.md +2 -9
  77. package/docs/specs/006-rocm-overlay/spec.md +3 -10
  78. package/docs/specs/007-target-aware-generation/spec.md +119 -0
  79. package/docs/specs/008-project-file-canonical/spec.md +82 -0
  80. package/docs/specs/009-project-env/spec.md +140 -0
  81. package/docs/specs/010-compose-env-materialization/spec.md +123 -0
  82. package/docs/specs/011-overlay-parameters/spec.md +228 -0
  83. package/docs/specs/012-ollama-cli-overlay/spec.md +47 -0
  84. package/docs/specs/013-doctor-dependency-check/spec.md +250 -0
  85. package/docs/specs/014-doctor-compose-port-cross-validation/spec.md +276 -0
  86. package/docs/specs/015-doctor-env-example-drift/spec.md +248 -0
  87. package/docs/specs/016-doctor-reproducibility-check/spec.md +276 -0
  88. package/docs/specs/017-doctor-dry-run/spec.md +276 -0
  89. package/docs/specs/018-init-project-file/spec.md +59 -0
  90. package/docs/specs/taxonomy.md +186 -0
  91. package/overlays/.presets/full-observability.yml +113 -0
  92. package/overlays/.presets/k8s-dev.yml +174 -0
  93. package/overlays/.presets/local-llm.yml +105 -0
  94. package/overlays/.presets/vector-ai.yml +150 -0
  95. package/overlays/.shared/README.md +27 -2
  96. package/overlays/.shared/compose/nvidia-gpu-devcontainer.yml +22 -0
  97. package/overlays/.shared/vscode/js-ts-settings.json +19 -0
  98. package/overlays/.shared/vscode/markdown-extensions.json +8 -0
  99. package/overlays/alertmanager/devcontainer.patch.json +0 -1
  100. package/overlays/alertmanager/docker-compose.yml +8 -0
  101. package/overlays/alertmanager/overlay.yml +1 -0
  102. package/overlays/amp/devcontainer.patch.json +4 -1
  103. package/overlays/bun/devcontainer.patch.json +1 -10
  104. package/overlays/bun/overlay.yml +8 -1
  105. package/overlays/claude-code/devcontainer.patch.json +6 -1
  106. package/overlays/codex/devcontainer.patch.json +5 -0
  107. package/overlays/comfyui/.env.example +34 -0
  108. package/overlays/comfyui/README.md +342 -0
  109. package/overlays/comfyui/devcontainer.patch.json +15 -0
  110. package/overlays/comfyui/docker-compose.yml +40 -0
  111. package/overlays/comfyui/overlay.yml +24 -0
  112. package/overlays/comfyui/setup.sh +36 -0
  113. package/overlays/comfyui/verify.sh +103 -0
  114. package/overlays/commitlint/devcontainer.patch.json +1 -6
  115. package/overlays/docker-sock/overlay.yml +1 -0
  116. package/overlays/dotnet/overlay.yml +4 -1
  117. package/overlays/fuseki/.env.example +5 -0
  118. package/overlays/fuseki/README.md +173 -0
  119. package/overlays/fuseki/devcontainer.patch.json +18 -0
  120. package/overlays/fuseki/docker-compose.yml +29 -0
  121. package/overlays/fuseki/overlay.yml +42 -0
  122. package/overlays/fuseki/verify.sh +58 -0
  123. package/overlays/gemini-cli/devcontainer.patch.json +4 -1
  124. package/overlays/go/overlay.yml +6 -1
  125. package/overlays/grafana/devcontainer.patch.json +0 -1
  126. package/overlays/grafana/docker-compose.yml +8 -2
  127. package/overlays/grafana/overlay.yml +6 -1
  128. package/overlays/jaeger/.env.example +11 -0
  129. package/overlays/jaeger/README.md +33 -4
  130. package/overlays/jaeger/devcontainer.patch.json +9 -1
  131. package/overlays/jaeger/docker-compose.yml +17 -0
  132. package/overlays/jaeger/overlay.yml +1 -12
  133. package/overlays/java/overlay.yml +6 -1
  134. package/overlays/jupyter/docker-compose.yml +1 -0
  135. package/overlays/jupyter/overlay.yml +1 -0
  136. package/overlays/k3d/README.md +201 -0
  137. package/overlays/k3d/devcontainer.patch.json +9 -0
  138. package/overlays/k3d/overlay.yml +19 -0
  139. package/overlays/k3d/setup.sh +34 -0
  140. package/overlays/k3d/verify.sh +38 -0
  141. package/overlays/keycloak/devcontainer.patch.json +0 -1
  142. package/overlays/keycloak/docker-compose.yml +1 -0
  143. package/overlays/keycloak/overlay.yml +15 -0
  144. package/overlays/localstack/docker-compose.yml +1 -0
  145. package/overlays/localstack/overlay.yml +19 -1
  146. package/overlays/loki/devcontainer.patch.json +0 -1
  147. package/overlays/loki/docker-compose.yml +8 -0
  148. package/overlays/loki/overlay.yml +1 -0
  149. package/overlays/mailpit/docker-compose.yml +1 -0
  150. package/overlays/mailpit/overlay.yml +1 -0
  151. package/overlays/minio/devcontainer.patch.json +1 -1
  152. package/overlays/minio/docker-compose.yml +1 -0
  153. package/overlays/minio/overlay.yml +23 -2
  154. package/overlays/mkdocs/devcontainer.patch.json +1 -5
  155. package/overlays/mkdocs/overlay.yml +3 -1
  156. package/overlays/mkdocs2/devcontainer.patch.json +1 -5
  157. package/overlays/mkdocs2/overlay.yml +2 -0
  158. package/overlays/mongodb/docker-compose.yml +2 -0
  159. package/overlays/mongodb/overlay.yml +26 -2
  160. package/overlays/mysql/docker-compose.yml +2 -0
  161. package/overlays/mysql/overlay.yml +36 -2
  162. package/overlays/nats/docker-compose.yml +1 -0
  163. package/overlays/nats/overlay.yml +18 -2
  164. package/overlays/nodejs/devcontainer.patch.json +1 -12
  165. package/overlays/nodejs/overlay.yml +8 -1
  166. package/overlays/ollama/.env.example +14 -0
  167. package/overlays/ollama/README.md +326 -0
  168. package/overlays/ollama/devcontainer.patch.json +14 -0
  169. package/overlays/ollama/docker-compose.yml +25 -0
  170. package/overlays/ollama/overlay.yml +27 -0
  171. package/overlays/ollama/verify.sh +76 -0
  172. package/overlays/ollama-cli/README.md +90 -0
  173. package/overlays/ollama-cli/devcontainer.patch.json +3 -0
  174. package/overlays/ollama-cli/overlay.yml +19 -0
  175. package/overlays/ollama-cli/setup.sh +103 -0
  176. package/overlays/ollama-cli/verify.sh +49 -0
  177. package/overlays/open-webui/.env.example +5 -0
  178. package/overlays/open-webui/README.md +162 -0
  179. package/overlays/open-webui/devcontainer.patch.json +14 -0
  180. package/overlays/open-webui/docker-compose.yml +24 -0
  181. package/overlays/open-webui/overlay.yml +45 -0
  182. package/overlays/opencode/devcontainer.patch.json +4 -1
  183. package/overlays/otel-collector/README.md +4 -0
  184. package/overlays/otel-collector/devcontainer.patch.json +4 -1
  185. package/overlays/otel-collector/docker-compose.yml +8 -4
  186. package/overlays/otel-collector/overlay.yml +1 -0
  187. package/overlays/otel-demo-nodejs/devcontainer.patch.json +0 -1
  188. package/overlays/otel-demo-nodejs/docker-compose.yml +1 -0
  189. package/overlays/otel-demo-nodejs/overlay.yml +9 -1
  190. package/overlays/otel-demo-python/devcontainer.patch.json +0 -1
  191. package/overlays/otel-demo-python/docker-compose.yml +1 -0
  192. package/overlays/otel-demo-python/overlay.yml +6 -1
  193. package/overlays/pandoc/README.md +10 -0
  194. package/overlays/pandoc/devcontainer.patch.json +0 -5
  195. package/overlays/pandoc/overlay.yml +2 -0
  196. package/overlays/pandoc/setup.sh +10 -0
  197. package/overlays/pgvector/.env.example +6 -0
  198. package/overlays/pgvector/README.md +215 -0
  199. package/overlays/pgvector/devcontainer.patch.json +29 -0
  200. package/overlays/pgvector/docker-compose.yml +33 -0
  201. package/overlays/pgvector/overlay.yml +47 -0
  202. package/overlays/playwright/devcontainer.patch.json +0 -5
  203. package/overlays/playwright/overlay.yml +2 -1
  204. package/overlays/postgres/.env.example +5 -5
  205. package/overlays/postgres/devcontainer.patch.json +4 -4
  206. package/overlays/postgres/docker-compose.yml +11 -6
  207. package/overlays/postgres/overlay.yml +23 -2
  208. package/overlays/pre-commit/devcontainer.patch.json +1 -7
  209. package/overlays/prometheus/devcontainer.patch.json +0 -1
  210. package/overlays/prometheus/docker-compose.yml +8 -0
  211. package/overlays/prometheus/overlay.yml +1 -0
  212. package/overlays/promtail/devcontainer.patch.json +1 -2
  213. package/overlays/promtail/docker-compose.yml +8 -0
  214. package/overlays/promtail/overlay.yml +1 -0
  215. package/overlays/qdrant/.env.example +4 -0
  216. package/overlays/qdrant/README.md +216 -0
  217. package/overlays/qdrant/devcontainer.patch.json +20 -0
  218. package/overlays/qdrant/docker-compose.yml +26 -0
  219. package/overlays/qdrant/overlay.yml +44 -0
  220. package/overlays/rabbitmq/docker-compose.yml +1 -0
  221. package/overlays/rabbitmq/overlay.yml +25 -2
  222. package/overlays/redis/docker-compose.yml +7 -0
  223. package/overlays/redis/overlay.yml +15 -1
  224. package/overlays/redpanda/docker-compose.yml +1 -0
  225. package/overlays/redpanda/overlay.yml +15 -3
  226. package/overlays/rocm/overlay.yml +2 -1
  227. package/overlays/rust/overlay.yml +3 -1
  228. package/overlays/skaffold/README.md +256 -0
  229. package/overlays/skaffold/devcontainer.patch.json +9 -0
  230. package/overlays/skaffold/overlay.yml +20 -0
  231. package/overlays/skaffold/setup.sh +33 -0
  232. package/overlays/skaffold/verify.sh +24 -0
  233. package/overlays/sqlserver/docker-compose.yml +1 -0
  234. package/overlays/sqlserver/overlay.yml +17 -0
  235. package/overlays/tempo/devcontainer.patch.json +0 -1
  236. package/overlays/tempo/docker-compose.yml +8 -0
  237. package/overlays/tempo/overlay.yml +1 -0
  238. package/overlays/windsurf-cli/devcontainer.patch.json +4 -1
  239. package/package.json +3 -2
  240. package/tool/schema/config.schema.json +31 -1
  241. package/tool/schema/overlay-manifest.schema.json +33 -0
  242. package/overlays/.shared/otel/otel-base-config.yaml +0 -30
@@ -0,0 +1,103 @@
1
+ #!/bin/bash
2
+ # Ollama CLI setup script
3
+ # Installs the Ollama CLI in the devcontainer for local or remote Ollama usage.
4
+
5
+ set -e
6
+
7
+ source "$(dirname "${BASH_SOURCE[0]}")/setup-utils.sh"
8
+
9
+ detect_arch
10
+
11
+ if command_exists ollama; then
12
+ echo "✓ Ollama CLI already installed: $(ollama --version)"
13
+ echo "ℹ️ OLLAMA_HOST=${OLLAMA_HOST:-http://localhost:11434}"
14
+ exit 0
15
+ fi
16
+
17
+ echo "📦 Installing Ollama CLI..."
18
+ # Prefer copying the CLI binary from a local Ollama Docker image when available.
19
+ # This avoids downloading large release archives in Docker-enabled environments.
20
+ OLLAMA_IMAGE="ollama/ollama:${OLLAMA_VERSION:-latest}"
21
+ if command_exists docker && docker info >/dev/null 2>&1; then
22
+ tmpdir=$(mktemp -d)
23
+ docker_container_id=""
24
+ trap '[ -n "${docker_container_id}" ] && docker rm -f "${docker_container_id}" >/dev/null 2>&1 || true; rm -rf "${tmpdir}"' EXIT
25
+
26
+ # Guard Docker command substitutions with || fallback so failures here are
27
+ # non-fatal and the archive fallback below can still run.
28
+ container_id="$(docker ps -q --filter "ancestor=${OLLAMA_IMAGE}" 2>/dev/null | head -n 1)" || container_id=""
29
+
30
+ if [ -z "${container_id}" ] && docker image inspect "${OLLAMA_IMAGE}" >/dev/null 2>&1; then
31
+ container_id="$(docker create "${OLLAMA_IMAGE}" 2>/dev/null)" || container_id=""
32
+ [ -n "${container_id}" ] && docker_container_id="${container_id}"
33
+ fi
34
+
35
+ if [ -n "${container_id}" ] && docker cp "${container_id}:/usr/bin/ollama" "${tmpdir}/ollama" >/dev/null 2>&1; then
36
+ echo "📦 Installing Ollama CLI from local Docker image..."
37
+ sudo install -m 0755 "${tmpdir}/ollama" /usr/local/bin/ollama
38
+ fi
39
+
40
+ [ -n "${docker_container_id}" ] && docker rm -f "${docker_container_id}" >/dev/null 2>&1 || true
41
+ docker_container_id=""
42
+ rm -rf "${tmpdir}"
43
+ trap - EXIT
44
+ fi
45
+
46
+ if ! command_exists ollama; then
47
+ # Fallback to official release archives without invoking the full install.sh
48
+ # flow, which configures a local daemon/service.
49
+ OLLAMA_DOWNLOAD_BASE="https://ollama.com/download/ollama-linux-${CS_ARCH}"
50
+
51
+ if curl -fsSLI "${OLLAMA_DOWNLOAD_BASE}.tar.zst" >/dev/null 2>&1; then
52
+ if ! command_exists zstd; then
53
+ echo "📦 Installing zstd for Ollama archive extraction..."
54
+ apt_install zstd
55
+ fi
56
+
57
+ archive_size_bytes="$(
58
+ curl -fsSLI "${OLLAMA_DOWNLOAD_BASE}.tar.zst" |
59
+ awk 'BEGIN { IGNORECASE = 1 } /^content-length:/ { print $2 }' |
60
+ tr -d '\r' |
61
+ tail -n 1
62
+ )"
63
+
64
+ if [ -n "${archive_size_bytes}" ]; then
65
+ archive_size_gib="$(awk "BEGIN { printf \"%.1f\", ${archive_size_bytes} / 1024 / 1024 / 1024 }")"
66
+ echo "⬇️ Downloading official Ollama archive (~${archive_size_gib} GiB)..."
67
+ else
68
+ echo "⬇️ Downloading official Ollama archive..."
69
+ fi
70
+
71
+ tmpdir=$(mktemp -d)
72
+ trap 'rm -rf "${tmpdir}"' EXIT
73
+
74
+ curl --fail --location --progress-bar "${OLLAMA_DOWNLOAD_BASE}.tar.zst" -o "${tmpdir}/ollama.tar.zst"
75
+
76
+ # Match the official Linux package layout so the CLI keeps working even
77
+ # when upstream ships supporting files under lib/ollama alongside the
78
+ # top-level ollama binary.
79
+ echo "📦 Extracting Ollama CLI from archive..."
80
+ sudo rm -rf /usr/local/lib/ollama
81
+ zstd -d -c "${tmpdir}/ollama.tar.zst" | sudo tar -xf - -C /usr/local
82
+ sudo install -d /usr/local/bin
83
+ sudo ln -sf /usr/local/ollama /usr/local/bin/ollama
84
+
85
+ rm -rf "${tmpdir}"
86
+ trap - EXIT
87
+ else
88
+ install_binary_from_tar \
89
+ "${OLLAMA_DOWNLOAD_BASE}.tgz" \
90
+ "bin/ollama" \
91
+ "ollama"
92
+ fi
93
+ fi
94
+
95
+ export PATH="/usr/local/bin:/usr/bin:/bin:${PATH}"
96
+
97
+ if ! command_exists ollama; then
98
+ echo "❌ Ollama CLI install completed but the binary is still not on PATH"
99
+ exit 1
100
+ fi
101
+
102
+ echo "✓ Ollama CLI installed: $(ollama --version)"
103
+ echo "ℹ️ Configure OLLAMA_HOST to target your server (current: ${OLLAMA_HOST:-http://localhost:11434})"
@@ -0,0 +1,49 @@
1
+ #!/bin/bash
2
+ # Verification script for Ollama CLI overlay
3
+
4
+ set -e
5
+
6
+ echo "🔍 Verifying Ollama CLI overlay..."
7
+ echo ""
8
+
9
+ echo "1️⃣ Checking Ollama CLI..."
10
+ if ! command -v ollama &>/dev/null; then
11
+ echo " ❌ ollama CLI not found"
12
+ echo ""
13
+ echo "❌ Ollama CLI overlay verification failed"
14
+ exit 1
15
+ fi
16
+ echo " ✅ ollama CLI found: $(ollama --version 2>/dev/null || echo 'version unavailable')"
17
+
18
+ echo ""
19
+ echo "2️⃣ Checking OLLAMA_HOST configuration..."
20
+ if [[ -z "${OLLAMA_HOST:-}" ]]; then
21
+ echo " ℹ️ OLLAMA_HOST is not set (default CLI target: http://localhost:11434)"
22
+ echo " ℹ️ Set OLLAMA_HOST to a reachable Ollama endpoint, e.g. http://host.docker.internal:11434"
23
+ echo ""
24
+ echo "✅ Ollama CLI overlay verification complete"
25
+ exit 0
26
+ fi
27
+
28
+ echo " ✅ OLLAMA_HOST=${OLLAMA_HOST}"
29
+
30
+ echo ""
31
+ echo "3️⃣ Checking endpoint reachability (best effort)..."
32
+ if ! command -v curl &>/dev/null; then
33
+ echo " ⚠️ curl not found; skipping endpoint check"
34
+ echo ""
35
+ echo "✅ Ollama CLI overlay verification complete"
36
+ exit 0
37
+ fi
38
+
39
+ set +e
40
+ if curl -sf "${OLLAMA_HOST}/api/tags" >/dev/null; then
41
+ echo " ✅ Reached Ollama endpoint at ${OLLAMA_HOST}"
42
+ else
43
+ echo " ⚠️ Could not reach ${OLLAMA_HOST}/api/tags"
44
+ echo " ⚠️ Ensure your Ollama server is running and reachable from the devcontainer"
45
+ fi
46
+ set -e
47
+
48
+ echo ""
49
+ echo "✅ Ollama CLI overlay verification complete"
@@ -0,0 +1,5 @@
1
+ # Open WebUI Configuration
2
+ OPEN_WEBUI_VERSION={{cs.OPEN_WEBUI_VERSION}}
3
+ OPEN_WEBUI_PORT={{cs.OPEN_WEBUI_PORT}}
4
+ OLLAMA_BASE_URL={{cs.OLLAMA_BASE_URL}}
5
+ WEBUI_SECRET_KEY={{cs.WEBUI_SECRET_KEY}}
@@ -0,0 +1,162 @@
1
+ # Open WebUI Overlay
2
+
3
+ Adds [Open WebUI](https://github.com/open-webui/open-webui) as a Docker Compose service, providing a polished browser-based chat interface for Ollama and other OpenAI-compatible LLM backends.
4
+
5
+ ## Features
6
+
7
+ - **Browser-based chat UI** — Full-featured conversational interface for local LLMs at `http://localhost:3000`
8
+ - **Ollama integration** — Pre-configured to connect to the `ollama` sidecar when the `ollama` overlay is also selected
9
+ - **Multi-model support** — Switch between different Ollama models from the UI without CLI commands
10
+ - **Conversation history** — Persists chat history in a named Docker volume across container rebuilds
11
+ - **OpenAI-compatible** — Works with any backend that speaks the OpenAI Chat Completions API
12
+ - **Port 3000** — Web interface auto-forwarded and opened in the browser
13
+
14
+ ## How It Works
15
+
16
+ Open WebUI runs as a Docker Compose service (`open-webui`) alongside your devcontainer. It connects to the Ollama service (or any OpenAI-compatible API) using the `OLLAMA_BASE_URL` environment variable.
17
+
18
+ **Service configuration:**
19
+
20
+ - Image: `ghcr.io/open-webui/open-webui:main`
21
+ - Network: `devnet` (shared with devcontainer and ollama)
22
+ - Port: `3000` on the host, mapped to `8080` inside the container
23
+ - Volume: `open-webui-data` for persistent chat history and settings
24
+
25
+ When used together with the `ollama` overlay, the stack looks like:
26
+
27
+ ```
28
+ devcontainer ─── open-webui (port 3000) ─┐
29
+ ├── devnet
30
+ ollama (port 11434) ─────┘
31
+ ```
32
+
33
+ Open WebUI reads `OLLAMA_BASE_URL` to find the Ollama API. When the `ollama` overlay is selected, this is pre-set to `http://ollama:11434`.
34
+
35
+ ## Common Commands
36
+
37
+ ### Web Interface
38
+
39
+ ```bash
40
+ # Open the web UI (auto-forwarded to localhost:3000)
41
+ # Navigate to http://localhost:3000 in your browser
42
+
43
+ # Check service status
44
+ docker compose ps open-webui
45
+
46
+ # View logs
47
+ docker compose logs open-webui
48
+ docker compose logs -f open-webui
49
+
50
+ # Restart the service
51
+ docker compose restart open-webui
52
+ ```
53
+
54
+ ### Using with Ollama
55
+
56
+ ```bash
57
+ # Pull a model with the Ollama CLI (still available in devcontainer)
58
+ ollama pull llama3.2
59
+
60
+ # The model will automatically appear in the Open WebUI model picker
61
+ # Visit http://localhost:3000 and start chatting
62
+ ```
63
+
64
+ ### REST API
65
+
66
+ Open WebUI exposes an OpenAI-compatible REST API at `http://localhost:3000/api`:
67
+
68
+ ```bash
69
+ # List available models via Open WebUI API
70
+ curl http://localhost:3000/api/models
71
+
72
+ # Chat completion via OpenAI-compatible endpoint
73
+ curl http://localhost:3000/api/chat/completions \
74
+ -H "Content-Type: application/json" \
75
+ -d '{
76
+ "model": "llama3.2",
77
+ "messages": [{"role": "user", "content": "Hello!"}]
78
+ }'
79
+ ```
80
+
81
+ ## Configuration
82
+
83
+ ### Environment Variables
84
+
85
+ Copy `.devcontainer/.env.example` to `.devcontainer/.env` and customize:
86
+
87
+ | Variable | Default | Description |
88
+ | -------------------- | --------------------- | ------------------------------------------------ |
89
+ | `OPEN_WEBUI_VERSION` | `main` | Open WebUI Docker image tag |
90
+ | `OPEN_WEBUI_PORT` | `3000` | Host port for the web interface |
91
+ | `OLLAMA_BASE_URL` | `http://ollama:11434` | Base URL of the Ollama API |
92
+ | `WEBUI_SECRET_KEY` | `supersecret` | Secret key for session signing (change for prod) |
93
+
94
+ ### Connecting to a Different LLM Backend
95
+
96
+ If you are not using the `ollama` overlay but have another OpenAI-compatible API available, set `OLLAMA_BASE_URL` in `.devcontainer/.env`:
97
+
98
+ ```bash
99
+ # Point at a remote OpenAI-compatible server
100
+ OLLAMA_BASE_URL=http://my-llm-server:8000
101
+ ```
102
+
103
+ ## Use Cases
104
+
105
+ - **Local AI chat** — Interact with local models via a polished UI instead of the CLI
106
+ - **Model comparison** — Switch between models mid-conversation to compare quality
107
+ - **Prompt engineering** — Iterate on system prompts and parameters interactively
108
+ - **Offline AI workflows** — Full AI chat capability without internet access or API costs
109
+ - **Team demos** — Share the forwarded port URL with teammates for collaborative testing
110
+
111
+ **Integrates well with:**
112
+
113
+ - `ollama` — Provides the LLM backend; Open WebUI connects automatically
114
+ - `cuda` — GPU acceleration for faster Ollama inference
115
+ - `python` — Build integrations using the Open WebUI REST API
116
+
117
+ ## Troubleshooting
118
+
119
+ ### UI Not Loading
120
+
121
+ ```bash
122
+ # Check the service is running
123
+ docker compose ps open-webui
124
+
125
+ # View startup logs
126
+ docker compose logs open-webui
127
+
128
+ # Restart the service
129
+ docker compose restart open-webui
130
+ ```
131
+
132
+ ### No Models Available
133
+
134
+ If the model picker in Open WebUI shows no models:
135
+
136
+ 1. Ensure the `ollama` overlay is selected and the Ollama service is running
137
+ 2. Pull a model with `ollama pull llama3.2` from the devcontainer terminal
138
+ 3. Refresh the Open WebUI page
139
+
140
+ ```bash
141
+ # Verify Ollama is reachable from within the Open WebUI container
142
+ docker compose exec open-webui curl -sf http://ollama:11434/api/tags
143
+ ```
144
+
145
+ ### Port Conflict on 3000
146
+
147
+ ```bash
148
+ # .devcontainer/.env
149
+ OPEN_WEBUI_PORT=3001
150
+ ```
151
+
152
+ ## References
153
+
154
+ - [Open WebUI GitHub](https://github.com/open-webui/open-webui)
155
+ - [Open WebUI Documentation](https://docs.openwebui.com)
156
+ - [Open WebUI Docker Hub](https://ghcr.io/open-webui/open-webui)
157
+
158
+ **Related Overlays:**
159
+
160
+ - [`ollama`](../ollama/README.md) — Local LLM inference server (recommended companion)
161
+ - [`cuda`](../cuda/README.md) — NVIDIA GPU acceleration for faster inference
162
+ - [`python`](../python/README.md) — Python SDK for building integrations
@@ -0,0 +1,14 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.base.schema.json",
3
+ "runServices": ["open-webui"],
4
+ "forwardPorts": [3000],
5
+ "portsAttributes": {
6
+ "3000": {
7
+ "label": "Open WebUI",
8
+ "onAutoForward": "openBrowser"
9
+ }
10
+ },
11
+ "containerEnv": {
12
+ "OPEN_WEBUI_PORT": "3000"
13
+ }
14
+ }
@@ -0,0 +1,24 @@
1
+ version: '3.8'
2
+
3
+ services:
4
+ open-webui:
5
+ image: ghcr.io/open-webui/open-webui:${OPEN_WEBUI_VERSION:-{{cs.OPEN_WEBUI_VERSION}}}
6
+ restart: unless-stopped
7
+ volumes:
8
+ - open-webui-data:/app/backend/data
9
+ environment:
10
+ OLLAMA_BASE_URL: ${OLLAMA_BASE_URL:-{{cs.OLLAMA_BASE_URL}}}
11
+ WEBUI_SECRET_KEY: ${WEBUI_SECRET_KEY:-{{cs.WEBUI_SECRET_KEY}}}
12
+ ports:
13
+ - '${OPEN_WEBUI_PORT:-{{cs.OPEN_WEBUI_PORT}}}:8080'
14
+ extra_hosts:
15
+ - host.docker.internal:host-gateway
16
+ networks:
17
+ - devnet
18
+
19
+ volumes:
20
+ open-webui-data:
21
+
22
+ networks:
23
+ devnet:
24
+ name: devnet
@@ -0,0 +1,45 @@
1
+ id: open-webui
2
+ name: Open WebUI
3
+ description: Browser-based chat UI for Ollama and OpenAI-compatible LLM backends
4
+ category: dev
5
+ supports:
6
+ - compose
7
+ requires: []
8
+ suggests:
9
+ - ollama
10
+ - prometheus
11
+ - otel-collector
12
+ conflicts:
13
+ - grafana
14
+ - nodejs
15
+ - bun
16
+ - rust
17
+ serviceOrder: 3
18
+ tags:
19
+ - dev
20
+ - ai
21
+ - llm
22
+ - ui
23
+ - chat
24
+ - openwebui
25
+ ports:
26
+ - port: 3000
27
+ service: open-webui
28
+ protocol: http
29
+ path: /
30
+ description: Open WebUI web interface
31
+ onAutoForward: openBrowser
32
+ parameters:
33
+ OPEN_WEBUI_VERSION:
34
+ description: Open WebUI Docker image tag
35
+ default: main
36
+ OPEN_WEBUI_PORT:
37
+ description: Host port mapped to the Open WebUI web interface (8080 inside container)
38
+ default: '3000'
39
+ OLLAMA_BASE_URL:
40
+ description: Base URL of the Ollama API (leave default when using the ollama overlay)
41
+ default: 'http://ollama:11434'
42
+ WEBUI_SECRET_KEY:
43
+ description: Secret key for Open WebUI session signing (change for any shared environment)
44
+ default: change-me-please
45
+ sensitive: true
@@ -1,3 +1,6 @@
1
1
  {
2
- "$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.base.schema.json"
2
+ "$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.base.schema.json",
3
+ "postCreateCommand": {
4
+ "setup-opencode": "bash .devcontainer/scripts/setup-opencode.sh"
5
+ }
3
6
  }
@@ -45,6 +45,10 @@ graph TD
45
45
  - `8889` - Prometheus exporter endpoint (scrape target)
46
46
  - `13133` - Health check extension
47
47
 
48
+ ### Pre-configured OpenTelemetry Environment
49
+
50
+ When this overlay is selected, the devcontainer's `OTEL_EXPORTER_OTLP_ENDPOINT` is automatically set to `http://otel-collector:4317` so that any properly-instrumented app sends telemetry to the collector. If the **jaeger** overlay is also selected, the collector overlay takes precedence (it is applied later) and correctly routes telemetry through the collector pipeline to Jaeger.
51
+
48
52
  ### Environment Variables
49
53
 
50
54
  The overlay includes a `.env.example` file. Copy it to `.env` and customize:
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.base.schema.json",
3
3
  "runServices": ["otel-collector"],
4
- "_serviceOrder": 2,
5
4
  "forwardPorts": [4317, 4318, 8888, 8889, 13133],
6
5
  "portsAttributes": {
7
6
  "4317": {
@@ -24,5 +23,9 @@
24
23
  "label": "Health Check",
25
24
  "onAutoForward": "silent"
26
25
  }
26
+ },
27
+ "remoteEnv": {
28
+ "OTEL_EXPORTER_OTLP_ENDPOINT": "http://otel-collector:4317",
29
+ "OTEL_EXPORTER_OTLP_PROTOCOL": "grpc"
27
30
  }
28
31
  }
@@ -2,6 +2,7 @@ version: '3.8'
2
2
  services:
3
3
  otel-collector:
4
4
  image: otel/opentelemetry-collector-contrib:${OTEL_COLLECTOR_VERSION:-latest}
5
+ restart: unless-stopped
5
6
  command: ['--config=/etc/otel-collector-config.yaml']
6
7
  volumes:
7
8
  - ./otel-collector-config-otel-collector.yaml:/etc/otel-collector-config.yaml
@@ -11,12 +12,15 @@ services:
11
12
  - '${OTEL_METRICS_PORT:-8888}:8888' # Prometheus metrics exposed by collector
12
13
  - '${OTEL_EXPORTER_PORT:-8889}:8889' # Prometheus exporter
13
14
  - '${OTEL_HEALTH_PORT:-13133}:13133' # health_check extension
14
- depends_on:
15
- - jaeger
16
- - prometheus
17
- - loki
18
15
  networks:
19
16
  - devnet
17
+ healthcheck:
18
+ test: ['CMD', 'wget', '-qO-', 'http://localhost:13133/']
19
+ interval: 10s
20
+ timeout: 5s
21
+ retries: 5
22
+ start_period: 10s
20
23
 
21
24
  networks:
22
25
  devnet:
26
+ name: devnet
@@ -19,5 +19,6 @@ ports:
19
19
  - 8888
20
20
  - 8889
21
21
  order: 2
22
+ serviceOrder: 2
22
23
  imports:
23
24
  - .shared/otel/instrumentation.env
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.base.schema.json",
3
3
  "runServices": ["otel-demo-nodejs"],
4
- "_serviceOrder": 3,
5
4
  "forwardPorts": [8080],
6
5
  "portsAttributes": {
7
6
  "8080": {
@@ -17,3 +17,4 @@ services:
17
17
 
18
18
  networks:
19
19
  devnet:
20
+ name: devnet
@@ -12,7 +12,14 @@ suggests:
12
12
  - prometheus
13
13
  - loki
14
14
  - grafana
15
- conflicts: []
15
+ conflicts:
16
+ - mysql
17
+ - redpanda
18
+ - nodejs
19
+ - bun
20
+ - go
21
+ - java
22
+ - dotnet
16
23
  tags:
17
24
  - observability
18
25
  - demo
@@ -21,3 +28,4 @@ tags:
21
28
  ports:
22
29
  - 8080
23
30
  order: 4
31
+ serviceOrder: 4
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.base.schema.json",
3
3
  "runServices": ["otel-demo-python"],
4
- "_serviceOrder": 3,
5
4
  "forwardPorts": [8081],
6
5
  "portsAttributes": {
7
6
  "8081": {
@@ -17,3 +17,4 @@ services:
17
17
 
18
18
  networks:
19
19
  devnet:
20
+ name: devnet
@@ -12,7 +12,11 @@ suggests:
12
12
  - prometheus
13
13
  - loki
14
14
  - grafana
15
- conflicts: []
15
+ conflicts:
16
+ - mongodb
17
+ - redpanda
18
+ - go
19
+ - java
16
20
  tags:
17
21
  - observability
18
22
  - demo
@@ -21,3 +25,4 @@ tags:
21
25
  ports:
22
26
  - 8081
23
27
  order: 4
28
+ serviceOrder: 4
@@ -116,6 +116,16 @@ variables:
116
116
  header-includes:
117
117
  - |
118
118
  \usepackage{etoolbox}
119
+ \ifdefined\IfFontExistsTF
120
+ \IfFontExistsTF{Noto Sans Symbols 2}{%
121
+ \newfontfamily\textfallbackfont{Noto Sans Symbols 2}%
122
+ \newcommand{\textfallback}[1]{{\textfallbackfont #1}}%
123
+ }{%
124
+ \newcommand{\textfallback}[1]{#1}%
125
+ }
126
+ \else
127
+ \newcommand{\textfallback}[1]{#1}%
128
+ \fi
119
129
  \setlength{\tabcolsep}{3pt}
120
130
  \renewcommand{\arraystretch}{1.05}
121
131
  \AtBeginEnvironment{longtable}{\small}
@@ -6,11 +6,6 @@
6
6
  "apk": "fontconfig noto-fonts-emoji|noto-emoji perl chromium"
7
7
  }
8
8
  },
9
- "customizations": {
10
- "vscode": {
11
- "extensions": ["yzhang.markdown-all-in-one", "DavidAnson.vscode-markdownlint"]
12
- }
13
- },
14
9
  "remoteEnv": {
15
10
  "PUPPETEER_EXECUTABLE_PATH": "/usr/local/bin/chromium-no-sandbox",
16
11
  "PUPPETEER_SKIP_DOWNLOAD": "true"
@@ -15,5 +15,7 @@ tags:
15
15
  - markdown
16
16
  - docs
17
17
  - mermaid
18
+ imports:
19
+ - .shared/vscode/markdown-extensions.json
18
20
  ports: []
19
21
  order: 25
@@ -275,6 +275,16 @@ variables:
275
275
  header-includes:
276
276
  - |
277
277
  \usepackage{etoolbox}
278
+ \ifdefined\IfFontExistsTF
279
+ \IfFontExistsTF{Noto Sans Symbols 2}{%
280
+ \newfontfamily\textfallbackfont{Noto Sans Symbols 2}%
281
+ \newcommand{\textfallback}[1]{{\textfallbackfont #1}}%
282
+ }{%
283
+ \newcommand{\textfallback}[1]{#1}%
284
+ }
285
+ \else
286
+ \newcommand{\textfallback}[1]{#1}%
287
+ \fi
278
288
  \setlength{\tabcolsep}{3pt}
279
289
  \renewcommand{\arraystretch}{1.05}
280
290
  \AtBeginEnvironment{longtable}{\small}
@@ -0,0 +1,6 @@
1
+ # pgvector Configuration
2
+ PGVECTOR_VERSION={{cs.PGVECTOR_VERSION}}
3
+ PGVECTOR_DB={{cs.PGVECTOR_DB}}
4
+ PGVECTOR_USER={{cs.PGVECTOR_USER}}
5
+ PGVECTOR_PASSWORD={{cs.PGVECTOR_PASSWORD}}
6
+ PGVECTOR_PORT={{cs.PGVECTOR_PORT}}