# 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 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'.