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-upload | Server | Before files from uploads entries are copied to the server |
post-upload | Server | After files are uploaded, before stack deployment |
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.
Local hooks run through bash. On Windows, dockflow automatically uses Git Bash when installed (the System32 WSL bash.exe stub is never used) — install Git for Windows to run local hooks.
File-based hooks
Create shell scripts in .dockflow/hooks/:
- pre-build.sh
- post-build.sh
- pre-upload.sh
- post-upload.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-upload: Stop a service before files arrive
# .dockflow/hooks/pre-upload.sh
#!/bin/bash
systemctl stop myapp || truePost-upload: Run a migration on uploaded files
# .dockflow/hooks/post-upload.sh
#!/bin/bash
cd /var/www/myapp && php artisan migrate --forcePre-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-upload | string | string[] | Inline command(s) to run on the server before files are uploaded | — |
post-upload | string | string[] | Inline command(s) to run on the server after files are uploaded | — |
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.