Files
devcontainer/DEPLOYMENT.md
Chris Farhood f79be89e4e docs: Add comprehensive deployment and variables reference
Add detailed documentation to enable autonomous deployment by other AI agents.

New files:
- DEPLOYMENT.md: Complete step-by-step deployment guide
  - Prerequisites checklist
  - Required vs optional variables clearly marked
  - All configuration variables documented with examples
  - Troubleshooting section
  - Quick deploy example with all values
  - Configuration summary table

- VARIABLES.md: Complete variables reference
  - All variables listed with file, line, type, description
  - Required variables clearly marked
  - Optional variables with defaults
  - Variables grouped by use case
  - Quick copy templates
  - Environment variables reference

Updated README.md:
- Add links to new documentation files
- Clear pointer to DEPLOYMENT.md for deployment

These docs enable another Claude Code instance to:
1. Identify all required configuration variables
2. Know where to find/set each variable
3. Understand what values are valid
4. Deploy successfully without human intervention

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-15 08:36:45 -05:00

11 KiB

Deployment Guide

This guide provides step-by-step instructions for deploying the Antigravity Dev Container to Kubernetes.

Prerequisites

  • Kubernetes cluster with Gateway API support
  • kubectl configured to access your cluster
  • ReadWriteMany storage class available (e.g., ceph-filesystem, nfs-client, efs-sc)
  • Sealed Secrets controller installed (for secret encryption)
  • GitHub Container Registry access (images are public)

Required Configuration Variables

Before deploying, you need to provide the following configuration:

1. Storage Configuration

Variable: storageClassName Location: k8s/statefulset.yaml (line ~117) Description: The ReadWriteMany storage class name in your cluster Example values:

  • ceph-filesystem (Rook-Ceph)
  • nfs-client (NFS)
  • efs-sc (AWS EFS)
  • azurefile (Azure Files)
  • filestore (GCP Filestore)

How to find your storage class:

kubectl get storageclass

Look for a storage class that supports ReadWriteMany access mode.

2. GitHub Repository (Required)

Variable: github-repo Location: k8s/configmap.yaml (line ~9) Description: The GitHub repository URL to clone on container startup Format: https://github.com/username/repository Example: https://github.com/cpfarhood/my-project

3. GitHub Token (Optional, for private repos)

Variable: github-token Location: k8s/secrets-example.yaml (sealed secret) Description: GitHub Personal Access Token for cloning private repositories Format: ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Required: Only if cloning a private repository

How to create a GitHub token:

  1. Go to https://github.com/settings/tokens
  2. Click "Generate new token (classic)"
  3. Select scopes: repo (for private repos)
  4. Generate and copy the token

4. VNC Password (Optional)

Variable: vnc-password Location: k8s/secrets-example.yaml (sealed secret) Description: Password for accessing the VNC web interface Format: Any string (recommend 12+ characters) Required: Optional, but recommended for security

5. Gateway Configuration (Required for external access)

Variables:

  • parentRefs.name - Your Gateway resource name
  • parentRefs.namespace - Namespace where Gateway is deployed
  • hostnames - Domain name for accessing the container

Location: k8s/httproute.yaml Example:

parentRefs:
- name: cilium-gateway  # Your Gateway name
  namespace: kube-system  # Your Gateway namespace
hostnames:
- "devcontainer.example.com"  # Your domain

6. Namespace (Optional)

Variable: namespace Location: k8s/kustomization.yaml (line ~5) Description: Kubernetes namespace to deploy into Default: default Example: devcontainer, development, team-workspaces

7. Container Image (Optional)

Variable: image Location: k8s/statefulset.yaml (line ~32) Description: Docker image to use Default: ghcr.io/cpfarhood/devcontainer:latest Format: registry/repository:tag

8. Resource Limits (Optional)

Variables:

  • resources.requests.memory (default: 2Gi)
  • resources.requests.cpu (default: 1000m)
  • resources.limits.memory (default: 8Gi)
  • resources.limits.cpu (default: 4000m)

