Reading Time: 3 minutes

On Saturday 24th, Jordi Boggiano and Nils Adermann officially announced the release of composer 2.0! This is really great news and I’m looking forward to using composer 2. The speed improvements seem very promising and I really like the handy runtime feature with the new class Composer\\InstalledVersions.

Yet, as it is also stated in the announcement, you might get problems with plugins when updating to composer 2 when the composer-plugins are not yet ready. In my case, something similar happened. We are a couple of days before the launch of a big project and this is certainly not the time to upgrade your third party dependencies or your package manager.

This alone should not pose any problems. You can still choose not to update your composer version until you’re ready. But you might have guessed it already from the title: it’s a problem when using Deployer as your deployment library!

Deployer

Deployer is a deployment tool written in PHP which helps you deploy your code to multiple servers. It has a lot of built-in recipes for frameworks like Symfony, Laravel, Zend, CakePHP, Mageto, TYPO3, Yii and even more! And of course, you can write your own recipe or custom logic for your deployments.

How it works in a nutshell

Deployer has variables which you can get() and which can (or have to) be set(). Additionally, you can define task()s (i.e. php functions) which can be run in a certain order, in parallel on multiple hosts, once or only on a set of servers. There’s a common.php recipe which includes the “basic” functionality and can give you a broad overview of what is possible with Deployer (and so can the documentation at: https://deployer.org/docs/getting-started.html).

The deployment tool reminds me a lot of the Ruby-based tool Capistrano (https://capistranorb.com/) which was initially released 15 years ago and which I used for some of my early Symfony 2 projects (https://everzet.github.io/capifony/). We decided to use Deployer instead because Capifony is not maintained anymore and didn’t want to add complexity by adding another programming language to the repository – just for deployments.

The issue

Until last week, everything worked without a hiccup and I didn’t even bother to care if the composer.phar was re-installed from the web, copied or re-used from a different directory. It worked and I didn’t feel like I need to know every little detail of the Deployer implementation. But with the release of composer 2.0 I suddenly realised that Deployer always wants the newest composer version downloaded from the website.

set('bin/composer', function () {
    if (commandExist('composer')) {
        $composer = locateBinaryPath('composer');
    }

    if (empty($composer)) {
        run("cd {{release_path}} && curl -sS <https://getcomposer.org/installer> | {{bin/php}}");
        $composer = '{{bin/php}} {{release_path}}/composer.phar';
    }

    return $composer;
});

So what I did instead was to overwrite the bin/composer task inside our deploy script and set a specific version right there:

set('bin/composer', function () {
    if (commandExist('composer')) {
        $composer = locateBinaryPath('composer');
    }

    if (empty($composer)) {
        $version = '1.10.17';

        run("cd {{release_path}} && curl -sS https://getcomposer.org/installer | {{bin/php}} -- --version={$version}");
        $composer = '{{bin/php}} {{release_path}}/composer.phar';
    }

    return $composer;
});

A different approach

Maybe you want to have even more control over the composer binary or you are thinking: “Why should I download the same composer version every time I deploy something?”…

In Capifony, you could simply set the composer_bin to an absolute path on your server. So you could either make sure that the wanted composer.phar is available on every server you’re deploying to or you could add it to your repository. By the latter approach, you even have a git history of when, who and why the composer version was updated.

Addendum

I love the open source community for the unstopping effort to improve and make all our (programmer) lives better and I am extremely grateful to all contributors! Only a few days after publishing this article, there is already a Pull Request for the new Deployer version 7:

https://github.com/deployphp/deployer/pull/2222

I’m looking forward to the next release! Checkout what has changed and which cool new features were added so far:

https://github.com/deployphp/deployer/blob/v7.0.0-beta.3/CHANGELOG.md

Moritz Wachter

Author Moritz Wachter

More posts by Moritz Wachter