Hooks
Hooks allow you to run custom scripts at specific points during deployment.
Available hooks
| Hook | Location | Timing |
|---|---|---|
pre-build | Local (CI runner) | Before Docker images are built |
post-build | Local (CI runner) | After Docker images are built |
pre-deploy | Server | After file uploads, before stack deployment |
post-deploy | Server | After successful deployment and health checks |
When remote_build: true is set, pre-build and post-build hooks run on the server instead of locally — where the build is actually happening.
File-based hooks
Create shell scripts in .dockflow/hooks/:
- pre-build.sh
- post-build.sh
- pre-deploy.sh
- post-deploy.sh
All hooks are optional. If a hook file doesn’t exist, it is skipped.
Inline hooks
For simple commands, define them directly in .dockflow/config.yml instead of creating a separate script:
# .dockflow/config.yml
hooks:
post-deploy: systemctl reload nginx
pre-build:
- echo "Building {{ config.project_name }} {{ version }}"
- docker pull base-image:latestWhen both a file and inline commands are defined for the same phase, the file runs first, then the inline commands.
Templating
Hooks are rendered with Nunjucks before execution. You can use any template variable:
#!/bin/bash
echo "Deploying {{ config.project_name }} version {{ version }} to {{ env }}"
# Access server environment variables
DATABASE_URL="{{ current.env.database_url }}"Examples
Pre-build: Generate assets
# .dockflow/hooks/pre-build.sh
#!/bin/bash
npm run build:assetsPost-build: Security scan
# .dockflow/hooks/post-build.sh
#!/bin/bash
docker scan {{ project_name }}:{{ version }} || truePre-deploy: Database backup
# .dockflow/hooks/pre-deploy.sh
#!/bin/bash
pg_dump $DATABASE_URL > /backups/pre-deploy-{{ version }}.sqlPost-deploy: Reload a systemd service
# .dockflow/config.yml
hooks:
post-deploy:
- systemctl daemon-reload
- systemctl restart rclone-s3.servicePost-deploy: Notify team
# .dockflow/hooks/post-deploy.sh
#!/bin/bash
curl -X POST "https://hooks.slack.com/services/xxx" \
-H "Content-Type: application/json" \
-d '{"text":"Deployed {{ project_name }} {{ version }} to {{ env }}"}'Configuration
# .dockflow/config.yml
hooks:
enabled: true # Enable/disable all hooks (default: true)
timeout: 300 # Timeout per hook in seconds (default: 300)
fatal: false # Abort deploy on hook failure (default: false)
pre-build: echo "starting build"
post-deploy:
- systemctl daemon-reload
- systemctl restart myservice| Field | Type | Description | Default |
|---|---|---|---|
enabled | boolean | Enable or disable all hooks | true |
timeout | number | Max execution time per hook, in seconds | 300 |
fatal | boolean | Abort the deploy when a hook exits with a non-zero code | false |
pre-build | string | string[] | Inline command(s) for the pre-build phase | — |
post-build | string | string[] | Inline command(s) for the post-build phase | — |
pre-deploy | string | string[] | Inline command(s) for the pre-deploy phase | — |
post-deploy | string | string[] | Inline command(s) for the post-deploy phase | — |
By default, hook failures print a warning and let the deploy continue. Set fatal: true to treat a non-zero exit code as a deploy error — useful for hooks that run critical operations like database migrations.
With fatal: false (the default), a failing hook does not abort the deploy. If your hook runs a critical operation (e.g. a migration), set fatal: true.