Deploy a remote Claude Code environment on Kubernetes. Connect to it from the Claude Desktop app, your phone, or anywhere you have internet access.
One command gives you a persistent, cloud-hosted workspace with Claude Code, optional backend services, and databases — all defined by a single config file in your repo.
AI coding agents change what "remote development" means. You're not SSH-ing into a server to type code — you're sending high-level instructions to an agent that needs compute, not low-latency keystrokes. This means:
- Work from anywhere — send instructions from your phone, check back later.
- Keep it running — the agent works while your laptop is closed.
- Parallel environments — spin up multiple agents on different branches.
- Your infrastructure — code stays on your cluster, not a third-party SaaS.
graph TB
subgraph Pod["Kubernetes Pod (rda-<id>)"]
subgraph Containers
CC["claude-code<br/>Claude Code CLI + tmux<br/>Control panel · K8s log viewer"]
SVC["your services<br/>Dev server, API, workers, etc."]
end
PVC["/workspace (PVC)"]
CC --- PVC
SVC --- PVC
end
subgraph Infra["Supporting Infrastructure"]
DB["Database, cache, etc."]
end
You["You, from anywhere<br/>Claude Desktop · Mobile · Browser"]
You -->|"Cloudflare Tunnel / kubectl"| Pod
- A Kubernetes cluster
kubectl,helm,git, andyqinstalled- A GitHub token (for private repos)
- Docker (for building images)
# Set your container registry.
export REGISTRY=ghcr.io/your-org
# Build and push.
make docker-build-pushCreate .remote-dev.yaml in your repository root:
workspace:
packageManager: npm
install: npm install
services:
app:
command: npm run dev
port: 3000See examples/ for more complex setups with backend services and databases.
export GITHUB_TOKEN=ghp_...
# Deploy with make (REGISTRY overrides the image paths in the Helm values).
make deploy ID=myapp REPO=https://github.com/your-org/myapp.git REGISTRY=ghcr.io/your-org
# Or call the script directly.
REGISTRY=ghcr.io/your-org ./scripts/deploy.sh myapp https://github.com/your-org/myapp.git mainThis creates a namespace rda-myapp with everything running.
Shell into the pod once to authenticate Claude Code:
make k8s-exec ID=myapp
claude login
exitOpen the control panel (port 3200) and click Start Claude Code, then Enable Remote Control. The control panel will display the connection URL — open it in the Claude Desktop app (or on your phone) and you're connected.
./scripts/teardown.sh myappThe .remote-dev.yaml file in your repo root defines the environment:
# Working directory within the repo.
workspace:
dir: . # Subdirectory within the repo, or "." for root.
packageManager: pnpm
install: pnpm install
image: node:20 # Image for init containers.
# Services running alongside Claude Code. Each becomes a container.
services:
app:
command: pnpm run dev
port: 3000
api:
dir: backend
command: python -m uvicorn main:app --host 0.0.0.0
port: 8000
image: python:3.12-slim
env:
DB_HOST: postgres
# Infrastructure.
infra:
postgres:
version: "17"
database: mydb
user: myuser
redis:
version: "7"
# Environment variables for all containers.
env:
NODE_ENV: development
# Secrets (values provided via envs/<id>.env, never committed).
secrets:
- DB_PASSWORD
- API_SECRET
# Commands to run after install, before services start.
init:
- command: python manage.py migrate
dir: backend
image: python:3.12-slimSet TUNNEL_TOKEN and TUNNEL_DOMAIN before deploying to expose services
via Cloudflare Tunnel. Each service gets a subdomain:
<port>-<deployment-id>.<domain>.
For quick access without a tunnel:
kubectl port-forward -n rda-myapp svc/rda-myapp \
4000:3000 \ # preview
4001:3200 # control panelA web UI on port 3200 for managing the environment:
- Start Claude Code
- Enable remote control (generates the connection URL)
- Restart the pod
- View logs from any container in the pod via the K8s API
Protect the control panel with Cloudflare Access when exposed via a tunnel.
For local development without Kubernetes:
# Set environment variables.
export GITHUB_TOKEN=ghp_...
export REPO_URL=https://github.com/your-org/myapp.git
export API_KEY=dev-key
# Build and start.
make build
make up
# Shell into the Claude Code container.
make dev-exec build Build containers
up Start the stack
down Stop the stack
logs Tail container logs
dev-exec Shell into local claude-code
deploy Deploy to k8s: make deploy ID=myapp REPO=https://...
teardown Tear down: make teardown ID=myapp
docker-build Build container images
docker-push Push container images
docker-build-push Build and push images
k8s-exec Shell into k8s claude-code: make k8s-exec ID=myapp
k8s-logs Tail k8s pod logs: make k8s-logs ID=myapp