Location: k8s/statefulset.yaml (lines ~98-103)

9. Happy Coder Configuration (Optional)

Variables:

  • happy-server-url - Custom Happy server URL
  • happy-webapp-url - Custom Happy webapp URL

Location: k8s/configmap.yaml (lines ~12-13, commented out) Default: Uses Happy's default servers When to set: Only if using a self-hosted Happy instance

Deployment Steps

Step 1: Clone the Repository

git clone https://github.com/cpfarhood/devcontainer.git
cd devcontainer

Step 2: Configure Storage Class

Edit k8s/statefulset.yaml and find the volumeClaimTemplates section (around line 117):

# Find your storage class
kubectl get storageclass

# Edit the file
vi k8s/statefulset.yaml

Change storageClassName to match your cluster:

volumeClaimTemplates:
- metadata:
    name: userhome
  spec:
    accessModes: [ "ReadWriteMany" ]
    storageClassName: "ceph-filesystem"  # ← Change this
    resources:
      requests:
        storage: 10Gi

Step 3: Configure GitHub Repository

Edit k8s/configmap.yaml:

vi k8s/configmap.yaml

Set your repository URL:

data:
  github-repo: "https://github.com/yourusername/yourrepo"

Step 4: Configure Gateway (HTTPRoute)

Edit k8s/httproute.yaml:

# Find your Gateway
kubectl get gateway -A

# Edit the file
vi k8s/httproute.yaml

Update with your Gateway details:

spec:
  parentRefs:
  - name: your-gateway-name        # ← Change this
    namespace: your-gateway-namespace  # ← Change this
  hostnames:
  - "devcontainer.yourdomain.com"  # ← Change this

Step 5: Create Secrets

Create the secrets for GitHub token and VNC password:

# Create the secret
kubectl create secret generic antigravity-secrets \
  --from-literal=github-token='ghp_your_token_here' \
  --from-literal=vnc-password='your_vnc_password' \
  --dry-run=client -o yaml | \
  kubeseal --format=yaml > k8s/sealedsecrets.yaml

# Verify the sealed secret was created
cat k8s/sealedsecrets.yaml

If you don't have Sealed Secrets controller:

Option 1: Install Sealed Secrets

kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml

Option 2: Use plain secrets (not recommended for production)

kubectl create secret generic antigravity-secrets \
  --from-literal=github-token='ghp_your_token_here' \
  --from-literal=vnc-password='your_vnc_password'

Step 6: Review Configuration (Optional)

Review and adjust optional settings:

Namespace:

vi k8s/kustomization.yaml
# Change line 5: namespace: default

Resource limits:

vi k8s/statefulset.yaml
# Adjust lines 98-103 for your needs

Step 7: Deploy to Kubernetes

# Deploy everything
kubectl apply -k k8s/

# Or if you changed the namespace
kubectl apply -k k8s/ -n your-namespace

Step 8: Verify Deployment

# Check StatefulSet
kubectl get statefulset antigravity

# Check Pod
kubectl get pods -l app=antigravity

# Check PVC
kubectl get pvc -l app=antigravity

# Check HTTPRoute
kubectl get httproute antigravity

# View logs
kubectl logs antigravity-0

Step 9: Access the Container

Option A: Via HTTPRoute (external access)

# Open in browser
open https://devcontainer.yourdomain.com

Option B: Via Port Forward (local access)

# Port forward to localhost
kubectl port-forward statefulset/antigravity 5800:5800

# Open in browser
open http://localhost:5800

Configuration Summary

Here's a quick checklist of all variables you need to set:

Required Variables

Variable File Line Example Value
storageClassName k8s/statefulset.yaml ~117 ceph-filesystem
github-repo k8s/configmap.yaml ~9 https://github.com/user/repo
parentRefs.name k8s/httproute.yaml ~8 cilium-gateway
parentRefs.namespace k8s/httproute.yaml ~9 kube-system
hostnames k8s/httproute.yaml ~10 devcontainer.example.com

