GCP Workstations for AI Dev
Single-developer Google Cloud Workstations playbook. Provisions a workstation that runs Claude Code 2.1, Antigravity CLI (agy) 1.0, GitHub Copilot CLI 1.0, and supporting tooling, with sensible auth and cost defaults.
This is not a multi-tenant guide. Single-dev assumptions apply throughout.
When to use
- Spinning up a new GCP Workstation for AI-assisted development
- Authoring or updating the custom image with the AI CLI stack
- Picking the right auth flow per tool on a cloud VM
- Estimating monthly cost (or comparing against alternatives)
- Diagnosing persistence, networking, or credential-store issues
Versions and assumptions
| Component |
Version targeted |
| Google Cloud Workstations |
API v1 (April 2026) |
| Base image |
us-central1-docker.pkg.dev/cloud-workstations-images/predefined/code-oss:latest |
| Node.js |
22 LTS (for the AI CLIs) |
| Claude Code |
2.1.x via @anthropic-ai/claude-code |
| Antigravity CLI (agy) |
1.0.4 (agy binary at ~/.local/bin/agy). TODO(agy): confirm agy install + auth on GCP Workstation |
| GitHub Copilot CLI |
1.0.x via @github/copilot |
Quick task index
| Task |
Read |
| Provision a new cluster/config/workstation |
references/provision.md |
| Build the custom Dockerfile (AI CLIs preinstalled) |
references/custom-image.md + scripts/Dockerfile.ai-dev |
| Push image to Artifact Registry |
references/custom-image.md (Push section) |
| Pick auth per tool (Claude / agy / Copilot) |
references/auth-per-tool.md |
Understand $HOME vs /var//tmp persistence |
references/persistent-home.md |
| Manage secrets (Secret Manager + use-time fetch) |
references/secrets-and-security.md |
| Configure networking (public/private, IAP, egress) |
references/networking.md |
| Estimate cost and pick the right tier |
references/cost-optimization.md |
| Common gotchas (libsecret, clock drift, OAuth) |
references/gotchas-and-fixes.md |
| Run the lifecycle from end to end |
scripts/create-workstation.sh |
| Workstation startup hook with use-time secret fetch |
assets/startup-script.sh |
Lifecycle in three commands
# 1. Cluster (one per project, region)
gcloud workstations clusters create my-cluster \
--region=us-central1 \
--network=projects/$PROJECT/global/networks/default \
--subnetwork=projects/$PROJECT/regions/us-central1/subnetworks/default
# 2. Config (one per machine type / image / persistent disk shape)
gcloud workstations configs create ai-dev-config \
--cluster=my-cluster \
--region=us-central1 \
--machine-type=e2-standard-4 \
--container-custom-image=us-central1-docker.pkg.dev/$PROJECT/ai-dev/ai-dev:latest \
--pd-disk-type=pd-ssd \
--pd-disk-size=200 \
--idle-timeout=1800s \
--running-timeout=43200s
# 3. Workstation
gcloud workstations create my-station \
--cluster=my-cluster \
--config=ai-dev-config \
--region=us-central1
scripts/create-workstation.sh runs this end-to-end with idempotency and error handling.
Persistence summary
| Path |
Persists across stop/start? |
Persists across delete-workstation? |
$HOME (e.g. /home/user) |
YES |
YES (the persistent disk is decoupled from the workstation lifecycle) |
/var, /tmp, /etc, /usr |
NO |
NO |
Hidden caches outside $HOME (e.g. /root/.cache) |
NO |
NO |
This means:
~/.claude/, ~/.antigravity/, ~/.gemini/ (agy config lives under ~/.antigravity/ and ~/.gemini/antigravity-cli/), ~/.copilot/, ~/.config/gh/, ~/.npm/, ~/.cargo/, ~/.npm-global/ all persist
- Anything you
apt install is gone after restart unless it's baked into the image
- Build a custom image (
scripts/Dockerfile.ai-dev) for everything that should survive
Auth per tool — one-line summary
| Tool |
Recommended on GCP Workstation |
Why |
| Claude Code |
Vertex AI ADC (CLAUDE_CODE_USE_VERTEX=1) |
Metadata server provides ADC; no key file; same region as Vertex |
| Antigravity CLI (agy) |
Antigravity account login |
agy authenticates via its own Antigravity account (config under ~/.antigravity/), NOT Vertex ADC. TODO(agy): confirm agy install + auth on GCP Workstation |
| GitHub Copilot CLI |
Device flow with TCP tunnel fallback |
OAuth opens a browser; use gcloud workstations start-tcp-tunnel to forward localhost to your laptop |
| Codex CLI |
OpenAI account login |
No GCP integration; works on cloud VM with copy-paste device code |
See references/auth-per-tool.md for the full table and exact commands.
Cost realistic numbers
- ~$144/mo fixed cluster fee (you pay this even with no workstations running, per cluster)
- ~$30/mo compute for an
e2-standard-4 running ~6 h/day on a 1800s idle timeout
- ~$20/mo for the 200 GB pd-ssd persistent disk
- Total realistic for daily-use single dev: $170-280/mo
Cheaper alternative: a non-spot GCE VM with a manually built custom image. ~50% cheaper but no managed image lifecycle, no built-in IDE-in-browser, no auto-stop.
Spot VMs are NOT recommended for persistent dev — interruptions kill long-running operations and $HOME is on a separate disk regardless.
See references/cost-optimization.md for detail.
Anti-patterns
| Don't |
Why |
Run apt install and expect it to persist |
/usr does not survive restart. Bake into the custom image. |
Export secrets via /etc/profile.d/ |
Plaintext on disk + visible to all users. Use Secret Manager + use-time fetch. See references/secrets-and-security.md. |
| Use spot VMs for persistent dev |
Interruptions kill in-flight operations. Use regular workstations. |
Skip libsecret-1-0 in the Dockerfile |
Without it, CLI credential stores fail and tokens go to plaintext fallbacks |
Skip chrony in the Dockerfile |
Clock drift causes OAuth 401s and TLS handshake failures |
Forget the --network flag on cluster creation |
Default cluster has no inbound; you'll need to recreate. |
| Mix multiple users on one workstation |
Single-dev assumption holds throughout this skill. Multi-user is out of scope. |
Use the legacy code-oss image without updating |
Pin to :latest is fine for personal dev; lock to a digest for reproducibility. |
Run gcloud auth login on the workstation expecting browser to open on your laptop |
The browser opens on the VM (no display). Use gcloud auth application-default login --no-launch-browser and copy the URL. |
| Embed the SA key file in the image |
Key files in images are an audit nightmare. Use ADC via metadata server. |
See also
references/provision.md — exact gcloud commands
references/custom-image.md — Dockerfile, build, push
references/auth-per-tool.md — canonical auth recommendation
references/persistent-home.md — what survives restarts
references/secrets-and-security.md — Secret Manager pattern, anti-patterns
references/networking.md — public/private, IAP, egress allow list
references/cost-optimization.md — pricing breakdown, alternatives
references/gotchas-and-fixes.md — libsecret, clock drift, browser OAuth, marketplace
scripts/Dockerfile.ai-dev — the actual Dockerfile (ready to docker build)
scripts/create-workstation.sh — idempotent lifecycle script
assets/startup-script.sh — workstation startup template with use-time secret fetch
claude-code-cli, antigravity-cli, gh-copilot-cli — per-tool docs
docker-fundamentals, docker-security — for Dockerfile review and hardening
ubuntu-server-admin — for OS-level tuning if you switch from code-oss to a base image
1---2name: gcp-workstations3description: Use when provisioning, configuring, or operating Google Cloud Workstations as a single-developer AI/dev environment with Claude Code, Antigravity CLI (agy), GitHub Copilot CLI, and supporting tooling. Covers cluster/config/workstation lifecycle, custom images, persistent home semantics, per-tool authentication strategies, networking, cost optimization, and security gotchas.4---56# GCP Workstations for AI Dev78Single-developer Google Cloud Workstations playbook. Provisions a workstation that runs Claude Code 2.1, Antigravity CLI (agy) 1.0, GitHub Copilot CLI 1.0, and supporting tooling, with sensible auth and cost defaults.910This is **not** a multi-tenant guide. Single-dev assumptions apply throughout.1112## When to use1314- Spinning up a new GCP Workstation for AI-assisted development15- Authoring or updating the custom image with the AI CLI stack16- Picking the right auth flow per tool on a cloud VM17- Estimating monthly cost (or comparing against alternatives)18- Diagnosing persistence, networking, or credential-store issues1920## Versions and assumptions2122| Component | Version targeted |23|---|---|24| Google Cloud Workstations | API v1 (April 2026) |25| Base image | `us-central1-docker.pkg.dev/cloud-workstations-images/predefined/code-oss:latest` |26| Node.js | 22 LTS (for the AI CLIs) |27| Claude Code | 2.1.x via `@anthropic-ai/claude-code` |28| Antigravity CLI (agy) | 1.0.4 (`agy` binary at `~/.local/bin/agy`). TODO(agy): confirm agy install + auth on GCP Workstation |29| GitHub Copilot CLI | 1.0.x via `@github/copilot` |3031## Quick task index3233| Task | Read |34|---|---|35| Provision a new cluster/config/workstation | `references/provision.md` |36| Build the custom Dockerfile (AI CLIs preinstalled) | `references/custom-image.md` + `scripts/Dockerfile.ai-dev` |37| Push image to Artifact Registry | `references/custom-image.md` (Push section) |38| Pick auth per tool (Claude / agy / Copilot) | `references/auth-per-tool.md` |39| Understand `$HOME` vs `/var`/`/tmp` persistence | `references/persistent-home.md` |40| Manage secrets (Secret Manager + use-time fetch) | `references/secrets-and-security.md` |41| Configure networking (public/private, IAP, egress) | `references/networking.md` |42| Estimate cost and pick the right tier | `references/cost-optimization.md` |43| Common gotchas (libsecret, clock drift, OAuth) | `references/gotchas-and-fixes.md` |44| Run the lifecycle from end to end | `scripts/create-workstation.sh` |45| Workstation startup hook with use-time secret fetch | `assets/startup-script.sh` |4647## Lifecycle in three commands4849```bash50# 1. Cluster (one per project, region)51gcloud workstations clusters create my-cluster \52 --region=us-central1 \53 --network=projects/$PROJECT/global/networks/default \54 --subnetwork=projects/$PROJECT/regions/us-central1/subnetworks/default5556# 2. Config (one per machine type / image / persistent disk shape)57gcloud workstations configs create ai-dev-config \58 --cluster=my-cluster \59 --region=us-central1 \60 --machine-type=e2-standard-4 \61 --container-custom-image=us-central1-docker.pkg.dev/$PROJECT/ai-dev/ai-dev:latest \62 --pd-disk-type=pd-ssd \63 --pd-disk-size=200 \64 --idle-timeout=1800s \65 --running-timeout=43200s6667# 3. Workstation68gcloud workstations create my-station \69 --cluster=my-cluster \70 --config=ai-dev-config \71 --region=us-central172```7374`scripts/create-workstation.sh` runs this end-to-end with idempotency and error handling.7576## Persistence summary7778| Path | Persists across stop/start? | Persists across delete-workstation? |79|---|---|---|80| `$HOME` (e.g. `/home/user`) | YES | YES (the persistent disk is decoupled from the workstation lifecycle) |81| `/var`, `/tmp`, `/etc`, `/usr` | NO | NO |82| Hidden caches outside `$HOME` (e.g. `/root/.cache`) | NO | NO |8384This means:8586- `~/.claude/`, `~/.antigravity/`, `~/.gemini/` (agy config lives under `~/.antigravity/` and `~/.gemini/antigravity-cli/`), `~/.copilot/`, `~/.config/gh/`, `~/.npm/`, `~/.cargo/`, `~/.npm-global/` all persist87- Anything you `apt install` is gone after restart unless it's baked into the image88- Build a custom image (`scripts/Dockerfile.ai-dev`) for everything that should survive8990## Auth per tool — one-line summary9192| Tool | Recommended on GCP Workstation | Why |93|---|---|---|94| Claude Code | Vertex AI ADC (`CLAUDE_CODE_USE_VERTEX=1`) | Metadata server provides ADC; no key file; same region as Vertex |95| Antigravity CLI (agy) | Antigravity account login | agy authenticates via its own Antigravity account (config under `~/.antigravity/`), NOT Vertex ADC. TODO(agy): confirm agy install + auth on GCP Workstation |96| GitHub Copilot CLI | Device flow with TCP tunnel fallback | OAuth opens a browser; use `gcloud workstations start-tcp-tunnel` to forward localhost to your laptop |97| Codex CLI | OpenAI account login | No GCP integration; works on cloud VM with copy-paste device code |9899See `references/auth-per-tool.md` for the full table and exact commands.100101## Cost realistic numbers102103- ~$144/mo fixed cluster fee (you pay this even with no workstations running, per cluster)104- ~$30/mo compute for an `e2-standard-4` running ~6 h/day on a 1800s idle timeout105- ~$20/mo for the 200 GB pd-ssd persistent disk106- **Total realistic for daily-use single dev: $170-280/mo**107108Cheaper alternative: a non-spot GCE VM with a manually built custom image. ~50% cheaper but no managed image lifecycle, no built-in IDE-in-browser, no auto-stop.109110**Spot VMs are NOT recommended** for persistent dev — interruptions kill long-running operations and `$HOME` is on a separate disk regardless.111112See `references/cost-optimization.md` for detail.113114## Anti-patterns115116| Don't | Why |117|---|---|118| Run `apt install` and expect it to persist | `/usr` does not survive restart. Bake into the custom image. |119| Export secrets via `/etc/profile.d/` | Plaintext on disk + visible to all users. Use Secret Manager + use-time fetch. See `references/secrets-and-security.md`. |120| Use spot VMs for persistent dev | Interruptions kill in-flight operations. Use regular workstations. |121| Skip `libsecret-1-0` in the Dockerfile | Without it, CLI credential stores fail and tokens go to plaintext fallbacks |122| Skip `chrony` in the Dockerfile | Clock drift causes OAuth 401s and TLS handshake failures |123| Forget the `--network` flag on cluster creation | Default cluster has no inbound; you'll need to recreate. |124| Mix multiple users on one workstation | Single-dev assumption holds throughout this skill. Multi-user is out of scope. |125| Use the legacy `code-oss` image without updating | Pin to `:latest` is fine for personal dev; lock to a digest for reproducibility. |126| Run `gcloud auth login` on the workstation expecting browser to open on your laptop | The browser opens on the VM (no display). Use `gcloud auth application-default login --no-launch-browser` and copy the URL. |127| Embed the SA key file in the image | Key files in images are an audit nightmare. Use ADC via metadata server. |128129## See also130131- `references/provision.md` — exact gcloud commands132- `references/custom-image.md` — Dockerfile, build, push133- `references/auth-per-tool.md` — canonical auth recommendation134- `references/persistent-home.md` — what survives restarts135- `references/secrets-and-security.md` — Secret Manager pattern, anti-patterns136- `references/networking.md` — public/private, IAP, egress allow list137- `references/cost-optimization.md` — pricing breakdown, alternatives138- `references/gotchas-and-fixes.md` — libsecret, clock drift, browser OAuth, marketplace139- `scripts/Dockerfile.ai-dev` — the actual Dockerfile (ready to `docker build`)140- `scripts/create-workstation.sh` — idempotent lifecycle script141- `assets/startup-script.sh` — workstation startup template with use-time secret fetch142- `claude-code-cli`, `antigravity-cli`, `gh-copilot-cli` — per-tool docs143- `docker-fundamentals`, `docker-security` — for Dockerfile review and hardening144- `ubuntu-server-admin` — for OS-level tuning if you switch from code-oss to a base image