deployer/docs/basics.md
2021-11-03 15:54:01 +01:00

246 lines
5.5 KiB
Markdown

# Basics
Deployer has two main concepts: [**hosts**](hosts.md) and [**tasks**](tasks.md).
A **recipe** is a file containing definitions for **hosts** and **tasks**.
Deployer CLI requires two arguments to run: a **task** to run and a **host**
or group of **hosts**.
```
$ dep deploy deployer.org
--- ------ ------------
| | |
| | `--- The host
| `------------- The task
`------------------ The CLI
```
Then Deployer takes the given task, performs some preparation (described later),
and executes the task on all specified hosts.
:::info
The `dep` CLI looks for `deploy.php` or `deploy.yaml` file in current directory.
Or recipe can be specified explicitly via `-f` or `--file` option.
```bash
$ dep --file=deploy.php deploy deployer.org
```
:::
Let's write a recipe.
```php
<?php
// We are going to use functions declared primarily in Deployer namespace,
// to simplify recipe we will use Deployer namespace too. Alternativly,
// you can import individual functions via "use function".
namespace Deployer;
host('deployer.org');
task('my_task', function () {
run('whoami');
});
```
Let's try to run our task on deployer.org.
```
$ dep my_task
task my_task
$
```
:::tip
If no host provided, Deployer will show an interactive prompt for selecting hosts.
If your recipe contains only one host, Deployer will automatically choose it.
To select all hosts specify `all`.
:::
But there is our `whoami` command? By default, Deployer runs with normal verbosity
level and shows only names of executed tasks. Let's increase verbosity to verbose, and
rerun our task.
:::note The dep CLI options
Add `-v` option to increase verbosity. Read more about [CLI usage](cli.md).
:::
```
$ dep my_task -v
task my_task
[deployer.org] run whoami
[deployer.org] deployer
$
```
Now let's add second host:
```php
host('deployer.org');
host('medv.io');
```
:::info Connection options
How Deployer knows hot to connect to a host? It uses same `~/.ssh/config` file as
the `ssh` command. Or you can specify [connection options](hosts.md) in recipe.
:::
Let's run `my_task` task on both hosts:
```
$ dep my_task -v all
task my_task
[deployer.org] run whoami
[medv.io] run whoami
[medv.io] anton
[deployer.org] deployer
```
Deployer runs a task in parallel on each host. This is why output mixed. We can
limit it to run only one host.
```
$ dep my_task -v all --limit 1
task my_task
[deployer.org] run whoami
[deployer.org] deployer
[medv.io] run whoami
[medv.io] deployer
```
Limit level also possible to [specified per task](tasks.md).
Each host has a configuration: a list of key-value pairs. Let's define our first
configuration option for both our hosts:
```php
host('deployer.org')
->set('my_config', 'foo');
host('medv.io')
->set('my_config', 'bar');
```
In the task we can get current executing host with [currentHost](api.md#currenthost) function:
```php
task('my_task', function () {
$myConfig = currentHost()->get('my_config');
writeln("my_config: " . $myConfig);
});
```
Or with [get](api.md#get) function:
```diff
task('my_task', function () {
- $myConfig = currentHost()->get('my_config');
+ $myConfig = get('my_config');
writeln("my_config: " . $myConfig);
});
```
Or via [parse](api.md#parse) function which replaces brackets `{{ ... }}` and value
with of config option.
:::tip
All functions (writeln, run, runLocally, cd, upload, etc) call **parse** function
internally. So you don't need to call **parse** function by your self.
:::
```diff
task('my_task', function () {
- $myConfig = get('my_config');
- writeln("my_config: " . $myConfig);
+ writeln("my_config: {{my_config}}");
});
```
Let's try to run our task:
```
$ dep my_task all
task my_task
[deployer.org] my_config: foo
[medv.io] my_config: bar
```
Awesome! Each host configuration inherits global configuration. Let's refactor
our recipe to define one global config option:
```php
set('my_config', 'global');
host('deployer.org');
host('medv.io');
```
The config option `my_config` will be equal to `global` on both hosts.
Also, config option value can be specified as a callback, such callback
executed on first access and returned result saved in host configuration.
```php
set('whoami', function () {
return run('whoami');
});
task('my_task', function () {
writeln('Who am I? {{whoami}}');
});
```
Let's try to run it:
```
$ dep my_task all
task my_task
[deployer.org] Who am I? deployer
[medv.io] Who am I? anton
```
This was we can create dynamic configuration which uses current host information.
Only first call triggers callback execution. All consequential use saved value.
Here is an example:
```php
set('current_date', function () {
return run('date');
});
task('my_task', function () {
writeln('What time is it? {{current_date}}');
run('sleep 5');
writeln('What time is it? {{current_date}}');
});
```
If we run my_task we will see what `date` is called only once on `{{current_date}}`
access.
```
$ dep my_task deployer.org -v
task my_task
[deployer.org] run date
[deployer.org] Wed 03 Nov 2021 01:16:53 PM UTC
[deployer.org] What time is it? Wed 03 Nov 2021 01:16:53 PM UTC
[deployer.org] run sleep 5
[deployer.org] What time is it? Wed 03 Nov 2021 01:16:53 PM UTC
```
We can override config option via CLI option `-o` like this:
```
$ dep my_task deployer.org -v -o current_date="I don't know"
task my_task
[deployer.org] What time is it? I don't know
[deployer.org] run sleep 5
[deployer.org] What time is it? I don't know
```
With overridden config option `current_date` there is no need to call the callback.
So there is no 'run date'.