Skip to content

Run lifecycle hooks

View Markdown

Lifecycle hooks let a Component run one bounded command before or after a deployment. Use them for work that belongs to a specific application revision, such as applying database migrations or warming a cache.

They are deliberately not a general workflow engine. A Component has two ordered hook points:

release → deploy → ready → postDeploy

Use release when the new Component revision must not deploy unless a command succeeds:

resource: component
name: api
image: registry.deliberate.cloud/acme/api:1.8.0
env:
DATABASE_URL: "${{ postgres.url }}"
needs:
databases:
- postgres
release:
command: ["./api", "migrate"]
timeout: 10m

deliberate. runs the command before updating the Component. A non-zero exit or timeout fails the apply and leaves the currently deployed revision serving traffic. Run deliberate apply again after correcting the problem; the failed hook is retried and its logs appear in the apply output.

This is the appropriate hook for database migrations that must complete before new application code starts.

Use postDeploy for automation that needs the new revision to be available first:

resource: component
name: api
image: registry.deliberate.cloud/acme/api:1.8.0
postDeploy:
command: ["./api", "warm-cache"]
timeout: 5m

The platform deploys the Component, waits for it to become ready, and then runs the command. A failed postDeploy fails the apply, but the new Component is already deployed and may already be serving traffic. deliberate. does not roll it back or hide it from public routes.

Use readiness configuration or a private route when an application must not receive public traffic before some setup step. postDeploy is after availability; it is not a traffic gate.

Each hook runs as a separate, one-shot container:

  • It uses the Component’s image, environment variables, secret references, mounted configuration files, and resource configuration.
  • It runs in the same Environment and with the same workload isolation and network identity as the Component.
  • It does not run inside a serving replica and cannot reach that replica over localhost.
  • It does not share the serving replica’s processes or ephemeral filesystem.
  • Durable volumes declared in needs.volumes are not mounted into lifecycle hooks.

If a hook needs to contact the running application, address its internal service rather than localhost. Keep the necessary address in the Component’s declared environment configuration.

The command is an argument array, not a shell expression. Invoke a shell explicitly when shell syntax is required:

postDeploy:
command: ["sh", "-c", "./api warm-cache && ./api verify-cache"]

Hooks are not available on Components with schedule, because scheduled Components already run to completion.

A hook command must be idempotent: running it again should converge on the same result. A command may complete its external action immediately before the platform loses its completion result, so a retry can repeat the whole command.

Successful hook execution is remembered separately for each Environment, Component, phase, and hook identity. An unrelated apply does not run it again. A hook runs when it is introduced, when its meaningful declarative inputs change, or when its previous attempt did not succeed.

Meaningful inputs include the Component image, hook command, declared environment, dependency and secret bindings, and mounted file content or references. Changing only CPU, memory, timeout, or a stored secret value does not repeat a successful hook. If a hook intentionally needs to run for such an external change, change an explicit environment value or the hook command as part of the same revision.

timeout accepts a deliberate. duration such as 30s, 5m, or 10m.

  • Default: 10m
  • Minimum: 1s
  • Maximum: 30m

Timeouts and non-zero exits are reported with the hook’s logs in the streamed apply output.

Volume consistency.before and consistency.after commands surround a volume snapshot. They run inside the Component that mounts the volume so the application can flush, lock, and resume its data. They do not participate in the Component deployment sequence described here.

See Make snapshots application-consistent for that backup-specific contract.