Rapids Runs
Preview: Rapids runs are an early-access feature, available to select accounts while the API is reviewed. The shape described here may still change before general availability.
A run executes your Rapids container's image once, on demand — the same image and environment your container serves traffic from, but started as a single job instead of a scaled service. This is the right tool for one-off work that shouldn't run as part of normal request traffic: database migrations, one-time backfills, cache warm-ups, or a maintenance script bundled into your image.
Runs are separate from your container's normal scaling. Starting a run does not scale your container up or down, and a run in progress does not affect the replicas serving live traffic.
Why not just scale the container?
Scaling a container's replicas to run a one-off script — for example to apply a database migration before a deploy — runs into a mismatch: scaling creates a Knative revision, and a revision's startup work can run more than once (Knative may start additional replicas of the same revision under load, or retry a replica that failed to become ready). A migration that isn't safe to run twice concurrently should not be triggered this way.
A run avoids this: it executes your image exactly once, as a single Kubernetes Job, with no autoscaling and no retries.
Starting a run
curl -X POST https://api.danubedata.ro/api/v1/serverless/{container_id}/runs \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"command": ["php", "artisan", "migrate", "--force"],
"timeout_seconds": 900
}'
All fields are optional:
| Field | Type | Description |
|---|---|---|
command | string[] | Overrides the image's entrypoint for this run. 1–32 items, each up to 4096 characters. Omit it to run the image's own default startup command. |
image_tag | string | Run a different tag of your container's own image repository for this run only — e.g. to run a migration from a specific build. The repository itself can never be changed by a run. |
env | object | Extra environment variables for this run only, layered on top of (and overriding) your container's normal environment. Up to 50 keys, each UPPER_SNAKE_CASE-style ([A-Za-z_][A-Za-z0-9_]*). Values are never stored or returned — only the key names appear in the run object, so you can see what was overridden without the values being retrievable afterward. |
timeout_seconds | integer | How long the run may execute before it is stopped and marked timed out. 60–3600 (1 hour max). Defaults to 900 (15 minutes). |
A successful request returns 202 with the new run:
{
"success": true,
"data": {
"id": "0192f3b0-...",
"container_id": "0192f1a0-...",
"status": "queued",
"terminal": false,
"command": ["php", "artisan", "migrate", "--force"],
"image": "cr.danubedata.ro/acme/api:latest",
"env_keys": [],
"timeout_seconds": 900,
"exit_code": null,
"message": null,
"created_at": "2026-09-16T18:00:00+00:00",
"started_at": null,
"finished_at": null,
"duration_seconds": null
},
"error": null,
"meta": {}
}
Only one run at a time per container
A container can have at most one run queued or running at once. Starting a second run while one is already active returns 409:
{
"success": false,
"data": null,
"error": {
"code": "serverless.run_in_progress",
"message": "A run is already in progress for this container.",
"retryable": true
},
"meta": { "active_run_id": "0192f3b0-..." }
}
Wait for the active run to finish (or cancel it) before starting another.
Run status
| Status | Terminal | Meaning |
|---|---|---|
queued | No | Accepted; the Kubernetes Job is being created. |
running | No | The image is executing. |
succeeded | Yes | The image exited with status 0. |
failed | Yes | The image exited with a non-zero status, or the run could not be started. See message. |
cancelled | Yes | Stopped by a cancel request. |
timed_out | Yes | Still running when timeout_seconds elapsed. |
Poll GET /api/v1/serverless/{container_id}/runs/{run_id} until terminal is true.
Listing runs
curl https://api.danubedata.ro/api/v1/serverless/{container_id}/runs \
-H "Authorization: Bearer YOUR_API_TOKEN"
Returns runs newest first, 20 per page, with pagination in meta:
{
"success": true,
"data": [ { "id": "...", "status": "succeeded", "...": "..." } ],
"error": null,
"meta": { "current_page": 1, "per_page": 20, "total": 3 }
}
Reading logs
curl https://api.danubedata.ro/api/v1/serverless/{container_id}/runs/{run_id}/logs \
-H "Authorization: Bearer YOUR_API_TOKEN"
{
"success": true,
"data": {
"run_id": "0192f3b0-...",
"source": "live",
"logs": "Migrating: 2026_09_16_190000_create_..."
},
"error": null,
"meta": {}
}
source is live while the run is still active (read directly from its pod), stored once the run has finished (a tail is captured at completion), or none if no logs are available yet.
Cancelling a run
curl -X POST https://api.danubedata.ro/api/v1/serverless/{container_id}/runs/{run_id}/cancel \
-H "Authorization: Bearer YOUR_API_TOKEN"
Cancelling a queued or running run stops it immediately and marks it cancelled. Cancelling a run that has already finished returns 409 with error.code: "serverless.run_not_active".
Limits
- Timeout: 60–3600 seconds (1 hour), 900 by default.
- Command: up to 32 arguments, each up to 4096 characters.
- Environment overrides: up to 50 keys per run; values are not persisted or returned.
- Concurrency: one queued or running run per container.
- Resources: a run uses the same CPU and memory profile as your container's own replicas.
API abilities
| Endpoint | Ability |
|---|---|
GET /runs, GET /runs/{id} | serverless:read |
POST /runs, POST /runs/{id}/cancel | serverless:write |
GET /runs/{id}/logs | serverless:diagnostics |
Next steps
- Invoking Containers — how your container serves normal traffic
- Automation & Diagnostics — inspecting a container's live state
Questions? Contact support at support@danubedata.ro