Compare commits

..

15 Commits

Author SHA1 Message Date
github-actions[bot] fbcd9c1f72 chore: release version 0.3.0 2026-02-22 16:27:17 +00:00
DevContainer User 3be59e56eb docs: add Claude Code to documented AI coding agents
Claude Code was already installed via npm (line 65 of Dockerfile) but
was missing from the feature lists in README.md and CLAUDE.md.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-22 16:25:46 +00:00
DevContainer User be9479ef75 feat: add OpenCode and Crush AI coding agents to Docker image
Install both terminal-based AI coding agents alongside Happy Coder:
- OpenCode (opencode-ai/opencode) - open-source AI coding agent
- Crush (charmbracelet/crush) - OpenCode's active successor by Charm

Both are installed as Go binaries to /usr/local/bin from latest GitHub
releases and available to users via `opencode` and `crush` commands.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-22 16:24:19 +00:00
DevContainer User 065a6534e3 docs: comprehensive updates for new Helm chart structure
Major documentation updates to reflect the reorganized Helm chart:

- Update README.md and CLAUDE.md to use new mcp.sidecars structure
- Reflect removal of Happy daemon automatic startup
- Document new logical values organization (Basic → Access → Infrastructure → Integrations → Smart Defaults)
- Update all MCP sidecar examples to use mcp.sidecars instead of mcpSidecars
- Document new quickstart deployment options and progressive disclosure
- Update troubleshooting sections with current configurations
- Standardize all secret environment variable references to SCREAMING_SNAKE_CASE

This completes the documentation sync following the major Helm chart
user experience improvements implemented in previous commits.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-22 13:32:49 +00:00
DevContainer User d8d83ffa47 feat: major Helm chart user-friendliness improvements
Implements comprehensive enhancements to make the Helm chart more user-friendly
and easier to deploy across different scenarios.

🎯 **IMPLEMENTED IMPROVEMENTS:**

**1. Values Organization & Grouping**
- Reorganized values.yaml with logical sections:
  - Basic Configuration (name, image, githubRepo)
  - Access & Interface (ide, ssh, display, user)
  - Infrastructure & Resources (storage, resources, shm, clusterAccess)
  - Integrations (happy, mcp sidecars)
  - Smart Defaults & Auto-Detection
- Updated deployment templates to use new structure
- Maintains clean, navigable configuration

**2. Simplified Quick-Start Values**
- Added values-quickstart.yaml for 80% of users
- Just 2 required fields: name + githubRepo
- Includes usage instructions and common customizations
- Copy-paste ready deployment experience

**3. Better Documentation Structure**
- Added values.schema.json for IDE validation and autocomplete
- Created comprehensive USAGE.md with real-world examples:
  - Development, team, K8s admin, AI/ML, lightweight scenarios
  - Secret configuration examples
  - Resource sizing by use case
  - Common troubleshooting patterns

**4. Smart Defaults & Auto-Detection**
- Added template helpers for intelligent resource sizing
- Environment auto-detection based on naming patterns
- Smart MCP sidecar selection based on cluster access
- Resource profile auto-selection (auto/small/medium/large/xlarge)
- Enhanced _helpers.tpl with smart default functions

🎫 **CREATED GITHUB ISSUES** for future enhancements:
- #32: Helm chart preset profiles
- #33: Split large deployment.yaml template
- #34: Advanced auto-detection for Kubernetes environments
- #35: Specialized Helm chart variants (basic/team/k8s/ai)
- #36: Installation and configuration helper scripts
- #37: Comprehensive validation and health monitoring
- #38: User experience improvements with better error messages
- #39: Comprehensive examples and template library

📊 **IMPACT:**
- Reduced required configuration from ~20 values to 2 essential fields
- Added IDE support with schema validation
- Created guided examples for common scenarios
- Established foundation for advanced auto-detection
- Planned comprehensive tooling ecosystem

🚀 **USAGE:**
```bash
# Quick start (new users)
cp chart/values-quickstart.yaml my-values.yaml
# Edit name and githubRepo
helm install mydev ./chart -f my-values.yaml

# Full customization (power users)
# Edit chart/values.yaml with organized sections
helm install mydev ./chart
```

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-22 13:16:08 +00:00
DevContainer User 9535886945 feat: remove automatic Happy daemon startup
Removes unreliable automatic Happy Coder daemon startup, allowing users
to start it manually when needed for better reliability and control.

**Changes:**
- scripts/init-repo.sh: Removed Happy daemon startup code and lock cleanup
- scripts/startapp.sh: Updated comment to reflect init-repo only handles git
- README.md: Updated startup flow documentation and troubleshooting section
- CLAUDE.md: Updated startup flow and file descriptions

**Benefits:**
- No more unreliable automatic daemon startup failures
- Users can start Happy daemon manually when needed: `happy daemon start`
- Cleaner container startup without Happy-related delays or errors
- Happy configuration and credentials still persist on PVC when used

**Usage:**
Users can now manually start Happy Coder when needed:
```bash
happy daemon start  # Start when needed
happy daemon status # Check status
happy daemon stop   # Stop if needed
```

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-22 13:01:19 +00:00
DevContainer User 44f30ec03f fix: standardize secret key names to SCREAMING_SNAKE_CASE
Fixes inconsistent variable naming across the codebase by standardizing
all secret keys to use SCREAMING_SNAKE_CASE format.

**Changes:**
- homeassistant-url → HOMEASSISTANT_URL
- homeassistant-token → HOMEASSISTANT_TOKEN
- database-uri → DATABASE_URI
- pgtuner-exclude-userids → PGTUNER_EXCLUDE_USERIDS
- github-token → GITHUB_TOKEN

**Files updated:**
- chart/templates/deployment.yaml - Fixed secret key references
- README.md - Updated documentation and examples

**Result:**
All secret keys now follow the established SCREAMING_SNAKE_CASE
convention (GITHUB_TOKEN, VNC_PASSWORD, SSH_AUTHORIZED_KEYS, etc.)
for consistency and clarity.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-22 12:59:16 +00:00
DevContainer User 76391a8ed0 feat: major improvements to dev container and MCP sidecars
This commit addresses multiple GitHub issues and adds significant enhancements:

🔧 **Issue #8 - Browser Window Title Fix**
- Updated browser window title from "Antigravity Dev Container" to "Dev Container"
- Changed APP_NAME in Dockerfile and startup script for consistency

🚀 **Issue #30 - PostgreSQL Tuner MCP Sidecar**
- Added PostgreSQL performance tuning MCP sidecar (dog830228/pgtuner_mcp)
- Provides AI assistant with database analysis capabilities:
  - Slow query analysis and optimization suggestions
  - Index recommendations with HypoPG virtual testing
  - Table and index bloat detection
  - Vacuum operation tracking and health scoring
- Requires DATABASE_URI in env secret, optional PGTUNER_EXCLUDE_USERIDS
- Disabled by default, configurable via mcpSidecars.pgtuner.enabled
- Updated CLAUDE.md documentation with full configuration examples

🎭 **Playwright: Centralized Service → Sidecar Conversion**
- Converted Playwright from external service to self-contained sidecar
- Updated .mcp.json endpoint: cluster service → http://localhost:8086/sse
- Added deployment configuration with proper health checks
- Enabled by default for immediate browser automation capabilities
- Higher resource allocation (512Mi memory, 1 CPU) for browser workloads

📚 **Documentation Updates**
- Updated README.md: "Antigravity Dev Container" → "Dev Container"
- Added comprehensive MCP sidecars documentation
- Updated secret keys table with database-uri and pgtuner-exclude-userids
- Added configuration examples for all 6 MCP sidecars:
  - kubernetes-mcp (enabled)
  - flux-mcp (enabled)
  - github-mcp (disabled - archived)
  - homeassistant-mcp (disabled - needs secrets)
  - pgtuner-mcp (disabled - needs DATABASE_URI)
  - playwright-mcp (enabled - browser automation)
- Updated CLAUDE.md with complete sidecar reference table
- Added Helm deployment examples and troubleshooting

🏗️ **Architecture Improvements**
- All MCP sidecars now self-contained within pod
- Consistent SSE transport configuration across all sidecars
- Proper health checks and resource limits for all services
- Simplified deployment with no external service dependencies

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-22 12:55:17 +00:00
github-actions[bot] ac1e5074b1 chore: release version 0.2.5 2026-02-22 12:37:45 +00:00
DevContainer User 2a63f227f1 change default value 2026-02-22 12:36:21 +00:00
DevContainer User 5da23def5b fix: add automatic release workflow for tag-based releases
- Triggers on tag pushes (v*) to create GitHub releases
- Publishes Helm chart to OCI registry
- Generates release notes with commit history
- Complements existing build-and-push workflow