Optional Variables

Variable File Line Default When to Change
namespace k8s/kustomization.yaml ~5 default If deploying to different namespace
github-token Sealed secret N/A None For private repos
vnc-password Sealed secret N/A None For VNC security
image k8s/statefulset.yaml ~32 ghcr.io/cpfarhood/devcontainer:latest For specific version or custom build
resources.* k8s/statefulset.yaml ~98-103 2Gi/8Gi RAM, 1/4 CPU Based on workload needs
happy-server-url k8s/configmap.yaml ~12 Default Happy server For self-hosted Happy
happy-webapp-url k8s/configmap.yaml ~13 Default Happy webapp For self-hosted Happy

Troubleshooting

Pod not starting

Check events:

kubectl describe pod antigravity-0

Common issues:

  • Storage class doesn't support ReadWriteMany
  • PVC not binding (check storage class exists)
  • Image pull errors (check image name)

Repository not cloning

Check logs:

kubectl logs antigravity-0 | grep -A 10 "Repository Initialization"

Common issues:

  • Invalid GitHub URL
  • Private repo without token
  • Token doesn't have correct permissions

HTTPRoute not working

Check HTTPRoute:

kubectl describe httproute antigravity

Common issues:

  • Gateway name/namespace incorrect
  • Domain not pointing to Gateway
  • TLS certificate not issued

VNC not accessible

Check service:

kubectl get svc antigravity
kubectl describe svc antigravity

Port forward test:

kubectl port-forward antigravity-0 5800:5800
# Try accessing http://localhost:5800

Quick Deploy Example

Complete deployment with all values filled in:

# 1. Set your values
STORAGE_CLASS="ceph-filesystem"
GITHUB_REPO="https://github.com/myuser/myproject"
GITHUB_TOKEN="ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
VNC_PASSWORD="my-secure-password-123"
GATEWAY_NAME="cilium-gateway"
GATEWAY_NAMESPACE="kube-system"
DOMAIN="devcontainer.example.com"

# 2. Update storage class
sed -i "s/storageClassName: .*/storageClassName: \"$STORAGE_CLASS\"/" k8s/statefulset.yaml

# 3. Update GitHub repo
sed -i "s|github-repo: .*|github-repo: \"$GITHUB_REPO\"|" k8s/configmap.yaml

# 4. Update Gateway
sed -i "s/- name: gateway/- name: $GATEWAY_NAME/" k8s/httproute.yaml
sed -i "s/namespace: gateway-system/namespace: $GATEWAY_NAMESPACE/" k8s/httproute.yaml
sed -i "s/antigravity.example.com/$DOMAIN/" k8s/httproute.yaml

# 5. Create sealed secret
kubectl create secret generic antigravity-secrets \
  --from-literal=github-token="$GITHUB_TOKEN" \
  --from-literal=vnc-password="$VNC_PASSWORD" \
  --dry-run=client -o yaml | \
  kubeseal --format=yaml > k8s/sealedsecrets.yaml

# 6. Deploy
kubectl apply -k k8s/

# 7. Watch deployment
kubectl get pods -l app=antigravity -w

Updates and Maintenance

Updating the Image

The image is automatically built and pushed to ghcr.io on every commit to main.

To use latest:

kubectl set image statefulset/antigravity \
  antigravity=ghcr.io/cpfarhood/devcontainer:latest

To use specific version:

kubectl set image statefulset/antigravity \
  antigravity=ghcr.io/cpfarhood/devcontainer:v1.0.0

Changing Repository

Edit the ConfigMap and restart:

kubectl edit configmap antigravity-config
# Change github-repo value
kubectl rollout restart statefulset/antigravity

Scaling

# Scale to multiple instances (each gets own home PVC)
kubectl scale statefulset antigravity --replicas=3

Support

For issues or questions: