Documentation
Configuration
Delivery Boy keeps the release contract in .deliver.yml at the root of your repository.
Treat this file as executable release code. Review changes to it with the same care as a shell script: deployers can run local commands, upload files, and run commands on remote hosts.
A small Hugo site
version: 1
app: example-site
defaults:
target: production
targets:
production:
hosts: [example.com]
dir: /var/www/example
ssh:
user: deploy
key: ~/.ssh/example.pem
services:
web:
deployer: hugo
config:
source: .
minify: true
remote_subdir: web
owner: www-data:www-data
verify:
- http:
url: https://example.com/
expect_status: 200
Targets
A target describes where a release goes. A target can name more than one host. SSH defaults to port 22 and supports a key or the running SSH agent.
targets:
production:
hosts: [app-1.example.com, app-2.example.com]
dir: /var/www/example
ssh:
user: deploy
port: 22
key: ~/.ssh/example.pem
Services and order
Each service uses one deployer. Use needs to order related services:
services:
web:
deployer: hugo
config: {source: apps/site, remote_subdir: web}
nginx:
deployer: nginx-vhost
needs: [web]
config:
conf: nginx/example.conf
Run only part of a release with --service:
deliver plan --service web
deliver deploy --service web
Secrets
Declare names in the config and resolve values from the environment, a gitignored file, the macOS Keychain, 1Password, or SOPS. Plans show names and hidden placeholders, never values.
secrets:
providers:
- env
- file: .env.deploy
- keychain: {prefix: "example-"}
define:
DATABASE_PASSWORD: {}
OPTIONAL_TOKEN: {required: false}
Check them without deploying:
deliver secrets
Keep secret values out of .deliver.yml. Use a provider and commit only the secret names. deliver plan --json also hides resolved values.
Checks
Checks run after activation. A failed check fails the release and rolls back reversible steps.
verify:
- remote_file: web/index.html
- contains:
remote_file: web/index.html
text: Example
- http:
url: https://example.com/health
expect_status: 200
retries: 5
interval: 5
Version rules
Projects can refuse releases from the wrong branch, a dirty tree, or a commit that does not match its upstream:
versioning:
require_clean: true
require_pushed: true
branch: main
tag:
enabled: true
name: "v{version}"
push: true
Tags are created only after the release and its checks succeed.
Use versioning.require_clean and versioning.require_pushed for production releases. They keep a local edit or an unpushed commit from becoming a release no one else can reproduce.