---
title: Deploy Hooks
url: "/docs/apps/deploy-hooks/"
canonical_url: https://docs.blossom88.com/docs/apps/deploy-hooks/
markdown_url: https://docs.blossom88.com/docs/apps/deploy-hooks.md
summary: Run a command before each release goes live, or after it does
categories:
- deployment
- configuration
---

# Deploy Hooks

Deploy hooks run your commands at two points in every deploy:

| Hook | Runs | Typical use | If it fails |
|---|---|---|---|
| **Release Phase** | After the build, before the new version takes traffic | Database migrations | The deploy stops; the current version keeps serving |
| **Post Deploy** | After the new version is live | Notifications, cache warming | The deploy still succeeds |

## Set Them Up

Turn them on in the Environment's **Deploy Hooks** settings, or from the CLI:

    blossom environment:deploy_hooks:init

deploy_hooks.yml:

```yaml
deploy_hooks:
  release_phase:
    enabled: true
    command: bin/rails db:migrate
    # timeout_seconds: 900 # 1 through 3600
  # post_deploy:
  #   enabled: false
  #   command:
```

    blossom environment:deploy_hooks:update --id environment-100 --data deploy_hooks.yml

Hooks run with your App's image and variables. Common Release Phase commands:

    bin/rails db:migrate
    python manage.py migrate
    npm run migrate

## Release Phase

The release command has 15 minutes by default, up to an hour with
`timeout_seconds`. Its output is part of the deploy's log.

To stop a release that's taking too long, cancel it:

    blossom release:cancel --id release-100

The current version keeps serving either way. Cancelling stops the command
but doesn't undo what it already changed, so make migrations safe to run
again.

See [Jobs](/docs/apps/jobs/) for commands that run on a schedule
or once, outside a deploy.
