Configuration¶
GitLab Runner config.toml¶
Add the executor hooks to your runner configuration:
concurrent = 2
[[runners]]
name = "jeballto-custom"
url = "https://gitlab.example.com"
token = "REDACTED"
executor = "custom"
shell = "bash"
limit = 2
request_concurrency = 2
environment = [
"JEBALLTO_BASE_URL=http://127.0.0.1:8011/v1"
]
[runners.custom]
config_exec = "/usr/local/bin/jeballto-gitlab-executor"
config_args = ["config"]
prepare_exec = "/usr/local/bin/jeballto-gitlab-executor"
prepare_args = ["prepare"]
run_exec = "/usr/local/bin/jeballto-gitlab-executor"
run_args = ["run"]
cleanup_exec = "/usr/local/bin/jeballto-gitlab-executor"
cleanup_args = ["cleanup"]
config_exec_timeout = 60
prepare_exec_timeout = 9000
cleanup_exec_timeout = 300
The repo also contains the same sample in examples/config.toml.snippet.
Runner concurrency¶
One Jeballto host has two VM slots. GitLab Runner must enforce that at job pickup time:
- set top-level
concurrent = 2for a runner process dedicated to this host - set
limit = 2on the Jeballto[[runners]]entry - set
request_concurrency = 2so the runner asks for at most two jobs for that entry - run only one GitLab Runner service/process for the host, unless the total limits across all entries still add up to two
Executor capacity waiting is only a recovery path for races, stale VMs, or external VM usage. It cannot stop GitLab from assigning a job after GitLab Runner has already accepted it. If three or four jobs are shown as picked, inspect every active config.toml and every runner process. Common causes are duplicate runner entries using the same token, a system runner plus a user runner both running, or limit placed under [runners.custom] instead of directly under [[runners]].
Core environment variables¶
| Variable | Default | Purpose |
|---|---|---|
JEBALLTO_BASE_URL |
http://127.0.0.1:8011/v1 |
Jeballto API base URL |
JEBALLTO_TOKEN |
auto-detected | API bearer token |
JEBALLTO_TOKEN_FILE |
~/Library/Application Support/Jeballto/config.json |
Token file fallback |
JEBALLTO_DEFAULT_IMAGE |
unset | Default OCI image when jobs do not provide one |
The executor defaults to 127.0.0.1 because same-host deployments are the common case. The Jeballto Agent itself binds to 0.0.0.0:8011 by default unless api.host is changed.
VM sizing¶
Set sizing variables on the GitLab Runner host, for example in the runner config.toml environment = [...] array or in the service environment that launches gitlab-runner. Jobs may also set the same variables in .gitlab-ci.yml; GitLab exposes them to custom executor hooks as CUSTOM_ENV_JEBALLTO_*, and the executor reads both forms.
[[runners]]
name = "jeballto-macos"
executor = "custom"
environment = [
"JEBALLTO_VM_CPU_COUNT=6",
"JEBALLTO_VM_MEMORY_SIZE=12884901888",
"JEBALLTO_VM_DISK_SIZE=274877906944",
"JEBALLTO_VM_LIFETIME_SECONDS=7200"
]
Plain JEBALLTO_* values take precedence over CUSTOM_ENV_JEBALLTO_* values. That lets host configuration define hard defaults while still allowing job-level overrides when the host does not set a plain value.
| Variable | Default | Purpose |
|---|---|---|
JEBALLTO_VM_NAME_PREFIX |
gl |
Prefix for deterministic VM names |
JEBALLTO_VM_LIFETIME_SECONDS |
0 |
Max VM lifetime in seconds, 0 means no limit |
JEBALLTO_VM_CPU_COUNT |
0 |
Requested vCPU count, 0 keeps the image default |
JEBALLTO_VM_MEMORY_SIZE |
0 |
Requested memory in bytes, 0 keeps the image default |
JEBALLTO_VM_DISK_SIZE |
0 |
Requested disk size in bytes, 0 keeps the image default |
Resource values are only applied when they are greater than 0. A missing value or 0 sends no resource override, so the VM keeps the CPU, memory, and disk from the image. When an image is present and any resource override is greater than 0, resource updates happen after VM creation and before the VM starts because the Jeballto API does not accept image and resource overrides in the same create call.
JEBALLTO_VM_LIFETIME_SECONDS is passed to Jeballto as lifetimeSeconds. Positive values must be between 1 and 604800 seconds.
Use lifetime as a CI/CD safety guard. Set it slightly higher than the GitLab job timeout because the VM still needs time to boot, become reachable over SSH, 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.
SSH configuration¶
| Variable | Default | Purpose |
|---|---|---|
JEBALLTO_SSH_USER |
admin |
SSH username inside the VM |
JEBALLTO_VM_PASSWORD |
admin |
SSH password |
JEBALLTO_VM_PASSWORD_ENV |
JEBALLTO_VM_PASSWORD |
Env var name that stores the password |
JEBALLTO_SSH_CONNECT_TIMEOUT |
20s |
Per-connection timeout for OpenSSH |
Image policy¶
| Variable | Default | Purpose |
|---|---|---|
JEBALLTO_ALLOW_JOB_IMAGE_OVERRIDE |
true |
Allow image: in .gitlab-ci.yml |
JEBALLTO_IMAGE_ALLOWLIST |
unset | Comma-separated glob allowlist |
See Image Policy for the full resolution order.
Timeouts¶
| Variable | Default | Purpose |
|---|---|---|
JEBALLTO_PREPARE_TIMEOUT |
150m |
Full prepare budget, including image pull |
JEBALLTO_IMAGE_PULL_TIMEOUT |
120m |
Time to pull a missing image |
JEBALLTO_IMAGE_PULL_LOCK_TIMEOUT |
130m |
Time to wait for another job pulling the same image |
JEBALLTO_STATE_WAIT_TIMEOUT |
10m |
Time to wait for RUNNING |
JEBALLTO_SSH_WAIT_TIMEOUT |
5m |
Time to wait for SSH readiness |
JEBALLTO_PROBE_TIMEOUT |
90s |
Toolchain readiness probe |
JEBALLTO_STOP_TIMEOUT |
2m |
Stop timeout during cleanup |
JEBALLTO_DELETE_TIMEOUT |
2m |
Delete timeout during cleanup |
Retry and local state¶
| Variable | Default | Purpose |
|---|---|---|
JEBALLTO_RETRY_MAX_ATTEMPTS |
6 |
Retries for transient API failures |
JEBALLTO_RETRY_INITIAL_BACKOFF |
1s |
Initial retry delay |
JEBALLTO_RETRY_MAX_BACKOFF |
20s |
Backoff cap |
JEBALLTO_STATE_ROOT |
~/.cache/jeballto-gitlab-executor/jobs |
Job state and lock file root |
JEBALLTO_BUILDS_BASE_DIR |
/tmp/builds |
Build directory inside the VM |
JEBALLTO_CACHE_BASE_DIR |
/tmp/cache |
Cache directory inside the VM |
Recommended baseline¶
For a first host, start with:
- one default image
- positive
JEBALLTO_VM_LIFETIME_SECONDSslightly higher than your GitLab job timeout - job image overrides enabled only if you also define an allowlist
- default retry settings
- default timeouts
- explicit SSH credentials instead of relying on image defaults
Validation checklist¶
Before running the first real pipeline:
- confirm the Jeballto Agent health endpoint responds
- confirm the token is available either via env var or config file
- confirm the image exists or can be pulled by the agent
- confirm the VM image contains
bash,git, andgitlab-runner - confirm the GitLab Runner process can execute the hook binary