Now releases are fully automated:
1. Push tag → build-and-push.yaml builds Docker images
2. Push tag → release.yaml creates GitHub release + publishes Helm chart

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-21 21:17:37 +00:00
DevContainer User 5532eee8cd chore: release version 0.2.4
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-21 19:13:41 +00:00
DevContainer User d32e453f93 feat: add PostgreSQL tuner (pgtuner) MCP sidecar
- Add pgtuner MCP sidecar configuration (disabled by default)
- Supports PostgreSQL performance tuning and optimization
- Analyzes slow queries, recommends indexes, detects bloat
- Requires DATABASE_URI secret to be configured
- Runs in SSE mode on port 8085

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-21 19:11:50 +00:00
DevContainer User f95e8877e8 chore: release version 0.2.3
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-21 17:31:09 +00:00
DevContainer User 46267b6e26 fix: resolve antigravity IDE init and homeassistant MCP issues (fixes #27, #28)
- Fix homeassistant MCP sidecar command by removing incorrect module specification
- Add init container for antigravity IDE to create /config/userdata directory
- Bump chart version to 0.2.2

The homeassistant sidecar was failing with "File not found: /app/ha_mcp.main"
because fastmcp should run without explicit module specification.

The antigravity IDE was failing to initialize due to missing /config/userdata
directory. Added an init container to ensure the directory exists with proper
permissions before the main container starts.

Generated with Claude Code via Happy

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-02-21 17:29:38 +00:00
14 changed files with 1316 additions and 199 deletions
+86
View File
@@ -0,0 +1,86 @@
name: Release
on:
push:
tags:
- 'v*'
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Helm
uses: azure/setup-helm@v4
- name: Extract version from tag
id: version
run: |
TAG=${GITHUB_REF#refs/tags/}
VERSION=${TAG#v}
echo "tag=${TAG}" >> $GITHUB_OUTPUT
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "🚀 Creating release for ${TAG}"
- name: Package and Push Helm Chart
run: |
helm registry login ghcr.io \
--username ${{ github.actor }} \
--password ${{ secrets.GITHUB_TOKEN }}
helm package chart/
helm push devcontainer-${{ steps.version.outputs.version }}.tgz oci://ghcr.io/cpfarhood/charts
- name: Generate Release Notes
id: notes
run: |
# Get commits since last tag
PREV_TAG=$(git describe --tags --abbrev=0 ${{ steps.version.outputs.tag }}^ 2>/dev/null || echo "")
if [ -z "$PREV_TAG" ]; then
COMMITS=$(git log --pretty=format:"- %s (%h)" ${{ steps.version.outputs.tag }})
else
COMMITS=$(git log --pretty=format:"- %s (%h)" ${PREV_TAG}..${{ steps.version.outputs.tag }})
fi
cat << EOF > release-notes.md
## 🚀 Release ${{ steps.version.outputs.version }}
### Changes
${COMMITS}
### Docker Image
\`\`\`bash
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.tag }}
\`\`\`
### Helm Chart
\`\`\`bash
helm install devcontainer oci://ghcr.io/cpfarhood/charts/devcontainer --version ${{ steps.version.outputs.version }}
\`\`\`
EOF
echo "notes<<EOF" >> $GITHUB_OUTPUT
cat release-notes.md >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Create GitHub Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.version.outputs.tag }}
release_name: Release ${{ steps.version.outputs.tag }}
body: ${{ steps.notes.outputs.notes }}
draft: false
prerelease: false
+13 -10
View File
@@ -1,5 +1,12 @@
{ {
"mcpServers": { "mcpServers": {
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": {
"Authorization": "Bearer ${GITHUB_TOKEN}"
}
},
"kubernetes": { "kubernetes": {
"type": "sse", "type": "sse",
"url": "http://localhost:8080/sse" "url": "http://localhost:8080/sse"
@@ -8,18 +15,14 @@
"type": "sse", "type": "sse",
"url": "http://localhost:8081/sse" "url": "http://localhost:8081/sse"
}, },
"homeassistant": {
"type": "sse",
"url": "http://localhost:8087/sse"
},
"github": {
"type": "sse",
"url": "http://localhost:8088/sse"
},
"playwright": { "playwright": {
"type": "sse", "type": "sse",
"url": "http://playwright-mcp.playwright.svc.cluster.local:3000/sse" "url": "http://localhost:8086/sse"
} },
"pgtuner": {
"type": "sse",
"url": "http://localhost:8085/sse"
}
} }
} }
+34 -13
View File
@@ -4,11 +4,12 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Project Overview ## Project Overview
Antigravity is a Docker-based cloud development environment that provides: The Dev Container is a Docker-based cloud development environment that provides:
- Web-based GUI IDE (VSCode/Antigravity) via VNC on port 5800 - Web-based GUI IDE (VSCode/Antigravity) via VNC on port 5800
- Happy Coder AI assistant integration - Claude Code, Happy Coder, OpenCode, and Crush AI coding agents (terminal-based)
- Automatic GitHub repository cloning on startup - Automatic GitHub repository cloning on startup
- Kubernetes-native deployment with persistent home storage - Kubernetes-native deployment with persistent home storage
- MCP (Model Context Protocol) sidecars for AI assistant integrations
The stack is primarily **Bash scripts + YAML** — there is no Node.js package, compiled language, or test framework. The stack is primarily **Bash scripts + YAML** — there is no Node.js package, compiled language, or test framework.
@@ -60,7 +61,6 @@ Container start
→ scripts/init-repo.sh → scripts/init-repo.sh
→ Configure git user & credentials → Configure git user & credentials
→ Clone GITHUB_REPO (if set) → Clone GITHUB_REPO (if set)
→ Start Happy Coder
→ Launch VSCode as user `user` in /workspace → Launch VSCode as user `user` in /workspace
``` ```
@@ -68,8 +68,8 @@ Container start
| File | Purpose | | File | Purpose |
|------|---------| |------|---------|
| `Dockerfile` | Image definition — installs Chrome, Node.js, VSCode, Happy Coder; creates non-root user (UID 1000) | | `Dockerfile` | Image definition — installs Chrome, Node.js, VSCode, Claude Code, Happy Coder, OpenCode, Crush; creates non-root user (UID 1000) |
| `scripts/init-repo.sh` | Configures git credentials, clones GitHub repo, starts Happy Coder background service | | `scripts/init-repo.sh` | Configures git credentials, clones GitHub repo |
| `scripts/startapp.sh` | Calls init-repo.sh then opens VSCode in the workspace | | `scripts/startapp.sh` | Calls init-repo.sh then opens VSCode in the workspace |
| `chart/` | Helm chart for Kubernetes deployment | | `chart/` | Helm chart for Kubernetes deployment |
| `chart/templates/deployment.yaml` | Deployment spec — main container + MCP sidecar containers | | `chart/templates/deployment.yaml` | Deployment spec — main container + MCP sidecar containers |
@@ -88,15 +88,18 @@ MCP (Model Context Protocol) servers run as sidecar containers in the pod, enabl
|---------|-------|---------|------|----------|---------| |---------|-------|---------|------|----------|---------|
| `kubernetes-mcp` | `quay.io/containers/kubernetes_mcp_server` | v0.0.57 | 8080 | `http://localhost:8080/sse` | Enabled | | `kubernetes-mcp` | `quay.io/containers/kubernetes_mcp_server` | v0.0.57 | 8080 | `http://localhost:8080/sse` | Enabled |
| `flux-mcp` | `ghcr.io/controlplaneio-fluxcd/flux-operator-mcp` | v0.41.1 | 8081 | `http://localhost:8081/sse` | Enabled | | `flux-mcp` | `ghcr.io/controlplaneio-fluxcd/flux-operator-mcp` | v0.41.1 | 8081 | `http://localhost:8081/sse` | Enabled |
| `github-mcp` | `ghcr.io/modelcontextprotocol/servers/github` | latest | 8088 | `http://localhost:8088/sse` | Enabled | | `github-mcp` | `ghcr.io/modelcontextprotocol/servers/github` | latest | 8088 | `http://localhost:8088/sse` | Disabled |
| `homeassistant-mcp` | `ghcr.io/homeassistant-ai/ha-mcp` | 6.7.1 | 8087 | `http://localhost:8087/sse` | Disabled | | `homeassistant-mcp` | `ghcr.io/homeassistant-ai/ha-mcp` | stable | 8087 | `http://localhost:8087/sse` | Disabled |
| `pgtuner-mcp` | `dog830228/pgtuner_mcp` | latest | 8085 | `http://localhost:8085/sse` | Disabled |
| `playwright-mcp` | `microsoft/playwright-mcp` | latest | 8086 | `http://localhost:8086/sse` | Enabled |
**Note:** **Note:**
- Kubernetes and Flux sidecars require `clusterAccess` != `none` to be deployed (they need RBAC permissions) - Kubernetes and Flux sidecars require `clusterAccess` != `none` to be deployed (they need RBAC permissions)
- Kubernetes and Flux sidecars inherit the pod's ServiceAccount RBAC permissions - Kubernetes and Flux sidecars inherit the pod's ServiceAccount RBAC permissions
- GitHub sidecar uses `GITHUB_TOKEN` from the env secret (same token used for repo cloning) - GitHub sidecar uses `GITHUB_TOKEN` from the env secret (same token used for repo cloning)
- Home Assistant sidecar requires `HOMEASSISTANT_URL` and `HOMEASSISTANT_TOKEN` in the env secret - Home Assistant sidecar requires `HOMEASSISTANT_URL` and `HOMEASSISTANT_TOKEN` in the env secret
- Playwright MCP remains an external service - PostgreSQL tuner sidecar requires `DATABASE_URI` in the env secret (PostgreSQL connection string)
- Playwright sidecar provides browser automation and web testing capabilities
#### Enabling/Disabling MCP Servers #### Enabling/Disabling MCP Servers
@@ -104,7 +107,8 @@ To control MCP sidecars, set the `enabled` flag in your values override:
```yaml ```yaml
# Disable all MCP sidecars # Disable all MCP sidecars
mcpSidecars: mcp:
sidecars:
kubernetes: kubernetes:
enabled: false enabled: false
flux: flux:
@@ -113,9 +117,14 @@ mcpSidecars:
enabled: false enabled: false
homeassistant: homeassistant:
enabled: false enabled: false
pgtuner:
enabled: false
playwright:
enabled: false
# Or selectively enable/disable # Or selectively enable/disable
mcpSidecars: mcp:
sidecars:
kubernetes: kubernetes:
enabled: true # Keep Kubernetes MCP enabled enabled: true # Keep Kubernetes MCP enabled
flux: flux:
@@ -124,14 +133,26 @@ mcpSidecars:
enabled: true # Keep GitHub MCP enabled (uses GITHUB_TOKEN) enabled: true # Keep GitHub MCP enabled (uses GITHUB_TOKEN)
homeassistant: homeassistant:
enabled: true # Enable Home Assistant MCP (requires secrets) enabled: true # Enable Home Assistant MCP (requires secrets)
pgtuner:
enabled: true # Enable PostgreSQL tuner MCP (requires DATABASE_URI)
playwright:
enabled: true # Enable Playwright MCP for browser automation
``` ```
When deploying via Helm: When deploying via Helm:
```bash ```bash
# Using --set flag # Quick start (recommended)
helm install my-devcontainer ./chart --set mcpSidecars.kubernetes.enabled=false --set mcpSidecars.flux.enabled=false cp chart/values-quickstart.yaml my-values.yaml
# Edit name and githubRepo in my-values.yaml
helm install my-devcontainer ./chart -f my-values.yaml
# Or with a values file # Using --set flags
helm install my-devcontainer ./chart \
--set name=mydev \
--set githubRepo=https://github.com/user/repo \
--set mcp.sidecars.kubernetes.enabled=false
# Full customization
helm install my-devcontainer ./chart -f custom-values.yaml helm install my-devcontainer ./chart -f custom-values.yaml
``` ```
+14 -2
View File
@@ -1,7 +1,7 @@
FROM jlesage/baseimage-gui:ubuntu-22.04-v4 FROM jlesage/baseimage-gui:ubuntu-22.04-v4
# Set environment variables # Set environment variables
ENV APP_NAME="Antigravity Dev Container" \ ENV APP_NAME="Dev Container" \
KEEP_APP_RUNNING=1 \ KEEP_APP_RUNNING=1 \
DISPLAY_WIDTH=1920 \ DISPLAY_WIDTH=1920 \
DISPLAY_HEIGHT=1080 \ DISPLAY_HEIGHT=1080 \
@@ -64,6 +64,18 @@ RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - && \
# Install Happy Coder and Claude Code globally # Install Happy Coder and Claude Code globally
RUN npm install -g happy-coder @anthropic-ai/claude-code RUN npm install -g happy-coder @anthropic-ai/claude-code
# Install OpenCode AI coding agent
RUN OPENCODE_VERSION=$(curl -sL https://api.github.com/repos/opencode-ai/opencode/releases/latest | jq -r '.tag_name') && \
curl -fsSL "https://github.com/opencode-ai/opencode/releases/download/${OPENCODE_VERSION}/opencode-linux-x86_64.tar.gz" | \
tar -xz -C /usr/local/bin opencode && \
chmod +x /usr/local/bin/opencode
# Install Crush AI coding agent (OpenCode successor by Charm)
RUN CRUSH_VERSION=$(curl -sL https://api.github.com/repos/charmbracelet/crush/releases/latest | jq -r '.tag_name' | sed 's/^v//') && \
curl -fsSL "https://github.com/charmbracelet/crush/releases/download/v${CRUSH_VERSION}/crush_${CRUSH_VERSION}_Linux_x86_64.tar.gz" | \
tar -xz --strip-components=1 -C /usr/local/bin "crush_${CRUSH_VERSION}_Linux_x86_64/crush" && \
chmod +x /usr/local/bin/crush
# Install VSCode # Install VSCode
RUN wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o /usr/share/keyrings/packages.microsoft.gpg && \ RUN wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o /usr/share/keyrings/packages.microsoft.gpg && \
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" > /etc/apt/sources.list.d/vscode.list && \ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" > /etc/apt/sources.list.d/vscode.list && \
@@ -119,4 +131,4 @@ ENV HOME=/config/userdata \
EXPOSE 5800 EXPOSE 5800
# Set app name for baseimage-gui # Set app name for baseimage-gui
RUN set-cont-env APP_NAME "Antigravity" RUN set-cont-env APP_NAME "Dev Container"
+118 -26
View File
@@ -1,17 +1,43 @@
# Antigravity Dev Container # Dev Container
![Build and Push](https://github.com/cpfarhood/devcontainer/actions/workflows/build-and-push.yaml/badge.svg) ![Build and Push](https://github.com/cpfarhood/devcontainer/actions/workflows/build-and-push.yaml/badge.svg)
A containerized cloud development environment with web-based GUI access, featuring: A containerized cloud development environment with web-based GUI access, featuring:
- **VSCode or Google Antigravity** via browser-based VNC (port 5800) - **VSCode or Google Antigravity** via browser-based VNC (port 5800)
- **SSH access** option (OpenSSH on port 22, additive with any IDE) - **SSH access** option (OpenSSH on port 22, additive with any IDE)
- **Happy Coder** AI assistant backed by Claude - **Claude Code**, **Happy Coder**, **OpenCode**, and **Crush** AI coding agents (terminal-based)
- **Automatic GitHub repo cloning** on startup - **Automatic GitHub repo cloning** on startup
- **Persistent home directory** via ReadWriteMany PVC - **Persistent home directory** via ReadWriteMany PVC
- **Kubernetes-native** Helm chart deployment - **Kubernetes-native** Helm chart deployment
## Quick Start ## Quick Start
### Option A: Quickstart (Recommended)
For 80% of users, use the simplified quickstart values:
```bash
# Copy and customize the quickstart template
cp chart/values-quickstart.yaml my-values.yaml
# Edit my-values.yaml to set your name and repository:
# name: mydev
# githubRepo: https://github.com/youruser/yourrepo
# Deploy with minimal configuration
helm install mydev ./chart -f my-values.yaml
```
### Option B: One-Command Deploy
```bash
helm install mydev ./chart \
--set name=mydev \
--set githubRepo=https://github.com/youruser/yourrepo
```
### Option C: Full Configuration
### 1. Create a secret ### 1. Create a secret
The secret is picked up automatically via `envFrom`. Keys recognised: The secret is picked up automatically via `envFrom`. Keys recognised:
@@ -22,8 +48,10 @@ The secret is picked up automatically via `envFrom`. Keys recognised:
| `VNC_PASSWORD` | Password for the VNC web UI | | `VNC_PASSWORD` | Password for the VNC web UI |
| `ANTHROPIC_API_KEY` | API key — alternative to browser-based Claude login | | `ANTHROPIC_API_KEY` | API key — alternative to browser-based Claude login |
| `SSH_AUTHORIZED_KEYS` | Public key(s) for SSH access (required when `ssh: true`) | | `SSH_AUTHORIZED_KEYS` | Public key(s) for SSH access (required when `ssh: true`) |
| `homeassistant-url` | Home Assistant URL (required when `mcpSidecars.homeassistant.enabled: true`) | | `HOMEASSISTANT_URL` | Home Assistant URL (required when `mcpSidecars.homeassistant.enabled: true`) |
| `homeassistant-token` | Home Assistant long-lived access token (required when `mcpSidecars.homeassistant.enabled: true`) | | `HOMEASSISTANT_TOKEN` | Home Assistant long-lived access token (required when `mcpSidecars.homeassistant.enabled: true`) |
| `DATABASE_URI` | PostgreSQL connection string (required when `mcpSidecars.pgtuner.enabled: true`) |
| `PGTUNER_EXCLUDE_USERIDS` | Comma-separated PostgreSQL user OIDs to exclude from monitoring (optional) |
```bash ```bash
kubectl create secret generic devcontainer-mydev-secrets-env \ kubectl create secret generic devcontainer-mydev-secrets-env \
@@ -73,6 +101,18 @@ A Chrome browser window will open inside VNC for the Claude Max OAuth login. Cre
## Helm Chart Reference ## Helm Chart Reference
The Helm chart uses a logical organization with these main sections:
- **Basic Configuration**: name, image, githubRepo
- **Access & Interface**: IDE, SSH, display, user settings
- **Infrastructure**: storage, resources, cluster access
- **Integrations**: Happy Coder, MCP sidecars
- **Smart Defaults**: auto-detection and profiles
📖 **Documentation**:
- [USAGE.md](chart/USAGE.md) - Comprehensive examples and scenarios
- [values-quickstart.yaml](chart/values-quickstart.yaml) - Minimal configuration
- [values.schema.json](chart/values.schema.json) - IDE validation support
### Core values ### Core values
| Value | Default | Description | | Value | Default | Description |
@@ -158,29 +198,35 @@ The devcontainer includes MCP (Model Context Protocol) servers as sidecar contai
| Sidecar | Default | Purpose | | Sidecar | Default | Purpose |
|---------|---------|---------| |---------|---------|---------|
| `mcpSidecars.kubernetes.enabled` | `true` | Kubernetes API access via MCP | | `mcp.sidecars.kubernetes.enabled` | `true` | Kubernetes API access via MCP |
| `mcpSidecars.flux.enabled` | `true` | Flux GitOps operations via MCP | | `mcp.sidecars.flux.enabled` | `true` | Flux GitOps operations via MCP |
| `mcpSidecars.homeassistant.enabled` | `false` | Home Assistant smart home control via MCP | | `mcp.sidecars.github.enabled` | `false` | GitHub API access via MCP (DISABLED: archived image) |
| `mcp.sidecars.homeassistant.enabled` | `false` | Home Assistant smart home control via MCP |
| `mcp.sidecars.pgtuner.enabled` | `false` | PostgreSQL performance tuning and analysis via MCP |
| `mcp.sidecars.playwright.enabled` | `true` | Browser automation and web testing via MCP |
**Notes:** **Notes:**
- Kubernetes and Flux sidecars require `clusterAccess` != `none` to be deployed (automatically disabled when no cluster access) - Kubernetes and Flux sidecars require `clusterAccess` != `none` to be deployed (automatically disabled when no cluster access)
- Kubernetes and Flux sidecars inherit the pod's ServiceAccount RBAC permissions (controlled by `clusterAccess`) - Kubernetes and Flux sidecars inherit the pod's ServiceAccount RBAC permissions (controlled by `clusterAccess`)
- Home Assistant sidecar requires additional configuration (see below) - Home Assistant sidecar requires `homeassistant-url` and `homeassistant-token` in the env secret
- PostgreSQL tuner sidecar requires `database-uri` in the env secret (PostgreSQL connection string)
- Playwright sidecar provides browser automation and web testing capabilities
**Disable MCP sidecars:** **Disable MCP sidecars:**
```bash ```bash
# Disable both sidecars # Disable multiple sidecars
helm install mydev ./chart \ helm install mydev ./chart \
--set name=mydev \ --set name=mydev \
--set githubRepo=https://github.com/youruser/yourrepo \ --set githubRepo=https://github.com/youruser/yourrepo \
--set mcpSidecars.kubernetes.enabled=false \ --set mcp.sidecars.kubernetes.enabled=false \
--set mcpSidecars.flux.enabled=false --set mcp.sidecars.flux.enabled=false \
--set mcp.sidecars.playwright.enabled=false
# Or selectively disable # Or selectively disable
helm install mydev ./chart \ helm install mydev ./chart \
--set name=mydev \ --set name=mydev \
--set githubRepo=https://github.com/youruser/yourrepo \ --set githubRepo=https://github.com/youruser/yourrepo \
--set mcpSidecars.flux.enabled=false # Disable only Flux MCP --set mcp.sidecars.flux.enabled=false # Disable only Flux MCP
``` ```
**Enable Home Assistant MCP:** **Enable Home Assistant MCP:**
@@ -188,25 +234,40 @@ helm install mydev ./chart \
# Create secret with Home Assistant credentials # Create secret with Home Assistant credentials
kubectl create secret generic devcontainer-mydev-secrets-env \ kubectl create secret generic devcontainer-mydev-secrets-env \
--from-literal=GITHUB_TOKEN='ghp_...' \ --from-literal=GITHUB_TOKEN='ghp_...' \
--from-literal=homeassistant-url='http://homeassistant.local:8123' \ --from-literal=HOMEASSISTANT_URL='http://homeassistant.local:8123' \
--from-literal=homeassistant-token='your_long_lived_access_token' --from-literal=HOMEASSISTANT_TOKEN='your_long_lived_access_token'
# Deploy with Home Assistant MCP enabled # Deploy with Home Assistant MCP enabled
helm install mydev ./chart \ helm install mydev ./chart \
--set name=mydev \ --set name=mydev \
--set githubRepo=https://github.com/youruser/yourrepo \ --set githubRepo=https://github.com/youruser/yourrepo \
--set mcpSidecars.homeassistant.enabled=true --set mcp.sidecars.homeassistant.enabled=true
```
**Enable PostgreSQL Tuner MCP:**
```bash
# Create secret with PostgreSQL connection string
kubectl create secret generic devcontainer-mydev-secrets-env \
--from-literal=GITHUB_TOKEN='ghp_...' \
--from-literal=DATABASE_URI='postgresql://user:password@postgres.example.com:5432/dbname'
# Deploy with PostgreSQL tuner MCP enabled
helm install mydev ./chart \
--set name=mydev \
--set githubRepo=https://github.com/youruser/yourrepo \
--set mcp.sidecars.pgtuner.enabled=true
``` ```
**Custom MCP configuration:** **Custom MCP configuration:**
```yaml ```yaml
# values.yaml override # values.yaml override
mcpSidecars: mcp:
sidecars:
kubernetes: kubernetes:
enabled: true enabled: true
image: image:
repository: quay.io/containers/kubernetes_mcp_server repository: quay.io/containers/kubernetes_mcp_server
tag: latest tag: v0.0.57
port: 8080 port: 8080
resources: resources:
requests: requests:
@@ -217,19 +278,47 @@ mcpSidecars:
cpu: "500m" cpu: "500m"
flux: flux:
enabled: false # Disabled in this example enabled: false # Disabled in this example
github:
enabled: false # Disabled by default (archived image)
homeassistant: homeassistant:
enabled: true enabled: true
image: image:
repository: ghcr.io/homeassistant-ai/ha-mcp repository: ghcr.io/homeassistant-ai/ha-mcp
tag: 6.7.1 # Override the pinned version if needed tag: stable
port: 8087 port: 8087
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "256Mi"
cpu: "500m"
pgtuner:
enabled: true
image:
repository: dog830228/pgtuner_mcp
tag: latest
port: 8085
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "256Mi"
cpu: "500m"
playwright:
enabled: true
image:
repository: microsoft/playwright-mcp
tag: latest
port: 8086
resources: resources:
requests: requests:
memory: "128Mi" memory: "128Mi"
cpu: "100m" cpu: "100m"
limits: limits:
memory: "512Mi" memory: "512Mi"
cpu: "500m" cpu: "1000m"
``` ```
### Display and resources ### Display and resources
@@ -263,8 +352,6 @@ Container start
→ /startapp.sh (runs as app user, UID 1000) → /startapp.sh (runs as app user, UID 1000)
→ init-repo.sh → init-repo.sh
→ clone / pull GITHUB_REPO into /workspace/{repo} → clone / pull GITHUB_REPO into /workspace/{repo}
→ rm daemon.state.json.lock — clear stale Happy lock
→ happy daemon start — starts Happy Coder background daemon
→ IDE=vscode: code --new-window --wait /workspace/{repo} → IDE=vscode: code --new-window --wait /workspace/{repo}
IDE=antigravity: antigravity --no-sandbox --user-data-dir ~/.config/antigravity ... /workspace/{repo} IDE=antigravity: antigravity --no-sandbox --user-data-dir ~/.config/antigravity ... /workspace/{repo}
IDE=none: sleep infinity IDE=none: sleep infinity
@@ -278,23 +365,28 @@ Container start
| `/home` | ReadWriteMany PVC (`userhome-{name}`) | Survives pod restarts — stores Claude credentials, dotfiles, git config | | `/home` | ReadWriteMany PVC (`userhome-{name}`) | Survives pod restarts — stores Claude credentials, dotfiles, git config |
| `/workspace` | `emptyDir` | Ephemeral — repo is re-cloned on each pod start | | `/workspace` | `emptyDir` | Ephemeral — repo is re-cloned on each pod start |
Happy Coder's runtime state (`HAPPY_HOME_DIR`) is kept in `/home/user/.happy` on the persistent home PVC, so auth credentials and settings survive pod restarts. A stale lock file (`daemon.state.json.lock`) is removed automatically on each startup. Happy Coder's runtime state (`HAPPY_HOME_DIR`) is kept in `/home/user/.happy` on the persistent home PVC, so auth credentials and settings survive pod restarts when manually started.
--- ---
## Troubleshooting ## Troubleshooting
### Happy Coder daemon not starting ### Happy Coder (manual startup)
Happy daemon is not started automatically. Launch it manually when needed:
```bash ```bash
# Start Happy Coder daemon manually
happy daemon start
# Check daemon status # Check daemon status
happy daemon status happy daemon status
# Start manually (also clears any stale lock)
happy daemon start
# View daemon logs # View daemon logs
ls ~/.happy/logs/ ls ~/.happy/logs/
# Stop daemon if needed
happy daemon stop
``` ```
### Claude not authenticated ### Claude not authenticated
+1 -1
View File
@@ -2,5 +2,5 @@ apiVersion: v2
name: devcontainer name: devcontainer
description: Antigravity Dev Container with Happy Coder AI assistant description: Antigravity Dev Container with Happy Coder AI assistant
type: application type: application
version: 0.2.2 version: 0.3.0
appVersion: "latest" appVersion: "latest"
+381
View File
@@ -0,0 +1,381 @@
# Dev Container Helm Chart Usage Guide
This guide provides common usage patterns and examples for the Dev Container Helm chart.
## Quick Start
### 1. Minimal Installation (Recommended)
Use the quickstart values for the simplest setup:
```bash
# Copy and customize quickstart values
cp values-quickstart.yaml my-values.yaml
# Edit my-values.yaml to set your name and repo:
# name: myproject
# githubRepo: https://github.com/youruser/yourproject
# Install
helm install myproject ./chart -f my-values.yaml
```
### 2. One-Command Installation
```bash
helm install mydev ./chart \
--set name=mydev \
--set githubRepo=https://github.com/youruser/yourrepo
```
## Common Use Cases
### Development Environment
**Scenario**: Standard development with GitHub integration
```yaml
name: dev-environment
githubRepo: https://github.com/company/project
ide:
type: vscode
mcp:
sidecars:
kubernetes:
enabled: true
playwright:
enabled: true
flux:
enabled: false # Disable if not using Flux
```
### Team Workspace
**Scenario**: Shared development environment with more resources
```yaml
name: team-workspace
githubRepo: https://github.com/company/project
resources:
requests:
memory: "4Gi"
cpu: "2000m"
limits:
memory: "16Gi"
cpu: "8000m"
storage:
size: 64Gi
ssh:
enabled: true # Enable SSH access for team
clusterAccess: readwrite # Full cluster access
```
### Kubernetes Admin Environment
**Scenario**: Platform engineering with full cluster access
```yaml
name: k8s-admin
githubRepo: https://github.com/company/k8s-configs
clusterAccess: readwrite
mcp:
sidecars:
kubernetes:
enabled: true
flux:
enabled: true
pgtuner:
enabled: true # Database administration
playwright:
enabled: false # Save resources
```
### AI/ML Development
**Scenario**: AI development with browser automation
```yaml
name: ai-playground
githubRepo: https://github.com/company/ai-project
resources:
requests:
memory: "8Gi" # More memory for ML workloads
cpu: "4000m"
limits:
memory: "32Gi"
cpu: "16000m"
storage:
size: 128Gi # Large datasets
mcp:
sidecars:
playwright:
enabled: true # Web scraping, testing
kubernetes:
enabled: false # Save resources
flux:
enabled: false
```
### Lightweight Environment
**Scenario**: Resource-constrained setup
```yaml
name: lightweight
githubRepo: https://github.com/youruser/small-project
resources:
requests:
memory: "1Gi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "1000m"
storage:
size: 8Gi
mcp:
sidecars:
kubernetes:
enabled: false
flux:
enabled: false
playwright:
enabled: false
# Only keep essential sidecars enabled
```
## Secret Configuration
### Basic Secrets
```bash
# GitHub access only
kubectl create secret generic devcontainer-mydev-secrets-env \
--from-literal=GITHUB_TOKEN='ghp_...' \
--from-literal=VNC_PASSWORD='changeme'
```
### Extended Secrets
```bash
# Full feature set
kubectl create secret generic devcontainer-mydev-secrets-env \
--from-literal=GITHUB_TOKEN='ghp_...' \
--from-literal=VNC_PASSWORD='changeme' \
--from-literal=SSH_AUTHORIZED_KEYS='ssh-ed25519 AAAA...' \
--from-literal=HOMEASSISTANT_URL='http://homeassistant.local:8123' \
--from-literal=HOMEASSISTANT_TOKEN='eyJ...' \
--from-literal=DATABASE_URI='postgresql://user:pass@postgres:5432/db'
```
## Storage Configuration
### Different Storage Classes
```yaml
# For different Kubernetes distributions
storage:
className: "" # Auto-detect (recommended)
# className: longhorn # Longhorn
# className: nfs-client # NFS
# className: fast-ssd # Custom fast storage
```
### Storage Sizes by Use Case
```yaml
# Small projects
storage:
size: 8Gi
# Standard development
storage:
size: 32Gi
# Large projects / datasets
storage:
size: 128Gi
# Team environments
storage:
size: 256Gi
```
## Access Patterns
### VNC Only (Default)
```yaml
ide:
type: vscode
# Access via: kubectl port-forward deployment/devcontainer-mydev 5800:5800
```
### SSH Only
```yaml
ide:
type: none
ssh:
enabled: true
# Access via: kubectl port-forward deployment/devcontainer-mydev 2222:22
# ssh -p 2222 user@localhost
```
### Both VNC and SSH
```yaml
ide:
type: vscode
ssh:
enabled: true
# VNC: kubectl port-forward deployment/devcontainer-mydev 5800:5800
# SSH: kubectl port-forward deployment/devcontainer-mydev 2222:22
```
## Resource Profiles
### Small (1-2 developers)
```yaml
resources:
requests:
memory: "1Gi"
cpu: "500m"
limits:
memory: "4Gi"
cpu: "2000m"
```
### Medium (standard development)
```yaml
resources:
requests:
memory: "2Gi"
cpu: "1000m"
limits:
memory: "8Gi"
cpu: "4000m"
```
### Large (intensive workloads)
```yaml
resources:
requests:
memory: "4Gi"
cpu: "2000m"
limits:
memory: "16Gi"
cpu: "8000m"
```
### XLarge (AI/ML, data processing)
```yaml
resources:
requests:
memory: "8Gi"
cpu: "4000m"
limits:
memory: "32Gi"
cpu: "16000m"
```
## MCP Sidecar Combinations
### Minimal (basic development)
```yaml
mcp:
sidecars:
kubernetes:
enabled: false
flux:
enabled: false
playwright:
enabled: true # Keep for web testing
```
### Standard (full-stack development)
```yaml
mcp:
sidecars:
kubernetes:
enabled: true
flux:
enabled: false
playwright:
enabled: true
```
### DevOps/Platform (infrastructure work)
```yaml
mcp:
sidecars:
kubernetes:
enabled: true
flux:
enabled: true
pgtuner:
enabled: true
playwright:
enabled: false
```
### All Features
```yaml
mcp:
sidecars:
kubernetes:
enabled: true
flux:
enabled: true
homeassistant:
enabled: true
pgtuner:
enabled: true
playwright:
enabled: true
```
## Troubleshooting
### Values Validation
Your IDE should automatically validate values.yaml against the schema. If not:
```bash
# Manual validation (if you have a JSON schema validator)
helm template ./chart -f values.yaml > /dev/null
```
### Common Issues
**Resource Limits**: Start with smaller resource requests and increase as needed.
**Storage Class**: Use `className: ""` for auto-detection.
**GitHub Access**: Ensure GITHUB_TOKEN has `repo` scope.
**MCP Sidecars**: Disable unused sidecars to save resources.
### Getting Help
1. Check the main [README.md](../README.md) for detailed documentation
2. Review [values.yaml](values.yaml) for all available options
3. Use [values-quickstart.yaml](values-quickstart.yaml) as a starting point
+68
View File
@@ -26,3 +26,71 @@ Common labels
app: devcontainer app: devcontainer
instance: {{ .Values.name }} instance: {{ .Values.name }}
{{- end }} {{- end }}
{{/*
Smart resource sizing based on enabled features
*/}}
{{- define "antigravity.smartResources" -}}
{{- $baseMemory := "2Gi" }}
{{- $baseCpu := "1000m" }}
{{- $limitMemory := "8Gi" }}
{{- $limitCpu := "4000m" }}
{{/* Adjust for enabled MCP sidecars */}}
{{- if .Values.mcp.sidecars.playwright.enabled }}
{{- $baseMemory = "3Gi" }}
{{- $limitMemory = "12Gi" }}
{{- end }}
{{/* Adjust for IDE type */}}
{{- if eq .Values.ide.type "antigravity" }}
{{- $baseMemory = "4Gi" }}
{{- $limitMemory = "16Gi" }}
{{- end }}
requests:
memory: {{ .Values.resources.requests.memory | default $baseMemory | quote }}
cpu: {{ .Values.resources.requests.cpu | default $baseCpu | quote }}
limits:
memory: {{ .Values.resources.limits.memory | default $limitMemory | quote }}
cpu: {{ .Values.resources.limits.cpu | default $limitCpu | quote }}
{{- end }}
{{/*
Auto-detect environment type and set smart defaults
*/}}
{{- define "antigravity.smartDefaults" -}}
{{- $isDev := or (contains "dev" .Values.name) (contains "test" .Values.name) (contains "local" .Values.name) }}
{{- $isProd := or (contains "prod" .Values.name) (contains "production" .Values.name) }}
{{- $isTeam := or (contains "team" .Values.name) (contains "shared" .Values.name) }}
{{/* Development environment - enable more sidecars, smaller resources */}}
{{- if $isDev }}
development: true
{{/* Production environment - conservative defaults, fewer sidecars */}}
{{- else if $isProd }}
production: true
{{/* Team environment - enable SSH, more resources */}}
{{- else if $isTeam }}
team: true
{{- end }}
{{- end }}
{{/*
Smart MCP sidecar selection based on cluster access
*/}}
{{- define "antigravity.mcpDefaults" -}}
{{- if eq .Values.clusterAccess "none" }}
{{/* No cluster access - disable k8s/flux sidecars */}}
kubernetes:
enabled: false
flux:
enabled: false
{{- else }}
{{/* Has cluster access - enable k8s sidecars */}}
kubernetes:
enabled: true
flux:
enabled: {{ ne .Values.clusterAccess "readonly" }}
{{- end }}
{{- end }}
+125 -44
View File
@@ -20,44 +20,63 @@ spec:
securityContext: securityContext:
fsGroup: 1000 fsGroup: 1000
fsGroupChangePolicy: "OnRootMismatch" fsGroupChangePolicy: "OnRootMismatch"
{{- if and .Values.ide.type (eq .Values.ide.type "antigravity") }}
initContainers:
- name: setup-userdata
image: busybox:latest
command: ['sh', '-c']
args:
- |
echo "Setting up userdata directory..."
mkdir -p /config/userdata
chown 1000:1000 /config/userdata
chmod 755 /config/userdata
echo "Userdata directory setup complete"
volumeMounts:
- name: userhome
mountPath: /config
securityContext:
runAsUser: 0
runAsGroup: 0
{{- end }}
containers: containers:
- name: devcontainer - name: devcontainer
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }} imagePullPolicy: {{ .Values.image.pullPolicy }}
ports: ports:
{{- if ne (.Values.ide | default "vscode") "none" }} {{- if ne (.Values.ide.type | default "vscode") "none" }}
- containerPort: 5800 - containerPort: 5800
name: vnc-web name: vnc-web
protocol: TCP protocol: TCP
{{- end }} {{- end }}
{{- if .Values.ssh }} {{- if .Values.ssh.enabled }}
- containerPort: 22 - containerPort: 22
name: ssh name: ssh
protocol: TCP protocol: TCP
{{- end }} {{- end }}
env: env:
- name: IDE - name: IDE
value: {{ .Values.ide | default "vscode" | quote }} value: {{ .Values.ide.type | default "vscode" | quote }}
- name: SSH - name: SSH
value: {{ .Values.ssh | toString | quote }} value: {{ .Values.ssh.enabled | toString | quote }}
- name: USER_ID - name: USER_ID
value: {{ .Values.userId | quote }} value: {{ .Values.user.id | quote }}
- name: GROUP_ID - name: GROUP_ID
value: {{ .Values.groupId | quote }} value: {{ .Values.user.groupId | quote }}
- name: DISPLAY_WIDTH - name: DISPLAY_WIDTH
value: {{ .Values.display.width | quote }} value: {{ .Values.display.width | quote }}
- name: DISPLAY_HEIGHT - name: DISPLAY_HEIGHT
value: {{ .Values.display.height | quote }} value: {{ .Values.display.height | quote }}
- name: SECURE_CONNECTION - name: SECURE_CONNECTION
value: {{ .Values.secureConnection | quote }} value: {{ .Values.display.secureConnection | quote }}
- name: HAPPY_HOME_DIR - name: HAPPY_HOME_DIR
value: {{ .Values.happyHomeDir | quote }} value: {{ .Values.happy.homeDir | quote }}
- name: HAPPY_EXPERIMENTAL - name: HAPPY_EXPERIMENTAL
value: {{ .Values.happyExperimental | quote }} value: {{ .Values.happy.experimental | quote }}
- name: HAPPY_SERVER_URL - name: HAPPY_SERVER_URL
value: {{ .Values.happyServerUrl | quote }} value: {{ .Values.happy.serverUrl | quote }}
- name: HAPPY_WEBAPP_URL - name: HAPPY_WEBAPP_URL
value: {{ .Values.happyWebappUrl | quote }} value: {{ .Values.happy.webappUrl | quote }}
- name: GITHUB_REPO - name: GITHUB_REPO
value: {{ .Values.githubRepo | quote }} value: {{ .Values.githubRepo | quote }}
envFrom: envFrom:
@@ -73,7 +92,7 @@ spec:
mountPath: /workspace mountPath: /workspace
- name: shm - name: shm
mountPath: /dev/shm mountPath: /dev/shm
{{- if ne (.Values.ide | default "vscode") "none" }} {{- if ne (.Values.ide.type | default "vscode") "none" }}
livenessProbe: livenessProbe:
httpGet: httpGet:
path: / path: /
@@ -86,7 +105,7 @@ spec:
port: 5800 port: 5800
initialDelaySeconds: 10 initialDelaySeconds: 10
periodSeconds: 5 periodSeconds: 5
{{- else if .Values.ssh }} {{- else if .Values.ssh.enabled }}
livenessProbe: livenessProbe:
tcpSocket: tcpSocket:
port: 22 port: 22
@@ -98,120 +117,182 @@ spec:
initialDelaySeconds: 5 initialDelaySeconds: 5
periodSeconds: 5 periodSeconds: 5
{{- end }} {{- end }}
{{- if and .Values.mcpSidecars.kubernetes.enabled (ne .Values.clusterAccess "none") }} {{- if and .Values.mcp.sidecars.kubernetes.enabled (ne .Values.clusterAccess "none") }}
- name: kubernetes-mcp - name: kubernetes-mcp
image: "{{ .Values.mcpSidecars.kubernetes.image.repository }}:{{ .Values.mcpSidecars.kubernetes.image.tag }}" image: "{{ .Values.mcp.sidecars.kubernetes.image.repository }}:{{ .Values.mcp.sidecars.kubernetes.image.tag }}"
args: args:
- --port - --port
- {{ .Values.mcpSidecars.kubernetes.port | quote }} - {{ .Values.mcp.sidecars.kubernetes.port | quote }}
ports: ports:
- containerPort: {{ .Values.mcpSidecars.kubernetes.port }} - containerPort: {{ .Values.mcp.sidecars.kubernetes.port }}
name: k8s-mcp name: k8s-mcp
protocol: TCP protocol: TCP
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /healthz path: /healthz
port: {{ .Values.mcpSidecars.kubernetes.port }} port: {{ .Values.mcp.sidecars.kubernetes.port }}
initialDelaySeconds: 10 initialDelaySeconds: 10
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /healthz path: /healthz
port: {{ .Values.mcpSidecars.kubernetes.port }} port: {{ .Values.mcp.sidecars.kubernetes.port }}
initialDelaySeconds: 5 initialDelaySeconds: 5
periodSeconds: 5 periodSeconds: 5
resources: resources:
{{- toYaml .Values.mcpSidecars.kubernetes.resources | nindent 12 }} {{- toYaml .Values.mcp.sidecars.kubernetes.resources | nindent 12 }}
{{- end }} {{- end }}
{{- if and .Values.mcpSidecars.flux.enabled (ne .Values.clusterAccess "none") }} {{- if and .Values.mcp.sidecars.flux.enabled (ne .Values.clusterAccess "none") }}
- name: flux-mcp - name: flux-mcp
image: "{{ .Values.mcpSidecars.flux.image.repository }}:{{ .Values.mcpSidecars.flux.image.tag }}" image: "{{ .Values.mcp.sidecars.flux.image.repository }}:{{ .Values.mcp.sidecars.flux.image.tag }}"
args: args:
- serve - serve
- --transport=sse - --transport=sse
- --port={{ .Values.mcpSidecars.flux.port }} - --port={{ .Values.mcp.sidecars.flux.port }}
ports: ports:
- containerPort: {{ .Values.mcpSidecars.flux.port }} - containerPort: {{ .Values.mcp.sidecars.flux.port }}
name: flux-mcp name: flux-mcp
protocol: TCP protocol: TCP
livenessProbe: livenessProbe:
tcpSocket: tcpSocket:
port: {{ .Values.mcpSidecars.flux.port }} port: {{ .Values.mcp.sidecars.flux.port }}
initialDelaySeconds: 10 initialDelaySeconds: 10
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
tcpSocket: tcpSocket:
port: {{ .Values.mcpSidecars.flux.port }} port: {{ .Values.mcp.sidecars.flux.port }}
initialDelaySeconds: 5 initialDelaySeconds: 5
periodSeconds: 5 periodSeconds: 5
resources: resources:
{{- toYaml .Values.mcpSidecars.flux.resources | nindent 12 }} {{- toYaml .Values.mcp.sidecars.flux.resources | nindent 12 }}
{{- end }} {{- end }}
{{- if .Values.mcpSidecars.homeassistant.enabled }} {{- if .Values.mcp.sidecars.homeassistant.enabled }}
- name: homeassistant-mcp - name: homeassistant-mcp
image: "{{ .Values.mcpSidecars.homeassistant.image.repository }}:{{ .Values.mcpSidecars.homeassistant.image.tag }}" image: "{{ .Values.mcp.sidecars.homeassistant.image.repository }}:{{ .Values.mcp.sidecars.homeassistant.image.tag }}"
imagePullPolicy: Always imagePullPolicy: Always
command: ["fastmcp", "run", "ha_mcp.main:app", "--transport", "sse", "--host", "0.0.0.0", "--port", "{{ .Values.mcpSidecars.homeassistant.port }}"] command: ["fastmcp", "run", "--transport", "sse", "--host", "0.0.0.0", "--port", "{{ .Values.mcp.sidecars.homeassistant.port }}"]
ports: ports:
- name: homeassistant - name: homeassistant
containerPort: {{ .Values.mcpSidecars.homeassistant.port }} containerPort: {{ .Values.mcp.sidecars.homeassistant.port }}
env: env:
- name: HOMEASSISTANT_URL - name: HOMEASSISTANT_URL
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ include "antigravity.envSecretName" . }} name: {{ include "antigravity.envSecretName" . }}
key: homeassistant-url key: HOMEASSISTANT_URL
optional: true optional: true
- name: HOMEASSISTANT_TOKEN - name: HOMEASSISTANT_TOKEN
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ include "antigravity.envSecretName" . }} name: {{ include "antigravity.envSecretName" . }}
key: homeassistant-token key: HOMEASSISTANT_TOKEN
optional: true optional: true
livenessProbe: livenessProbe:
tcpSocket: tcpSocket:
port: {{ .Values.mcpSidecars.homeassistant.port }} port: {{ .Values.mcp.sidecars.homeassistant.port }}
initialDelaySeconds: 10 initialDelaySeconds: 10
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
tcpSocket: tcpSocket:
port: {{ .Values.mcpSidecars.homeassistant.port }} port: {{ .Values.mcp.sidecars.homeassistant.port }}
initialDelaySeconds: 5 initialDelaySeconds: 5
periodSeconds: 5 periodSeconds: 5
resources: resources:
{{- toYaml .Values.mcpSidecars.homeassistant.resources | nindent 12 }} {{- toYaml .Values.mcp.sidecars.homeassistant.resources | nindent 12 }}
{{- end }} {{- end }}
{{- if .Values.mcpSidecars.github.enabled }} {{- if .Values.mcp.sidecars.github.enabled }}
- name: github-mcp - name: github-mcp
image: "{{ .Values.mcpSidecars.github.image.repository }}:{{ .Values.mcpSidecars.github.image.tag }}" image: "{{ .Values.mcp.sidecars.github.image.repository }}:{{ .Values.mcp.sidecars.github.image.tag }}"
imagePullPolicy: Always imagePullPolicy: Always
args: args:
- --sse - --sse
- --port={{ .Values.mcpSidecars.github.port }} - --port={{ .Values.mcp.sidecars.github.port }}
ports: ports:
- name: github - name: github
containerPort: {{ .Values.mcpSidecars.github.port }} containerPort: {{ .Values.mcp.sidecars.github.port }}
env: env:
- name: GITHUB_PERSONAL_ACCESS_TOKEN - name: GITHUB_PERSONAL_ACCESS_TOKEN
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ include "antigravity.envSecretName" . }} name: {{ include "antigravity.envSecretName" . }}
key: github-token key: GITHUB_TOKEN
optional: true optional: true
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /health path: /health
port: {{ .Values.mcpSidecars.github.port }} port: {{ .Values.mcp.sidecars.github.port }}
initialDelaySeconds: 10 initialDelaySeconds: 10
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /health path: /health
port: {{ .Values.mcpSidecars.github.port }} port: {{ .Values.mcp.sidecars.github.port }}
initialDelaySeconds: 5 initialDelaySeconds: 5
periodSeconds: 5 periodSeconds: 5
resources: resources:
{{- toYaml .Values.mcpSidecars.github.resources | nindent 12 }} {{- toYaml .Values.mcp.sidecars.github.resources | nindent 12 }}
{{- end }}
{{- if .Values.mcp.sidecars.pgtuner.enabled }}
- name: pgtuner-mcp
image: "{{ .Values.mcp.sidecars.pgtuner.image.repository }}:{{ .Values.mcp.sidecars.pgtuner.image.tag }}"
imagePullPolicy: Always
command: ["python", "-m", "pgtuner_mcp", "--transport", "sse", "--port", "{{ .Values.mcp.sidecars.pgtuner.port }}"]
ports:
- name: pgtuner
containerPort: {{ .Values.mcp.sidecars.pgtuner.port }}
env:
- name: DATABASE_URI
valueFrom:
secretKeyRef:
name: {{ include "antigravity.envSecretName" . }}
key: DATABASE_URI
optional: true
- name: PGTUNER_EXCLUDE_USERIDS
valueFrom:
secretKeyRef:
name: {{ include "antigravity.envSecretName" . }}
key: PGTUNER_EXCLUDE_USERIDS
optional: true
livenessProbe:
tcpSocket:
port: {{ .Values.mcp.sidecars.pgtuner.port }}
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
tcpSocket:
port: {{ .Values.mcp.sidecars.pgtuner.port }}
initialDelaySeconds: 5
periodSeconds: 5
resources:
{{- toYaml .Values.mcp.sidecars.pgtuner.resources | nindent 12 }}
{{- end }}
{{- if .Values.mcp.sidecars.playwright.enabled }}
- name: playwright-mcp
image: "{{ .Values.mcp.sidecars.playwright.image.repository }}:{{ .Values.mcp.sidecars.playwright.image.tag }}"
imagePullPolicy: Always
args:
- --transport
- sse
- --port
- {{ .Values.mcp.sidecars.playwright.port | quote }}
ports:
- name: playwright
containerPort: {{ .Values.mcp.sidecars.playwright.port }}
livenessProbe:
tcpSocket:
port: {{ .Values.mcp.sidecars.playwright.port }}
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
tcpSocket:
port: {{ .Values.mcp.sidecars.playwright.port }}
initialDelaySeconds: 10
periodSeconds: 5
resources:
{{- toYaml .Values.mcp.sidecars.playwright.resources | nindent 12 }}
securityContext:
runAsUser: 1000
runAsGroup: 1000
{{- end }} {{- end }}
volumes: volumes:
- name: workspace - name: workspace
+58
View File
@@ -0,0 +1,58 @@
# =============================================================================
# QUICKSTART VALUES - Just set these 3 essentials!
# =============================================================================
# Instance name (required)
name: mydev
# GitHub repository to clone (required)
githubRepo: https://github.com/youruser/yourrepo
# IDE choice (optional - defaults to vscode)
# Options: vscode | antigravity | none
ide:
type: vscode
# =============================================================================
# COMMON CUSTOMIZATIONS (optional)
# =============================================================================
# Enable SSH access
# ssh:
# enabled: true
# Adjust resources for smaller/larger workloads
# resources:
# requests:
# memory: "1Gi" # Smaller
# cpu: "500m"
# limits:
# memory: "4Gi" # Smaller
# cpu: "2000m"
# Different storage size
# storage:
# size: 16Gi # Smaller
# Disable some MCP sidecars to save resources
# mcp:
# sidecars:
# kubernetes:
# enabled: false
# flux:
# enabled: false
# =============================================================================
# USAGE INSTRUCTIONS
# =============================================================================
# 1. Copy this file: cp values-quickstart.yaml my-values.yaml
# 2. Edit the 'name' and 'githubRepo' fields above
# 3. Deploy: helm install mydev ./chart -f my-values.yaml
# 4. Access: kubectl port-forward deployment/devcontainer-mydev 5800:5800
# 5. Open: http://localhost:5800
# For secrets (GitHub token, passwords):
# kubectl create secret generic devcontainer-mydev-secrets-env \
# --from-literal=GITHUB_TOKEN='ghp_...' \
# --from-literal=VNC_PASSWORD='changeme'
+259
View File
@@ -0,0 +1,259 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://github.com/cpfarhood/devcontainer/chart/values.schema.json",
"title": "Dev Container Helm Chart Values Schema",
"description": "Schema for validating values.yaml in the Dev Container Helm chart",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Instance name used to generate resource names",
"pattern": "^[a-z0-9][a-z0-9-]*[a-z0-9]$",
"minLength": 1,
"maxLength": 63
},
"image": {
"type": "object",
"properties": {
"repository": {
"type": "string",
"description": "Container image repository"
},
"tag": {
"type": "string",
"description": "Container image tag"
},
"pullPolicy": {
"type": "string",
"enum": ["Always", "IfNotPresent", "Never"],
"description": "Image pull policy"
}
},
"required": ["repository", "tag"]
},
"githubRepo": {
"type": "string",
"description": "GitHub repository URL to clone",
"pattern": "^https://github\\.com/.+/.+$"
},
"ide": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["vscode", "antigravity", "none"],
"description": "IDE to launch in the container"
}
},
"required": ["type"]
},
"ssh": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean",
"description": "Enable SSH server on port 22"
}
},
"required": ["enabled"]
},
"display": {
"type": "object",
"properties": {
"width": {
"type": "string",
"pattern": "^[0-9]+$",
"description": "VNC display width in pixels"
},
"height": {
"type": "string",
"pattern": "^[0-9]+$",
"description": "VNC display height in pixels"
},
"secureConnection": {
"type": "string",
"enum": ["0", "1"],
"description": "Enable secure VNC connection"
}
},
"required": ["width", "height", "secureConnection"]
},
"user": {
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[0-9]+$",
"description": "User ID (UID)"
},
"groupId": {
"type": "string",
"pattern": "^[0-9]+$",
"description": "Group ID (GID)"
}
},
"required": ["id", "groupId"]
},
"storage": {
"type": "object",
"properties": {
"size": {
"type": "string",
"pattern": "^[0-9]+[KMGT]i$",
"description": "Storage size (e.g., 32Gi)"
},
"className": {
"type": "string",
"description": "Storage class name (must support ReadWriteMany)"
}
},
"required": ["size", "className"]
},
"resources": {
"type": "object",
"properties": {
"requests": {
"$ref": "#/$defs/resourceSpec"
},
"limits": {
"$ref": "#/$defs/resourceSpec"
}
},
"required": ["requests", "limits"]
},
"shm": {
"type": "object",
"properties": {
"sizeLimit": {
"type": "string",
"pattern": "^[0-9]+[KMGT]i$",
"description": "Shared memory size limit"
}
},
"required": ["sizeLimit"]
},
"clusterAccess": {
"type": "string",
"enum": ["none", "readonlyns", "readwritens", "readonly", "readwrite"],
"description": "Kubernetes cluster access level"
},
"happy": {
"type": "object",
"properties": {
"serverUrl": {
"type": "string",
"format": "uri",
"description": "Happy Coder server URL"
},
"webappUrl": {
"type": "string",
"format": "uri",
"description": "Happy Coder webapp URL"
},
"homeDir": {
"type": "string",
"description": "Happy Coder home directory"
},
"experimental": {
"type": "string",
"enum": ["true", "false"],
"description": "Enable experimental Happy features"
}
},
"required": ["serverUrl", "webappUrl", "homeDir", "experimental"]
},
"mcp": {
"type": "object",
"properties": {
"sidecars": {
"type": "object",
"properties": {
"kubernetes": {
"$ref": "#/$defs/mcpSidecar"
},
"flux": {
"$ref": "#/$defs/mcpSidecar"
},
"homeassistant": {
"$ref": "#/$defs/mcpSidecar"
},
"github": {
"$ref": "#/$defs/mcpSidecar"
},
"pgtuner": {
"$ref": "#/$defs/mcpSidecar"
},
"playwright": {
"$ref": "#/$defs/mcpSidecar"
}
},
"additionalProperties": false
}
},
"required": ["sidecars"]
},
"envSecretName": {
"type": "string",
"description": "Custom environment secret name"
}
},
"required": ["name"],
"$defs": {
"resourceSpec": {
"type": "object",
"properties": {
"memory": {
"type": "string",
"pattern": "^[0-9]+[KMGT]i$",
"description": "Memory resource specification"
},
"cpu": {
"type": "string",
"pattern": "^[0-9]+m?$",
"description": "CPU resource specification"
}
},
"required": ["memory", "cpu"]
},
"mcpSidecar": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean",
"description": "Enable this MCP sidecar"
},
"image": {
"type": "object",
"properties": {
"repository": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"required": ["repository", "tag"]
},
"port": {
"type": "integer",
"minimum": 1,
"maximum": 65535,
"description": "Port for the MCP sidecar"
},
"resources": {
"type": "object",
"properties": {
"requests": {
"$ref": "#/$defs/resourceSpec"
},
"limits": {
"$ref": "#/$defs/resourceSpec"
}
},
"required": ["requests", "limits"]
}
},
"required": ["enabled", "image", "port", "resources"]
}
}
}
+156 -88
View File
@@ -1,6 +1,11 @@
# =============================================================================
# BASIC CONFIGURATION
# =============================================================================
# Instance name — used to generate resource names (devcontainer-{name}, userhome-{name}) # Instance name — used to generate resource names (devcontainer-{name}, userhome-{name})
name: "" name: ""
# Container image configuration
image: image:
repository: ghcr.io/cpfarhood/devcontainer repository: ghcr.io/cpfarhood/devcontainer
tag: latest tag: latest
@@ -9,43 +14,40 @@ image:
# GitHub repository to clone into /workspace # GitHub repository to clone into /workspace
githubRepo: "" githubRepo: ""
# IDE to launch inside the container. # =============================================================================
# Options: # ACCESS & INTERFACE
# vscode — VSCode via VNC browser UI on port 5800 (default) # =============================================================================
# antigravity — Google Antigravity (VSCode fork) via VNC on port 5800
# none — no IDE; useful when ssh: true is the sole access method
ide: vscode
# Start an OpenSSH server on port 22 in addition to the IDE. # IDE configuration
# Set SSH_AUTHORIZED_KEYS in the env secret to allow key-based login. ide:
ssh: false # Options: vscode | antigravity | none
type: vscode
# Happy Coder endpoints # SSH access configuration
happyServerUrl: "https://happy.farh.net" ssh:
happyWebappUrl: "https://happy-coder.farh.net" enabled: false
happyHomeDir: "/config/userdata/.happy"
happyExperimental: "true"
# VNC display # VNC display settings
display: display:
width: "1920" width: "1920"
height: "1080" height: "1080"
secureConnection: "0" # Set to "1" when TLS is not terminated upstream
# Set to "0" when TLS is terminated at the gateway layer # User configuration
secureConnection: "0" user:
id: "1000"
groupId: "1000"
userId: "1000" # =============================================================================
groupId: "1000" # INFRASTRUCTURE & RESOURCES
# =============================================================================
# Storage configuration
storage: storage:
size: 32Gi size: 32Gi
className: ceph-filesystem className: ceph-filesystem
# Shared memory size — mounted at /dev/shm as a memory-backed emptyDir. # Resource allocation
# Electron apps (Antigravity, Chrome) use /dev/shm for GPU/IPC buffers.
shm:
sizeLimit: 2Gi
resources: resources:
requests: requests:
memory: "2Gi" memory: "2Gi"
@@ -54,70 +56,136 @@ resources:
memory: "8Gi" memory: "8Gi"
cpu: "4000m" cpu: "4000m"
# Kubernetes cluster access granted to the devcontainer pod via RBAC. # Shared memory for Electron apps (Chrome, Antigravity)
# Options: shm:
# none — no cluster access (default) sizeLimit: 2Gi
# readonlyns — get/list/watch all resources in the release namespace
# readwritens — full access to all resources in the release namespace # Kubernetes cluster access via RBAC
# readonly — get/list/watch all resources cluster-wide # Options: none | readonlyns | readwritens | readonly | readwrite
# readwrite — full access to all resources cluster-wide
clusterAccess: none clusterAccess: none
# Name of existing Secret containing env vars (GITHUB_TOKEN, VNC_PASSWORD, etc.) # =============================================================================
# Defaults to: devcontainer-{name}-secrets-env # INTEGRATIONS
envSecretName: "" # =============================================================================
# MCP server sidecars — run alongside the devcontainer to inherit pod RBAC. # Happy Coder AI assistant configuration
mcpSidecars: happy:
kubernetes: serverUrl: "https://happy.farh.net"
enabled: true webappUrl: "https://happy-coder.farh.net"
image: homeDir: "/config/userdata/.happy"
repository: quay.io/containers/kubernetes_mcp_server experimental: "true"
tag: v0.0.57 # Pinned version (Jan 27, 2025) with token exchange and field selector support
port: 8080 # MCP (Model Context Protocol) server sidecars
resources: mcp:
requests: sidecars:
memory: "64Mi" # Kubernetes API access
cpu: "50m" kubernetes:
limits: enabled: true
memory: "256Mi" image:
cpu: "500m" repository: quay.io/containers/kubernetes_mcp_server
flux: tag: v0.0.57
enabled: true port: 8080
image: resources:
repository: ghcr.io/controlplaneio-fluxcd/flux-operator-mcp requests:
tag: v0.41.1 memory: "64Mi"
port: 8081 cpu: "50m"
resources: limits:
requests: memory: "256Mi"
memory: "64Mi" cpu: "500m"
cpu: "50m"
limits: # Flux GitOps operations
memory: "256Mi" flux:
cpu: "500m" enabled: true
homeassistant: image:
enabled: false # Disabled by default, requires HOMEASSISTANT_URL and HOMEASSISTANT_TOKEN repository: ghcr.io/controlplaneio-fluxcd/flux-operator-mcp
image: tag: v0.41.1
repository: ghcr.io/homeassistant-ai/ha-mcp port: 8081
tag: 6.7.1 # Pinned version (Feb 20, 2026) - latest stable release resources:
port: 8087 requests:
resources: memory: "64Mi"
requests: cpu: "50m"
memory: "64Mi" limits:
cpu: "50m" memory: "256Mi"
limits: cpu: "500m"
memory: "256Mi"
cpu: "500m" # Home Assistant smart home control
github: homeassistant:
enabled: false # DISABLED: GitHub MCP server has been archived, image doesn't exist enabled: false # Requires HOMEASSISTANT_URL and HOMEASSISTANT_TOKEN
image: image:
repository: ghcr.io/modelcontextprotocol/servers/github repository: ghcr.io/homeassistant-ai/ha-mcp
tag: latest # Update to specific version once available tag: stable
port: 8088 port: 8087
resources: resources:
requests: requests:
memory: "64Mi" memory: "64Mi"
cpu: "50m" cpu: "50m"
limits: limits:
memory: "256Mi" memory: "256Mi"
cpu: "500m" cpu: "500m"
# GitHub API access (DISABLED: archived image)
github:
enabled: false
image:
repository: ghcr.io/modelcontextprotocol/servers/github
tag: latest
port: 8088
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "256Mi"
cpu: "500m"
# PostgreSQL performance tuning
pgtuner:
enabled: false # Requires DATABASE_URI in secrets
image:
repository: dog830228/pgtuner_mcp
tag: latest
port: 8085
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "256Mi"
cpu: "500m"
# Browser automation and web testing
playwright:
enabled: true
image:
repository: microsoft/playwright-mcp
tag: latest
port: 8086
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "1000m"
# =============================================================================
# SMART DEFAULTS & AUTO-DETECTION
# =============================================================================
# Environment auto-detection based on name patterns
# Automatically adjusts defaults for dev/test/prod/team environments
autoDetect:
environment: true # Auto-detect dev/prod/team from name
storageClass: true # Auto-detect ReadWriteMany storage class
resources: true # Auto-size resources based on enabled features
# Resource profiles (auto-selected based on environment and features)
# Override specific values above to customize
resourceProfile: auto # auto | small | medium | large | xlarge
# =============================================================================
# ADVANCED CONFIGURATION
# =============================================================================
# Custom env secret name (defaults to: devcontainer-{name}-secrets-env)
envSecretName: ""
+1 -13
View File
@@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
# Initialize repository and start Happy Coder # Initialize repository
set -e set -e
echo "=== Repository Initialization ===" echo "=== Repository Initialization ==="
@@ -102,18 +102,6 @@ chown -R "$RUN_UID:$RUN_GID" "$WORKSPACE_DIR"
mkdir -p "$HOME" mkdir -p "$HOME"
chown "$RUN_UID:$RUN_GID" "$HOME" chown "$RUN_UID:$RUN_GID" "$HOME"
# Start Happy Coder daemon. startapp.sh already runs as the app user (UID 1000),
# so no sudo needed — Happy/Claude Code will find credentials in the correct home dir.
echo "Starting Happy Coder..."
# Remove stale lock file. HAPPY_HOME_DIR lives on the home PVC so it survives
# pod restarts — without this cleanup the daemon refuses to start after a crash.
rm -f "${HAPPY_HOME_DIR:-$HOME/.happy}/daemon.state.json.lock"
cd "$WORKSPACE_DIR"
happy daemon start || echo "Happy Coder daemon failed to start, continuing anyway..."
echo "Happy Coder daemon started"
# Export workspace directory for startapp.sh # Export workspace directory for startapp.sh
echo "$WORKSPACE_DIR" > /tmp/workspace-dir echo "$WORKSPACE_DIR" > /tmp/workspace-dir
+2 -2
View File
@@ -2,9 +2,9 @@
# Start application script for baseimage-gui # Start application script for baseimage-gui
set -e set -e
echo "=== Starting Antigravity Dev Container ===" echo "=== Starting Dev Container ==="
# Initialize repository and Happy Coder # Initialize repository
/usr/local/bin/init-repo /usr/local/bin/init-repo
# Get workspace directory # Get workspace directory