docs/UPGRADE.md
run() and runLocally() changesThe $options array parameter has been removed. Use named arguments instead.
# Before (v7):
run('command', ['timeout' => 5, 'no_throw' => true]);
# After (v8):
run('command', timeout: 5, nothrow: true);
Parameter renames:
no_throw → nothrowreal_time_output → forceOutputidle_timeout → idleTimeoutThe secret parameter has been replaced with secrets (an associative array of multiple named secrets):
# Before (v7):
run('echo %secret%', secret: getenv('MY_SECRET'));
# After (v8):
run('echo %my_secret%', secrets: ['my_secret' => getenv('MY_SECRET')]);
A new cwd parameter allows setting the working directory directly:
run('ls', cwd: '/var/www');
escapeshellarg() → quote()All uses of PHP's escapeshellarg() have been replaced with Deployer's own quote() function,
which uses ANSI-C $'...' quoting syntax for better shell compatibility:
# Before (v7):
run('echo ' . escapeshellarg($arg));
# After (v8):
run('echo ' . quote($arg));
You can also use the quote filter in config templates:
run('echo {{ message | quote }}');
To output literal {{ in commands without config replacement, escape with a backslash:
run('echo \{{not_replaced}}'); // outputs: {{not_replaced}}
Httpie changesHttpie::send() now returns an HttpResponse object instead of a string.
Use ->send()->body() to get the response body as a string.Httpie::getJson() is deprecated. Use sendJson() instead.Httpie methods no longer clone the object — they mutate and return $this.fetch() function now supports put, patch, and delete methods.deploy.maml recipe format is now supported alongside PHP and YAML recipes.local_archive strategy: A new update_code_strategy option that copies code from the local machine instead of fetching from a remote repository.composer_version config: Install a specific Composer version on the remote host:
set('composer_version', '2.7');
Host::setShellPath(): Customize the shell path per host.writable_acl_groups and writable_acl_force config options for deploy:writable.Change config hostname to alias.
Change config real_hostname to hostname.
Change config user to remote_user.
Update host() definitions:
set prefix to all setters: identityFile -> setIdentityFile or set('identity_file')host(...)->addSshOption('UserKnownHostsFile', '/dev/null') to host(...)->setSshArguments(['-o UserKnownHostsFile=/dev/null']);host('deployer.org')
->set('labels', ['stage' => 'prod']);
dep deploy prod use dep deploy stage=prod.alias() is deleted, host() itself sets alias and hostname, to override hostname use setHostname().Update task() definitions.
onRoles() with select():
task(...)
->select('stage=prod');
# from
task('deploy:npm-install', 'npm clean-install');
# to
task('deploy:npm-install', function() {
cd('{{release_path}}');
run('npm clean-install');
});
shallow() tasks options.Third party recipes now live inside main Deployer repo in contrib:
require 'contrib/rsync.php';
Replace inventory() with import(). It now can import hosts, configs, tasks:
import: recipe/common.php
config:
application: deployer
shared_dirs:
- uploads
- storage/logs/
- storage/db
shared_files:
- .env
- config/test.yaml
keep_releases: 3
http_user: false
hosts:
prod:
local: true
tasks:
deploy:
- deploy:prepare
- deploy:vendors
- deploy:publish
deploy:vendors:
- run: "cd {{release_path}} && echo {{bin/composer}} {{composer_options}} 2>&1"
Rename task success to deploy:success and cleanup to deploy:cleanup.
Verbosity functions (isDebug(), etc) got deleted. Use output()->isDebug() instead.
runLocally() commands are executed relative to the recipe file directory. This behaviour can be overridden via an environment variable:
DEPLOYER_ROOT=. vendor/bin/dep taskname
Replace local() tasks with combination of once() and runLocally() func.
Replace locateBinaryPath() with which() func.
Replace default_stage with default_selector, and adjust the value accordingly (for example: "prod" to "stage=prod").
Replace onHosts() and onStage() with labels & selectors.
Replace setPrivate() with hidden().
Configuration property writable_recursive defaults to false. This behaviour can be overridden with:
set('writable_recursive', true);
.git directory is not present in release directory anymore. The previous behavior can be restored with:set('update_code_strategy', 'clone');
Since the release history numbering is not compatible between v6 and v7, you need to specify the release_name manually for the first time. Otherwise you start with release 1.
ls releases dir, find the biggest number). Example: 42.dep deploy -o release_name=43
:::note
In case a rollback is needed, manually change the current symlink:
ln -nfs releases/42 current
:::
:::note
In case there are multiple hosts with different release names, you should create a {{deploy_path}}/.dep/latest_release file in each host with the current release number of that particular host.
:::
Changed branch option priority
If you have host definition with branch(...) parameter, adding --branch option will not override it any more.
If no branch(...) parameter persists, branch will be fetched from current local git branch.
host('prod')
->set('branch', 'production')
In order to return to old behavior add checking of --branch option.
host('prod')
->set('branch', function () {
return input()->getOption('branch') ?: 'production';
})
Add deploy:info task to the beginning to deploy task.
run returns string instead of Deployer\Type\Result
Now run and runLocally returns string instead of Deployer\Type\Result.
Replace method calls as:
run('command')->toString() → run('command')run('if command; then echo "true"; fi;')->toBool() → test('command')env_vars renamed to env
set('env_vars', 'FOO=bar'); → set('env', ['FOO' => 'bar']);If your are using Symfony recipe, then you need to change env setting:
set('env', 'prod'); → set('symfony_env', 'prod');Servers to Hosts
server($hostname) to host($hostname), and server($name, $hostname) to host($name)->hostname($hostname)localServer($name) to localhost()cluster($name, $nodes, $port) to hosts(...$hodes)serverList($file) to inventory($file)If you need to deploy to same server use host aliases:
host('domain.com/green', 'domain.com/blue')
->set('deploy_path', '~/{{hostname}}')
...
Or you can define different hosts with same hostname:
host('production')
->hostname('domain.com')
->set('deploy_path', '~/production')
...
host('beta')
->hostname('domain.com')
->set('deploy_path', '~/beta')
...
Configuration options
{{server.name}} to {{hostname}}DotArray syntax
In v5 access to nested arrays in config via dot notation was removed. If you was using it, consider to move to plain config options.
Refactor this:
set('a', ['b' => 1]);
// ...
get('a.b');
To:
set('a_b', 1);
// ...
get('a_b');
Credentials
Best practice in new v5 is to omit credentials for connection in deploy.php and write them in ~/.ssh/config instead.
identityFile($publicKeyFile,, $privateKeyFile, $passPhrase) to identityFile($privateKeyFile)pemFile($pemFile) to identityFile($pemFile)forwardAgent() to forwardAgent(true)Tasks constraints
onlyOn to onHostsonlyOnStage to onStageNamespace for functions
Add to beginning of deploy.php next line:
use function Deployer\{server, task, run, set, get, add, before, after};
If you are using PHP version less than 5.6, you can use this:
namespace Deployer;
env() to set()/get()
Rename all calls env($name, $value) to set($name, $value).
Rename all rvalue env($name) to get($name).
Rename all server(...)->env(...) to server(...)->set(...).
Moved NonFatalException
Rename Deployer\Task\NonFatalException to Deployer\Exception\NonFatalException.
Prior release cleanup
Due to changes in release management, the new cleanup task will ignore any prior releases deployed with 3.x. These will need to be manually removed after migrating to and successfully releasing via 4.x.
->path('...')Replace your server paths configuration:
server(...)
->path(...);
to:
server(...)
->env('deploy_path', '...');