Instead of disabling shared memory usage, mount a proper tmpfs at
/dev/shm so Antigravity (and Chrome) have real shared memory available.
Removes --disable-dev-shm-usage; keeps --no-sandbox (separate issue).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Electron apps crash in Docker without --no-sandbox and
--disable-dev-shm-usage, same as Chrome. VSCode handles this
internally; Antigravity does not.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SSH is now a standalone `ssh: true/false` value that starts sshd on
port 22 *in addition to* whatever IDE is running, rather than replacing
it. The `ide` value loses the `ssh` option and gains `none` (keep
container alive with no GUI IDE, useful when ssh: true is the only
access method).
- chart/values.yaml: replace `ide: ssh` with `ssh: false` boolean
- chart/templates/deployment.yaml: expose port 22 when ssh=true,
port 5800 when ide!=none; probes use HTTP (VNC) or TCP socket (SSH-only)
- chart/templates/service.yaml: include both ports when both enabled
- scripts/cont-init-sshd.sh: check SSH=true instead of IDE=ssh
- scripts/startapp.sh: add ide=none case (sleep infinity), drop ssh case
- chart/Chart.yaml: bump to 0.1.6
- README.md: update IDE choice and SSH access docs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add `ide` Helm value with options: vscode, antigravity, ssh
- Dockerfile: install Google Antigravity via apt and openssh-server
- scripts/startapp.sh: branch on IDE env var to launch the right app
- scripts/cont-init-sshd.sh: start sshd as root in SSH mode, set up
authorized_keys from SSH_AUTHORIZED_KEYS env var
- chart/templates/deployment.yaml: pass IDE env var, conditional ports
and probes (HTTP for VNC modes, TCP socket for SSH mode)
- chart/templates/service.yaml: expose port 5800 (VNC) or 22 (SSH)
- chart/values.yaml: add ide field with documentation
- README.md: document IDE choice, fix stale happyHomeDir references
- chart/Chart.yaml: bump to 0.1.5
Closes#10
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Moving it to /workspace (emptyDir) wiped Happy Coder's auth, config,
and state on every pod restart. The daemon also failed to start on boot
because the settings were gone.
Keep HAPPY_HOME_DIR on the home PVC (/home/user/.happy) for persistence.
The stale lock cleanup in init-repo.sh already handles the daemon.state.json.lock
problem that motivated the workspace move.
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace all stale references (claude user, k8s/ dir, StatefulSet,
old Happy paths) with current state (app user, Helm chart, Deployment)
- Add full Helm chart reference table including new clusterAccess option
with usage examples for all five access levels
- Document Happy Coder daemon setup and startup flow accurately
- Update troubleshooting commands to match actual resource names
- Add Claude authentication notes (browser OAuth + API key fallback)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a clusterAccess value with five levels:
none — no cluster access (default, no RBAC resources created)
readonlyns — Role + RoleBinding: get/list/watch in release namespace
readwritens — Role + RoleBinding: full access in release namespace
readonly — ClusterRole + ClusterRoleBinding: get/list/watch cluster-wide
readwrite — ClusterRole + ClusterRoleBinding: full access cluster-wide
A ServiceAccount is created for the pod whenever access != none and
referenced in the Deployment's serviceAccountName.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The daemon.state.json.lock lives on the home PVC and survives pod
restarts, causing happy daemon start to fail on every reboot. Moving
HAPPY_HOME_DIR to /workspace (emptyDir) means the entire happy state
directory is ephemeral and always clean on startup.
The rm -f in init-repo.sh is kept as a safety net for the within-run
case but is now a no-op on fresh starts.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
daemon.state.json.lock is left behind when the daemon crashes or is
killed (e.g. pod restart). On next startup happy daemon start sees the
lock and exits with "Failed to start daemon" without further detail.
Remove the lock file unconditionally at startup — if no daemon is
running, the lock is stale by definition.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sudo -u failed because the app user is not in sudoers. It was unnecessary
anyway: startapp.sh (and init-repo.sh) run as the app user (UID 1000) so
happy daemon start already executes as the correct user with the right HOME.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When init-repo.sh starts the happy daemon as root, HOME=/root so
Happy and Claude Code can't find credentials stored in /home/user.
The mobile app works when the user manually runs happy from a VSCode
terminal (as the user user) because the right home dir is in scope.
Use sudo -u with -E (preserve environment) so the daemon runs as the
correct user while still inheriting the pod's env vars (HAPPY_SERVER_URL,
HAPPY_WEBAPP_URL, ANTHROPIC_API_KEY, etc.).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Chrome requires --no-sandbox and --disable-dev-shm-usage when running
inside a Docker container, otherwise it crashes silently and the OAuth
popup never completes.
- Add a /usr/local/bin/google-chrome wrapper that injects these flags
- Install xdg-utils so xdg-open can resolve browser handlers in VNC
- Set BROWSER env var to the wrapper so Claude Code and xdg-open both
use it when opening the Claude Max login URL
The OAuth callback (to localhost) works fine inside VNC because both
the browser and the Claude Code local auth server share the same
container network namespace.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Happy Coder requires the `claude` CLI to be present but it was never
installed in the image. Add @anthropic-ai/claude-code to the npm
global install step alongside happy-coder.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
baseimage-gui creates the app user (UID 1000) at runtime with
shell=/sbin/nologin and home=/dev/null. VSCode tries to spawn the
user's login shell for terminals, which fails with exit code 1.
Adds a cont-init script that runs as root after baseimage-gui's
adduser step and corrects both the shell and home directory.
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>
The npm package installs a binary named 'happy', not 'happy-coder'.
Use 'happy daemon start' to run it as a background service.
Also create $HOME on the PVC if it doesn't exist yet, which was
causing git config failures on fresh volumes.
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>
Introduces chart/ with deployment, service, and PVC templates driven
by Helm values instead of Kustomize variable substitution. Removes
the flux/ directory which is superseded by the 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>