Skip to content

Configuration

The controller reads one YAML config file and then overlays environment variable overrides.

Minimal poll-mode config

github:
  token: YOUR_GITHUB_PAT
  owner: YOUR_GITHUB_OWNER
  repository: YOUR_REPOSITORY

jeballto:
  base_url: http://127.0.0.1:8011/v1

controller:
  mode: poll
  poll_interval: 10s
  webhook_listen: :9090

labels:
  jeballto-macos:
    image: ghcr.io/jeballto/macos-ci:latest
    lifetime_seconds: 3600

GitHub authentication

GitHub App

Recommended for production:

github:
  app_id: 12345
  app_private_key_path: /path/to/private-key.pem
  installation_id: 67890

Personal Access Token

Useful for development or the first test:

github:
  token: ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

PAT scope guidance:

  • repo-level runners: repo or equivalent fine-grained permissions
  • org-level runners: admin:org or equivalent fine-grained permissions

Jeballto section

jeballto:
  base_url: http://127.0.0.1:8011/v1
  # token: your-token
  # token_file: ~/Library/Application Support/Jeballto/config.json

If the controller runs on the same host as the Jeballto Agent, token auto-discovery is usually enough.

127.0.0.1 is the controller default for same-host deployments. The Jeballto Agent itself binds to 0.0.0.0:8011 by default unless api.host is changed.

Controller settings

controller:
  mode: poll
  poll_interval: 10s
  webhook_listen: :9090
  max_concurrent_vms: 2
  vm_idle_timeout: 5m
  gc_interval: 60s
  vm_name_prefix: gh

Set max_concurrent_vms to the current host limit. Today that is two VM slots, and both RUNNING and PAUSED VMs consume a slot.

Runner settings

runner:
  ssh_user: admin
  ssh_password: admin
  install_path: /Users/admin/actions-runner
  connect_timeout: 20s

The image must contain the runner binaries at install_path.

Labels map jobs to VM specs

labels:
  jeballto-macos:
    image: ghcr.io/your-org/macos-ci:latest
  jeballto-xcode26:
    image: ghcr.io/your-org/macos-ci:xcode-26
    cpu: 6
    memory: 12GB
    disk: 256GB
    lifetime_seconds: 7200

Jobs only provision if their runs-on label matches one of these entries.

lifetime_seconds is optional. 0 or omitted means no VM lifetime limit. Positive values are passed to Jeballto as lifetimeSeconds and must be between 1 and 604800 seconds.

Use lifetime as a CI/CD safety guard. Set it slightly higher than the GitHub job timeout because the VM still needs time to boot, register the runner, and start the job after creation. Image pull happens before VM creation, so it does not need to be included in this buffer. For example, if jobs can run for 60 minutes, use a VM lifetime such as 3900 or 4200 seconds.

CPU, memory, disk, and lifetime are selected by the matched label. Omitted CPU, memory, or disk values keep the image defaults. Workflow env: variables do not change VM sizing. To provide small, medium, and large machines, define separate labels and use the desired label in runs-on.

When a label sets custom CPU, memory, or disk together with an image, the controller creates the VM from the image first and then applies resource overrides with PATCH /v1/vms/{id} before start. The Jeballto API does not accept image and resources together on create.

Timeouts and retry

timeouts:
  prepare: 150m
  image_pull: 120m
  image_pull_lock: 130m
  state_wait: 10m
  ssh_wait: 5m
  stop: 2m
  delete: 2m
  runner_verify: 90s
  toolchain_probe: 90s

retry:
  max_attempts: 6
  initial_backoff: 1s
  max_backoff: 20s

Environment variable overrides

Variable Config path
GITHUB_APP_ID github.app_id
GITHUB_APP_PRIVATE_KEY_PATH github.app_private_key_path
GITHUB_INSTALLATION_ID github.installation_id
GITHUB_TOKEN github.token
GITHUB_WEBHOOK_SECRET github.webhook_secret
GITHUB_OWNER github.owner
GITHUB_REPOSITORY github.repository
JEBALLTO_BASE_URL jeballto.base_url
JEBALLTO_TOKEN jeballto.token
JEBALLTO_TOKEN_FILE jeballto.token_file

Mode-specific rules

  • poll requires github.repository
  • webhook requires github.webhook_secret
  • both requires both repository polling support and a webhook secret

The controller rejects invalid combinations during config loading.