Skip to content

Deploy to Google Cloud

Deploy your personal agent to Google Cloud with an automated setup script (deploy/deploy-vm.sh). It defaults to an e2-micro VM (or your choice of VM SKU), with a persistent mounted SQLite database, automatic Let’s Encrypt HTTPS via Caddy, and 24/7 background automations.

Open in Cloud Shell

  1. Click Open in Cloud Shell above to launch Google Cloud Shell directly in your browser (no local CLI tools required), or clone the repository in Cloud Shell:
    Terminal window
    git clone https://github.com/kcthota/scout.git
    cd scout
  2. Run the automated deployment wizard:
    Terminal window
    ./deploy/deploy-vm.sh
  3. Enter your Google Gemini API Key.

    Use a pay-as-you-go key from a Google Cloud project with billing enabled. Using a free-tier AI Studio key with an external harness like Scout may be against Google’s terms of service, and the free tier has tight rate limits that cause 429 errors during agent tasks and reminders. Pay-as-you-go cost depends on your usage, so set a budget alert in Google Cloud Billing.

  • Enables required Google Cloud APIs (compute, artifactregistry, cloudbuild).
  • Lets you select your machine SKU (defaults to e2-micro).
  • Provisions a 30 GB standard persistent disk (pd-standard) and auto-configures a 2 GB swapfile (/swapfile).
  • Pulls the pre-built container image from GitHub Container Registry (ghcr.io/kcthota/scout:latest) by default—zero local compilation or build memory overhead on the VM.
  • If using a private GHCR package, securely prompts for a GitHub Personal Access Token (read:packages scope) for docker login (never stored in .env or VM metadata).
  • Mounts /opt/scout/data on the host to /app/data in the container (keeping your SQLite database and media persistent across restarts) and /opt/scout/goose for Goose session continuity.
  • Provisions automatic Let’s Encrypt HTTPS via Caddy (https://<YOUR-IP>.sslip.io by default).
  • Outputs your live HTTPS URL and one-time owner activation link. (Channels like Telegram and Email can be connected directly from the web setup wizard).

By default, the script sets up an instant HTTPS URL using https://<YOUR-IP>.sslip.io. To use your own domain (e.g. agent.example.com):

  1. Find your VM’s external IP address (shown at the end of deploy or via ./deploy/deploy-vm.sh status).
  2. Add a DNS A Record at your domain registrar (Cloudflare, Namecheap, Route 53, Google Cloud DNS, etc.):
    • Type: A
    • Host / Name: agent (or @ for root domain)
    • Target / IP: <YOUR_VM_EXTERNAL_IP>
    • TTL: Auto / 300s
  3. Provide your domain during deployment (--domain agent.example.com) or update an existing deployment anytime:
    Terminal window
    ./deploy/deploy-vm.sh set-domain agent.example.com

Caddy automatically provisions and renews trusted Let’s Encrypt SSL/TLS certificates.


Deployment Options, Version Pinning & Upgrades

Section titled “Deployment Options, Version Pinning & Upgrades”

To deploy a specific immutable release tag from GitHub Container Registry instead of latest:

Terminal window
./deploy/deploy-vm.sh --image ghcr.io/kcthota/scout:v0.1.0

If you have modified the source code locally and want Google Cloud Build to build your container image instead of pulling the pre-built GHCR image:

Terminal window
./deploy/deploy-vm.sh --use-cloud-build

To upgrade an existing VM deployment to the latest release (or a pinned --image), take an automatic pre-upgrade database backup, run Alembic migrations, and reload services:

Terminal window
./deploy/deploy-vm.sh upgrade

During upgrade:

  1. Automatic Pre-Upgrade Snapshot: Safely creates /opt/scout/data/backup_pre_upgrade.db before applying updates (using sqlite3 on the VM or Python’s online-backup API inside the running container). If a database exists and no snapshot can be taken, the upgrade aborts before changing anything.
  2. Alembic Database Migration: Automatically migrates the database schema up to head.
  3. Provider Keys: Any --openai-api-key, --anthropic-api-key, --openrouter-api-key, --xai-api-key, or --ollama-host flags passed to upgrade are added or updated in /opt/scout/.env. Existing keys you omit are preserved.
  4. Caddy Validation: Validates the Caddyfile with the Caddy container before applying it so a broken config never takes down HTTPS.

You can run deploy non-interactively by passing flags:

Terminal window
./deploy/deploy-vm.sh deploy \
--google-api-key "AIzaSy..." \
--domain "agent.example.com" \
--machine-type "e2-micro" \
--zone "us-central1-a"
Flag Default Description
--google-api-key <key> (or --gemini-api-key) (Prompted) Google Gemini API Key (always required for embeddings, compaction, and transcription)
--openai-api-key <key> (Optional prompt) OpenAI API Key
--anthropic-api-key <key> (Optional prompt) Anthropic API Key
--openrouter-api-key <key> (Optional prompt) OpenRouter API Key
--xai-api-key <key> (Optional prompt) xAI API Key
--ollama-host <url> (Optional prompt) Ollama server URL
--image <image> ghcr.io/kcthota/scout:latest Container image to pull and run
--use-cloud-build false Build image from source via Google Cloud Build instead of pulling from GHCR
--machine-type <type> (or --sku) e2-micro Compute Engine machine type (e2-micro, e2-small, e2-medium)
--domain <domain> <IP>.sslip.io Custom domain name (e.g. agent.example.com)
--zone <zone> us-central1-a GCP Zone (us-central1, us-east1, or us-west1 for Always Free)
--instance-name <name> scout Compute Engine VM instance name
--skip-build false Skip rebuilding/pulling image and reuse existing container
--dry-run false Preview operations without creating resources

Terminal window
# Check VM status, external IP, container health, disk usage, and memory/swap
./deploy/deploy-vm.sh status
# Stream live logs from Caddy, FastAPI, and the background worker
./deploy/deploy-vm.sh logs
# Update or set custom domain and reload Caddy HTTPS
./deploy/deploy-vm.sh set-domain agent.example.com
# Take a safe online SQLite backup and download scout_backup_<timestamp>.db locally
./deploy/deploy-vm.sh backup
# Restore SQLite database from a local backup file
./deploy/deploy-vm.sh restore path/to/backup.db
# SSH directly into the VM
./deploy/deploy-vm.sh ssh
# Permanently delete the VM instance and boot disk (prompts for confirmation)
./deploy/deploy-vm.sh teardown

To inspect which release version a live instance is running, open https://<your-domain>/stats (no login required):

{
"version": "v1.4.0",
"commit": "b55c8b8...",
"build_time": "2026-10-05T03:00:00.000Z",
"started_at": "2026-10-05T03:05:12+00:00"
}