fix: phase 0 quick wins — safety, naming, and portability

- Add helm.sh/resource-policy: keep to PVC (prevent data loss on uninstall)
- Add fail guard for empty name value in Helm templates
- Fix Makefile IMAGE_NAME from antigravity to devcontainer
- Pin busybox:1.37, homeassistant:v6.7.1, playwright:v0.0.68 (was latest/stable)
- Set imagePullPolicy: IfNotPresent on pinned sidecars
- Remove fetch/sequentialthinking from .mcp.json (sidecars removed from chart)
- Default storage.className to empty (use cluster default, was ceph-filesystem)
- Default Happy Coder URLs to empty (was private farh.net endpoints)
- Broaden githubRepo schema to accept GitLab/Gitea URLs
- Add unknown IDE warning before VSCode fallback
- Add mkdir -p before credential file write (fix fresh PVC boot)
- Guard app user existence in cont-init-user.sh
- Add NOTES.txt post-install template with port-forward and secret hints
- Add standard app.kubernetes.io/* labels and separate selectorLabels

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
DevContainer User
2026-02-24 04:13:24 +00:00
parent adb2ee4817
commit c8a7bbcd6e
11 changed files with 81 additions and 32 deletions
+31
View File
@@ -0,0 +1,31 @@
Dev Container "{{ .Values.name }}" has been deployed.
{{- if ne (.Values.ide.type | default "vscode") "none" }}
Access the IDE:
kubectl port-forward deployment/{{ include "devcontainer.fullname" . }} 5800:5800 -n {{ .Release.Namespace }}
Then open: http://localhost:5800
{{- end }}
{{- if .Values.ssh.enabled }}
SSH access:
kubectl port-forward deployment/{{ include "devcontainer.fullname" . }} 2222:22 -n {{ .Release.Namespace }}
Then: ssh -p 2222 user@localhost
{{- end }}
Useful commands:
Logs: kubectl logs -f deployment/{{ include "devcontainer.fullname" . }} -n {{ .Release.Namespace }}
Shell: kubectl exec -it deployment/{{ include "devcontainer.fullname" . }} -n {{ .Release.Namespace }} -- bash
{{- if not (lookup "v1" "Secret" .Release.Namespace (include "devcontainer.envSecretName" .)) }}
Optional: Create a secret for GITHUB_TOKEN, VNC_PASSWORD, etc:
kubectl create secret generic {{ include "devcontainer.envSecretName" . }} \
--from-literal=GITHUB_TOKEN=ghp_xxx \
--from-literal=VNC_PASSWORD=changeme \
-n {{ .Release.Namespace }}
{{- end }}
Note: The PVC "{{ include "devcontainer.pvcName" . }}" is protected from deletion on helm uninstall.
To remove it manually: kubectl delete pvc {{ include "devcontainer.pvcName" . }} -n {{ .Release.Namespace }}
+15
View File
@@ -2,6 +2,9 @@
Resource name prefix: devcontainer-{name}
*/}}
{{- define "devcontainer.fullname" -}}
{{- if not .Values.name }}
{{- fail "values.name is required and must not be empty" }}
{{- end }}
{{- printf "devcontainer-%s" .Values.name }}
{{- end }}
@@ -25,6 +28,18 @@ Common labels
{{- define "devcontainer.labels" -}}
app: devcontainer
instance: {{ .Values.name }}
app.kubernetes.io/name: devcontainer
app.kubernetes.io/instance: {{ .Values.name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
{{- end }}
{{/*
Selector labels keep narrow since changing these requires recreating the Deployment
*/}}
{{- define "devcontainer.selectorLabels" -}}
app: devcontainer
instance: {{ .Values.name }}
{{- end }}
{{/*
+5 -5
View File
@@ -8,7 +8,7 @@ spec:
replicas: 1
selector:
matchLabels:
{{- include "devcontainer.labels" . | nindent 6 }}
{{- include "devcontainer.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
@@ -23,7 +23,7 @@ spec:
{{- if and .Values.ide.type (eq .Values.ide.type "antigravity") }}
initContainers:
- name: setup-userdata
image: busybox:latest
image: busybox:1.37
command: ['sh', '-c']
args:
- |
@@ -169,7 +169,7 @@ spec:
{{- if .Values.mcp.sidecars.homeassistant.enabled }}
- name: homeassistant-mcp
image: "{{ .Values.mcp.sidecars.homeassistant.image.repository }}:{{ .Values.mcp.sidecars.homeassistant.image.tag }}"
imagePullPolicy: Always
imagePullPolicy: IfNotPresent
command: ["fastmcp", "run", "--transport", "sse", "--host", "0.0.0.0", "--port", "{{ .Values.mcp.sidecars.homeassistant.port }}"]
ports:
- name: homeassistant
@@ -203,7 +203,7 @@ spec:
{{- if .Values.mcp.sidecars.pgtuner.enabled }}
- name: pgtuner-mcp
image: "{{ .Values.mcp.sidecars.pgtuner.image.repository }}:{{ .Values.mcp.sidecars.pgtuner.image.tag }}"
imagePullPolicy: Always
imagePullPolicy: Always # pgtuner uses `latest` tag (no versioned releases available)
command: ["python", "-m", "pgtuner_mcp", "--mode", "sse", "--host", "0.0.0.0", "--port", "{{ .Values.mcp.sidecars.pgtuner.port }}"]
ports:
- name: pgtuner
@@ -237,7 +237,7 @@ spec:
{{- if .Values.mcp.sidecars.playwright.enabled }}
- name: playwright-mcp
image: "{{ .Values.mcp.sidecars.playwright.image.repository }}:{{ .Values.mcp.sidecars.playwright.image.tag }}"
imagePullPolicy: Always
imagePullPolicy: IfNotPresent
command: ["node"]
args:
- cli.js
+4
View File
@@ -2,12 +2,16 @@ apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "devcontainer.pvcName" . }}
annotations:
helm.sh/resource-policy: keep
labels:
{{- include "devcontainer.labels" . | nindent 4 }}
spec:
accessModes:
- ReadWriteMany
{{- if .Values.storage.className }}
storageClassName: {{ .Values.storage.className }}
{{- end }}
resources:
requests:
storage: {{ .Values.storage.size }}
+3 -5
View File
@@ -35,7 +35,7 @@
"githubRepo": {
"type": "string",
"description": "GitHub repository URL to clone",
"pattern": "^https://github\\.com/.+/.+$"
"pattern": "^https?://.+/.+/.+$"
},
"ide": {
"type": "object",
@@ -108,7 +108,7 @@
"description": "Storage class name (must support ReadWriteMany)"
}
},
"required": ["size", "className"]
"required": ["size"]
},
"resources": {
"type": "object",
@@ -143,12 +143,10 @@
"properties": {
"serverUrl": {
"type": "string",
"format": "uri",
"description": "Happy Coder server URL"
},
"webappUrl": {
"type": "string",
"format": "uri",
"description": "Happy Coder webapp URL"
},
"homeDir": {
@@ -161,7 +159,7 @@
"description": "Enable experimental Happy features"
}
},
"required": ["serverUrl", "webappUrl", "homeDir", "experimental"]
"required": ["homeDir", "experimental"]
},
"mcp": {
"type": "object",
+5 -5
View File
@@ -45,7 +45,7 @@ user:
# Storage configuration
storage:
size: 32Gi
className: ceph-filesystem
className: "" # Empty string uses the cluster's default StorageClass (must support ReadWriteMany)
# Resource allocation
resources:
@@ -70,8 +70,8 @@ clusterAccess: none
# Happy Coder AI assistant configuration
happy:
serverUrl: "https://happy.farh.net"
webappUrl: "https://happy-coder.farh.net"
serverUrl: ""
webappUrl: ""
homeDir: "/config/userdata/.happy"
experimental: "true"
@@ -115,7 +115,7 @@ mcp:
enabled: false # Requires HOMEASSISTANT_URL and HOMEASSISTANT_TOKEN
image:
repository: ghcr.io/homeassistant-ai/ha-mcp
tag: stable
tag: v6.7.1
port: 8087
resources:
requests:
@@ -145,7 +145,7 @@ mcp:
enabled: true
image:
repository: mcr.microsoft.com/playwright/mcp
tag: latest
tag: v0.0.68
port: 8086
resources:
requests: