Documentation

Configuration

Delivery Boy keeps the release contract in .deliver.yml at the root of your repository.

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

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.