# Gyro Containers: one-off jobs and database migrations

https://www.gyrohosting.com/en/knowledgebase/article/gyro-containers-one-off-jobs

- **What you will learn**: how to run a command such as a database migration, seed or maintenance script **once** with your service's image, variables and secrets; how to follow its output live and how to run it automatically before every Gyro Pipeline deploy.
- **Time**: 5 minutes

## 1. How it works

- The job starts from the **image of the running version** of the service you pick. The image is pinned by digest: even if a tag such as `:latest` moves meanwhile, exactly the running version is used.
- The service's **variables and secrets** come along, so connection settings like `DATABASE_URL` need no second copy.
- The command replaces the image ENTRYPOINT and is sent as a **list**. For shell features (`&&`, `>`, `|`) write `sh -c "…"`. Without a command the image's own command runs.
- A job has no ports and no health checks and stops when done. **A failed job is not retried** (so a migration never runs twice).
- Default size = the service's; time limit 30 minutes (choose 10 seconds to 6 hours). When the time is up the job is stopped.
- The last 50 jobs are kept with their output (last 2,000 lines). Secret values of the service show as `****`.

## 2. From the panel

1. Open the **Jobs** tab of your service and press **Run job**.
2. Pick the **Service** (image, variables and secrets come from it).
3. Type the **Command**, e.g. `npm run migrate`, `php artisan migrate --force` or `python manage.py migrate`.
4. Change the **time limit**, **vCPU** and **memory** if needed, then press **Start**.
5. The state moves *Starting → Running → Succeeded / Failed*. **Output** shows the log live; **Stop** ends a running job.

## 3. CLI, API and AI assistants

```
# follow the output; the CLI exits with the job's exit code (124 = time limit reached)
gyro container run 12345 --service api --follow -- npm run migrate

# with shell features and a 10 minute limit
gyro container run 12345 --service web --wait --time-limit 10m -- sh -c "php artisan migrate --force && php artisan db:seed --force"

gyro container jobs 12345                       # recent jobs
gyro container job logs 12345 jt0abc12def3      # output of one job
```

API: `POST /cloud/containers/{id}/services/{service}/run` with `{"command": ["npm","run","migrate"], "timeout_seconds": 900}`; state `GET /cloud/containers/{id}/jobs/{job}`, output `.../logs`, stop `DELETE /cloud/containers/{id}/jobs/{job}`. Send an `Idempotency-Key` header to retry safely. Gyro MCP tools: `run_container_job`, `get_container_job`, `list_container_jobs`, `stop_container_job`.

## 4. Before every pipeline deploy

Add `release` to `gyro-pipeline.yml`:

```
image: api
deploy:
  services: [api]
  release: ["npm", "run", "migrate"]   # with the new image, before the deploy
```

After the build the job runs with the **new image** and the settings of the first target service; the run waits in state **Running release job** (`releasing`). With approval on, the job runs after the approval. When it succeeds the deploy starts; **when it fails nothing is deployed**, your running version stays and the run ends with error `release_failed`. The job's output is on the Jobs tab with the run number.

## 5. Limits and price

|  | Node plans | Serverless |
| --- | --- | --- |
| Jobs at the same time | 2 on plans up to 2 vCPU, 3 otherwise | 2 |
| Where it runs | On your own nodes, in the free capacity next to your services | On the shared sandboxed pool |
| Price | No extra charge | Like a task, per vCPU-second / GB-second; billing line `<service>-job` |

- Without free capacity the job is refused: reduce its vCPU/memory, stop a copy or upgrade the plan.
- The parallel job limit can be raised with a support ticket (`gyro limits` shows it).
- A failed or timed out job sends the **job_failed** notification (your email, SMS, Telegram and webhook channels on the Alerts tab).

## 6. FAQ

**Can a migration run twice?**

No. A failed job is never retried automatically; running it again is your decision.

**Which image is used?**

For a job started by hand, the service's running version (digest). If the service has no running copy the configured tag is used and the panel says "by tag". In the pipeline the newly built image is used.

**Can I use < , > , && in the command?**

Yes. The command arrives unchanged; for redirection and chaining write `sh -c "…"`.

**Does a job affect my service?**

Your service keeps running. The job is a separate container that only shares the same capacity.

**Are scheduled jobs (cron) available?**

Not yet; start a one-off job from your own scheduler with the CLI or API.
