Skip to content

Run code with cloud-init

Cloud-init is how you run code on a server without logging in. You hand the instance a cloud-config document, and it runs that document the first time the machine boots: updating packages, installing software, writing files, and running commands. This is the direct way to make a new server arrive already configured.

How it works

You pass a cloud-config YAML string when you create the instance, in the cloud_init field on POST /v1/workspaces/{wid}/instances. On first boot, the instance reads that config and carries out each section. Because it runs on first boot, the reliable time to set it is at create time.

Set it at create time

Include cloud_init in the create request alongside the required fields. The value is the full cloud-config document as a single string:

bash
curl -X POST "https://api.galaxygate.net/v1/workspaces/$WORKSPACE_ID/instances" \
  -H "Authorization: Bearer $GALAXYGATE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "web-01",
    "specs": { "plan": 12, "cpu": 2, "memory": 4096, "storage": 80000 },
    "ipv4": { "enabled": true },
    "ipv6": { "enabled": true },
    "start": true,
    "cloud_init": "#cloud-config\npackage_update: true\npackages:\n  - nginx\nwrite_files:\n  - path: /var/www/html/index.html\n    content: |\n      Hello from cloud-init\nruncmd:\n  - systemctl enable --now nginx\n"
  }'

A cloud-config example

The cloud_init string above is JSON-escaped so it fits on one line. This is the same document, written out as readable YAML. It updates the package index, installs nginx, writes a home page, and starts the service:

yaml
#cloud-config
package_update: true
packages:
  - nginx
write_files:
  - path: /var/www/html/index.html
    content: |
      Hello from cloud-init
runcmd:
  - systemctl enable --now nginx

The first line must be exactly #cloud-config. From there:

  • package_update refreshes the package index before anything installs.
  • packages lists software to install. Here it is a single package, nginx.
  • write_files writes files to disk. This one drops a home page for nginx to serve.
  • runcmd runs shell commands in order, near the end of first boot. This one enables and starts the nginx service.

To feed this into the API, collapse it into a single JSON string with escaped newlines, as shown in the create request above.

Update cloud-init later

You can replace an instance's cloud-init after it exists:

POST /v1/instances/{id}/cloud-init
bash
curl -X POST "https://api.galaxygate.net/v1/instances/$INSTANCE_ID/cloud-init" \
  -H "Authorization: Bearer $GALAXYGATE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "cloud_init": "#cloud-config\npackages:\n  - htop\n" }'

Cloud-init runs on first boot

Updating the config on a running instance does not re-run it on the spot. Cloud-config sections like packages and runcmd are applied on first boot. A stored config takes effect on the next fresh boot of the machine, such as after a reinstall. To have code run right away on a brand new server, pass cloud_init in the create request instead.

Next step

Head back to Create a server to send cloud_init in your first provisioning call.