# gcloud Skill Common GCP patterns for the apes platform. All commands invoke gcloud/docker directly via Bash. **Project:** `apes-platform` **Region:** `europe-west1` **Zone:** `europe-west1-b` ## Current Infrastructure | Service | Host | VM | IP | Compose dir | |---------|------|----|----|-------------| | Gitea | git.unslope.com | gitea-vm | 34.78.255.104 | /opt/gitea | | Colony | apes.unslope.com | colony-vm (e2-medium) | 35.241.200.77 | /opt/colony-src/infra/colony | ## SSH into VMs ```bash gcloud compute ssh --zone=europe-west1-b --project=apes-platform gcloud compute ssh --zone=europe-west1-b --project=apes-platform --command="" ``` ## Colony Deploy ```bash # 1. SSH in and pull latest code gcloud compute ssh colony-vm --zone=europe-west1-b --project=apes-platform \ --command='sudo bash -c "cd /opt/colony-src && git pull"' # 2. Rebuild (deps cached, only source changes recompile ~30s) gcloud compute ssh colony-vm --zone=europe-west1-b --project=apes-platform \ --command='sudo bash -c "cd /opt/colony-src/infra/colony && docker compose build 2>&1 | tail -5"' # 3. Restart gcloud compute ssh colony-vm --zone=europe-west1-b --project=apes-platform \ --command='sudo bash -c "cd /opt/colony-src/infra/colony && docker compose up -d"' # 4. Verify gcloud compute ssh colony-vm --zone=europe-west1-b --project=apes-platform \ --command='sudo bash -c "sleep 3 && docker logs colony 2>&1 | tail -5 && curl -s http://localhost:3001/api/health"' ``` ## Docker Compose on VMs ```bash # Restart a service gcloud compute ssh --zone=europe-west1-b --project=apes-platform \ --command="sudo bash -c 'cd && docker compose restart '" # View logs (use 2>&1 for stderr) gcloud compute ssh --zone=europe-west1-b --project=apes-platform \ --command='sudo docker logs 2>&1 | tail -50' # Full redeploy gcloud compute ssh --zone=europe-west1-b --project=apes-platform \ --command="sudo bash -c 'cd && docker compose pull && docker compose up -d'" ``` ## Install Docker on Debian 12 ```bash gcloud compute ssh --zone=europe-west1-b --project=apes-platform --command='sudo bash -c " apt-get update && apt-get install -y ca-certificates curl gnupg git install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg chmod a+r /etc/apt/keyrings/docker.gpg echo \"deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable\" > /etc/apt/sources.list.d/docker.list apt-get update && apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin systemctl enable docker && systemctl start docker "' ``` ## Static IPs & DNS ```bash # Reserve IP gcloud compute addresses create --region=europe-west1 --project=apes-platform # Get IP gcloud compute addresses describe --region=europe-west1 --project=apes-platform --format='value(address)' # DNS: Namecheap → Advanced DNS → Add A Record → host= value= # Verify: dig @dns1.registrar-servers.com A +short ``` ## Firewall Rules ```bash gcloud compute firewall-rules list --project=apes-platform gcloud compute firewall-rules create --allow=tcp: --target-tags=web-server --project=apes-platform gcloud compute firewall-rules delete --project=apes-platform --quiet ``` ## New VM Pattern ```bash gcloud compute instances create \ --project=apes-platform \ --zone=europe-west1-b \ --machine-type=e2-small \ --image-family=debian-12 \ --image-project=debian-cloud \ --boot-disk-size=20GB \ --tags=web-server \ --address= ``` ## Gitea (git.unslope.com) ```bash # Git push/pull: HTTP on port 3000 (no gcloud needed) git clone http://git.unslope.com:3000/benji/apes.git git remote set-url origin http://:@34.78.255.104:3000/benji/apes.git # Create API token curl -u user:pass -X POST 'https://git.unslope.com/api/v1/users//tokens' \ -H 'Content-Type: application/json' -d '{"name":"my-token","scopes":["all"]}' # Create user (admin only, via SSH) gcloud compute ssh gitea-vm --zone=europe-west1-b --project=apes-platform \ --command='sudo docker exec -u git gitea gitea admin user create --username --password "" --email ""' ``` ## Troubleshooting | Error | Fix | |-------|-----| | SSH timeout | VM under load (e.g. compiling Rust). Wait and retry. Don't kill builds. | | SSH connection refused | VM still booting. Wait 30s, retry. | | Docker not running | `sudo systemctl start docker` | | Caddy cert failed | Check DNS: `dig @dns1.registrar-servers.com A +short`. Clear Caddy data if stuck on staging cert: `sudo rm -rf /caddy_data/caddy/certificates/acme-staging*` | | Container exits immediately | Check binary size — if < 1MB it's the stub binary. Rebuild with `docker rmi && docker compose build` | | Container restarting, no logs | Binary panicking before first print. Run interactively: `docker run --rm -e DATABASE_URL=... /app/` | | Git push fails (DNS) | Use IP directly: `http://34.78.255.104:3000/benji/apes.git` | | Git push auth fails | Use API token, not password (special chars break URL encoding) | | Build takes forever | First Rust build ~10min on e2-medium. Subsequent builds ~30s (deps cached). Don't use `--no-cache` unless Dockerfile changed. | | Docker build SSH timeout | Build in background: `nohup docker compose build > /tmp/build.log 2>&1 &` then check later |