deployer/docs/selector.md
Joda Stößer 3cb4b1e340
docs(selector): correct env config option to array (#3481)
As the `env` config options is expected to be an array, not a string, the supplied example is throwing errors.
This syntax checking of the `env` variable seems to only happen in the YAML config syntax, not with the php config.
2023-02-06 20:34:12 +01:00

4.1 KiB

Selector

Deployer uses the selector to choose hosts. Each host can have a set of labels. Labels are key-value pairs.

For example, stage: production or role: web.

You can use labels to select hosts. For example, dep deploy stage=production will deploy to all hosts with stage: production label.

Let's define two labels type and env of our hosts:

host('web.example.com')
    ->setLabels([
        'type' => 'web',
        'env' => 'prod',
    ]);

host('db.example.com')
    ->setLabels([
        'type' => 'db',
        'env' => 'prod',
    ]);

Now let's define a task to check labels:

task('info', function () {
    writeln('type:' . get('labels')['type'] . ' env:' . get('labels')['env']);
});

Now we can run this task on with a selector:

$ dep info env=prod
task info
[web.example.com] type:web env:prod
[db.example.com] type:db env:prod

As you can see, Deployer will run this task on all hosts with env: prod label. And if we define only type label, Deployer will run this task on specified host.

dep info type=web
task info
[web.example.com] type:web env:prod

Selector syntax

Label syntax is represented by disjunctive normal form (OR of ANDs).

For example, type=web,env=prod is a selector of: type=web OR env=prod.

$ dep info 'type=web,env=prod'
task info
[web.example.com] type:web env:prod
[db.example.com] type:db env:prod

As you can see both hosts are selected (as both of them has env: prod label).

We can use & to define AND. For example, type=web & env=prod is a selector for hosts with type: web AND env: prod labels.

$ dep info 'type=web & env=prod'
task info
[web.example.com] type:web env:prod

We can also use != to negate a label. For example, type!=web is a selector for all hosts what has not type: web label.

$ dep info 'type!=web'
task info
[db.example.com] type:db env:prod

:::note Deployer CLI can take a few selectors as arguments. For example, dep info type=web env=prod is a same as dep info 'type=web,env=prod'.

You can install bash autocompletion for Deployer CLI, which will help you to write selectors. See installation for more. :::

Deployer also has a few special selectors:

  • all - select all hosts
  • alias=... - select host by alias

If a selector does not contain = sign, Deployer will assume that it is an alias.

For example dep info web.example.com is a same as dep info alias=web.example.com.

$ dep info web.example.com
task info
[web.example.com] type:web env:prod
$ dep info 'web.example.com' 'db.example.com'
$ # Same as: 
$ dep info 'alias=web.example.com,alias=db.example.com'

Using select() function

You can use select() function to select hosts by selector from PHP code.

task('info', function () {
    $hosts = select('type=web,env=prod');
    foreach ($hosts as $host) {
        writeln('type:' . $host->get('labels')['type'] . ' env:' . $host->get('labels')['env']);
    }
});

Or you can use on() function to run a task on selected hosts.

task('info', function () {
    on(select('all'), function () {
        writeln('type:' . get('labels')['type'] . ' env:' . get('labels')['env']);
    });
});

Task selectors

To restrict a task to run only on selected hosts, you can use select() method.

task('info', function () {
    // ...
})->select('type=web,env=prod');

Labels in YAML

You can also define labels in YAML recipe. For example:

hosts:
  web.example.com:
    remote_user: deployer
    env:
      environment: production
    labels:
      env: prod

But make sure to distinguish between env and labels.env keys. env is a configuration key, and labels.env is a label.

task('info', function () {
    writeln('env:' . get('env')['environment'] . ' labels.env:' . get('labels')['env']);
});

Will print:

$ dep info env=prod
task info
[web.example.com] env:production labels.env:prod