---
title: "One-off jobs and migrations"
description: "Run a database migration or seed once with a service's image, variables and secrets; run it automatically before every pipeline deploy."
url: https://www.gyrohosting.com/developers/en/howto/container-job.html
language: en
openapi: https://www.gyrohosting.com/developers/openapi.json
api_version: 2.34.0
---

# One-off jobs and migrations

Run a database migration or seed once with a service's image, variables and secrets; run it automatically before every pipeline deploy.

**curl**

```bash
curl -s -X POST https://www.gyrohosting.com/api/v1/client/cloud/containers/12345/services/api/run \
  -H "Authorization: Bearer $GYRO_TOKEN" -H "Content-Type: application/json" -H "Idempotency-Key: $(uuidgen)" \
  -d '{"command":["npm","run","migrate"],"timeout_seconds":900}'
curl -s https://www.gyrohosting.com/api/v1/client/cloud/containers/12345/jobs/jt0abc12def3/logs -H "Authorization: Bearer $GYRO_TOKEN"
```

**CLI**

```bash
gyro container run 12345 --service api --follow -- npm run migrate
gyro container jobs 12345
gyro container job logs 12345 jt0abc12def3
```

The job uses the image of the service's **running version pinned by digest**, its variables and secrets (secret values are masked as `****` in the output). The command replaces the image ENTRYPOINT and is a list: no shell is involved unless you write `["sh","-c","a && b"]`. No ports, no health checks; a failed job is not retried. Default size = the service's, time limit 30 minutes (10 s - 6 h). The CLI with `--wait` / `--follow` exits with the job's exit code (124 = time limit).


## Before every deploy (Gyro Pipeline)

**YAML**

```
# gyro-pipeline.yml
image: api
deploy:
  services: [api]
  release: ["npm", "run", "migrate"]   # runs with the NEW image, before the rollout
```

The run waits in state `releasing`; when the job fails nothing is deployed and the running version stays (run error `release_failed`). Parallel jobs per environment: 2 on Serverless and plans up to 2 vCPU, 3 otherwise (raised with a support ticket). Free on node plans; on Serverless the job is billed per vCPU-second / GB-second like a task (line `<service>-job`). A failed job triggers the `job_failed` alert.
