Machines on Google Cloud
Caravel deploys a lane onto machines; it doesn't make them. The repository ships infrastructure as code for that part, written for OpenTofu, under infra/opentofu/. You describe the machine there and the lane in its lane file. The machine's outputs become the lane file's vars.
| Layer | Tool | Owns |
|---|---|---|
| Machines | OpenTofu | VM, static address, firewall, Docker, budget |
| Containers | Docker | how each node runs (runtime = "docker") |
| Lane | caravel | contracts on Stellar, keys, signers, node configs, releases |
What's there
modules/caravel-host-gcp: one VM (Ubuntu 24.04, e2-small by default) with a static address, ports 80 and 443 open to the web, and ssh only through IAP. Its startup script installs Docker and the Compose plugin at pinned versions, makes/opt/caravelfor the containers' user and adds swap.modules/billing-cap: a monthly budget with alerts, and a function that detaches billing from the project when the budget runs out, which stops everything in it. Budget alerts lag real costs, so treat it as a backstop, not an exact limit.envs/caravel-testnet: lane #1's project. Copy it as the start of your own.
A new project
You need OpenTofu 1.13, the gcloud CLI, logged in with gcloud auth application-default login, and a project with billing.
-
Copy
envs/caravel-testnettoenvs/<yours>. Set the project, its number, the billing account and the zone inmain.tf, and the state bucket's name inversions.tf. Deleteimports.tf, which adopts lane #1's existing resources, and the module arguments that keep lane #1's old names (address_name,web_rule_name,ssh_rule_name,ssh_rule_on_tag,install_docker,existing_source). Givebilling_capasource_bucketto upload the function's code to. -
Make the state bucket once:
PROJECT=<project> BUCKET=<bucket> ./infra/opentofu/bootstrap-state.sh -
Plan, read it, apply:
tofu -chdir=infra/opentofu/envs/<yours> inittofu -chdir=infra/opentofu/envs/<yours> plan -out machines.plantofu -chdir=infra/opentofu/envs/<yours> apply machines.plan
Hand the machine to the lane
The env's caravel_vars output is a vars file:
tofu -chdir=infra/opentofu/envs/<yours> output -raw caravel_vars > hosts.vars.toml
host_address = "caravel-1"
host_project = "caravel-testnet"
host_zone = "us-central1-a"
public_url = "https://35-224-76-64.sslip.io"
Declare those vars in the lane file and use them in the host (see Vars):
[env.testnet.host]
provider = "ssh"
transport = "gcloud-iap"
runtime = "docker"
address = "${var.host_address}"
project = "${var.host_project}"
zone = "${var.host_zone}"
public_url = "${var.public_url}"
Then deploy the lane as usual, with the file:
caravel plan lane.toml --env testnet --var-file hosts.vars.toml
caravel apply lane.toml --env testnet --var-file hosts.vars.toml
The public_url is the address's sslip.io name, so Caddy can get a certificate without any DNS to set up. Use your own domain by pointing it at the address and changing the var.
Changing the machine
- A bigger machine type is an in-place change: OpenTofu stops the VM, changes it and starts it again. The lane's stores live on the disk, so the nodes pick up where they stopped.
- The boot disk is never replaced from here, since a new disk would mean a new VM without the stores. A newer Ubuntu image is ignored once the VM exists. To grow the disk, resize it with
gcloud compute disks resize, then setdisk_gbto match. - Removing the env (
tofu destroy) deletes the VM and its disk, stores included. Wind the lane down first (Wind a lane down). The state bucket can't be destroyed from the plan.