A pre-deploy command runs after the new image is available and before Bex releases that revision. Use it for a finite task such as a database migration that must complete before the new application starts serving.
This step applies to web services, private services, and background workers. It does not apply to static sites or cron jobs. Configuring executable commands requires developer/admin permissions; permission to restart a service alone is not enough.
Configure the command
Add preDeployCommand to a Blueprint service declaration:
services:
- type: web
name: api
runtime: node
repo: https://github.com/acme/api
plan: starter
buildCommand: npm ci
preDeployCommand: npm run migrate
startCommand: npm start
healthCheckPath: /healthz
autoDeployTrigger: offThis assumes your application supplies the migration/start scripts, health endpoint, and required database configuration. Add a datastore reference or secret for the connection. Test the migration against disposable data before attaching it to a real deployment.
The API also supports updating the service's pre-deploy command; an empty string clears it. Treat a command change as a deployment-affecting configuration change, not just a label edit. For a Blueprint-managed service, update the manifest so a later sync does not restore the old command.
Execution environment and limits
Bex runs sh -c <command> in the new revision's image, in a separate job.
The image must contain sh and all tools the command uses. The command receives
the service's environment, secret files, image-pull credentials, and resource
limits; network access still follows the applicable policy.
The job does not mount the service's persistent disk. Files written to its local filesystem are not copied into the released service. Build required artifacts into the image, or write to an appropriate external store when that is the intended operation.
The current Bex job deadline is 10 minutes. A nonzero exit or deadline failure blocks the revision. Bex does not automatically retry the failed job, and a completed step is not rerun for the same revision. A new deployment can execute the command again, so make the operation safe to repeat and inspect partial changes after failure.
Observe the result
Follow the deployment and its predeploy logs. A successful command allows the
release to proceed; readiness and the application's own behavior still need to
succeed afterward. If the step fails, the previous revision can remain serving
when one exists. On a first deployment there is no previous release to serve.
Finished job pods are cleaned up; durable log availability depends on the configured logging backend. Capture useful diagnostics while investigating, without printing credentials.
Database migration discipline
The previous application may still use the database while the command runs. Prefer schema changes compatible with both old and new code during transition. Assign migration ownership deliberately when several services share a database; separate service deployments do not create a global migration lock.
A failed command may already have changed data. Before retrying, inspect the migration tool's state and decide whether to resume, repair, or restore from a verified backup. An image rollback does not undo a schema or data change. Long migrations that exceed the deadline need a separately planned procedure rather than a command that launches work in the background and exits.
For command-not-found failures, check the final image and working directory. For connection failures, check credentials, DNS, and network policy. For a timeout, measure the migration and split or redesign it before retrying. See how deploys work for the complete release sequence.
A runnable old/new application rehearsal for a compatible column rename lives in
the downloadable postgres-schema-rollout
sample and the guide Rehearse a Postgres schema change.