Automating Your PHP Application Deployment with PHP Deployer
Before the evolution of cloud technology, the biggest challenge was the stability of the server hardware. Since the growth of cloud technology, the focus from the stable hardware is moved to the stable application. Customers require application features to be developed and deployed quickly to beat the competitors. To achieve this it is important to implement Continuous Integration (CI) and Continuous Deployment (CD) for any organization.
There are plenty of tools available to manage the CI and CD, but this blog will focus on PHP Deployer. The intended audience for this blog post is from beginner to intermediate users with experience in basic Linux system administration and programming skills.
What Is Deployer?
PHP Deployer (Deployer) is a handy tool to deploy any PHP based applications effortlessly. Deployer is an open source application and it is free to use. Some of the known supported MVC/CMS is, Laravel, CakePHP, Codeigniter, WordPress, Drupal and many more.
Deployer comes with very easy setup process and it requires a very small learning curve. Anyone with some programming and coding skill can easily start developing scripts with PHP Deployer. Apart from that Deployer has a large community support that provides plenty of the ready to use scripts (Deployer recipes) to start working with.
Deployer also provides the following features:
- Capable of parallel deployment, meaning you can roll out new features on all application servers at the same time.
- Agentless utility. It does not require any agent installation on remote servers. Deployer runs on SSH.
- Comes with a great feature of rollback, which means that you can rollback applications to the previous version with a simple command.
- Deployments by Deployer do not require any downtimes and it can also be integrated with CI tools like Jenkins.
How Does Deployer Work?
Deployer tasks are divided into the following steps
- Preparation (deploy:prepare)
In this task, the Deployer checks the existence of the deployment directory (deploy_path). If the directory does not exist then it will create a new directory for the deployment.
The script also checks for the releases, shared and .dep folders. The releases contain the previous releases of the application and in the case of application rollback, the Deployer changes the release path to the previously available version by updating the symlink.
The shared directory contains the files and folder structure among all the releases. For example, in the case of any Laravel application publicshared files are shared among all the releases. In the case of WordPress wp-contentuploads folder must be shared among all the releases.
- Lock (deploy:lock)
Once the preparation step is successful the Deployer locks down the deployment to prevent concurrent application deployments. The deployment lock file is generated under .dep/deployment.lock
Due to any cases, if the deployment is unsuccessful then to release the lock deploy:unlock command must be supplied. As an alternate deployment.lock file can be deleted to unlock the deployment, however, it is neither a preferred nor an advised way.
- Release (deploy:release)
The Deployer will create a new release folder based on the name defined in release_name. This step will also check the previous releases details stored in the .dep folder
If the deployment is successful (All the deployment steps returns “Pass”) then Deployer will delete the symlink to the previous version and create a new symlink to the new version.
If the deployment is failed then the symlink will not be updated and the application will still be the old version/code.
- Code Update (deploy:update_code)
In this step, the Deployer pulls the new repository from the defined git source.
- Shared files Update (deploy:shared)
In this step, the Deployer Copies directory(ies) from release_path to shared, delete dir from release_path, and symlink dir from shared to release_path.
- Rights Update (deploy:writable)
On this step, the Deployer updates the writable directories rights using chown, chmod.
- Composer Install / Update (deploy:vendors)
After completion of above tasks, the Deployer runs composer install command to start installing/updating the dependencies.
- Remove Directories (deploy:clear_paths)
The Deployer can also remove the unnecessary directories after the deployment. This task can be achieved by defining the directories to be removed under the clear_paths.
- Activate new release (deploy:symlink)
Deployer creates a symbolic link (symlink) to the new version of the application and the new version gets activated.
- Unlock the deployment (deploy:unlock)
The Deployer then removes the deployment lock by removing the .dep/deployment.lock
- Remove old releases (cleanup)
If the keep_releases parameter is defined in the installation script then it will remove the excess number of release folders from the deployment path.
On completion of the above steps successfully, the Deployer will print successful deployment message.
Getting Started with Deployer
The first step is to install the Deployer. Before you begin, make sure that the system contains PHP. If you are using an Ubuntu-based system, you can meet the dependencies by supplying following commands
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install php
Once the above commands are supplied, the next step is to set up the Deployer
curl -LO https://Deployer.org/Deployer.phar
sudo mv Deployer.phar /usr/local/bin/dep
sudo chmod +x /usr/local/bin/dep
After successful installation, it is time to develop our first PHP Deployer script. As a best practice, it is recommended to create a separate folder for the deployment scripts. For this demo, we are using a folder named Deployer.
On running the deploy init command, some basic details need to be provided to generate a basic install script. For the beginning, we can choose 0 — Common.
In the next step provide your Git repository details. This step is optional, so in case you do not have any repository details, you can skip the step.
In the next step, you can choose to submit the anonymous usage information to the php-Deployer community. In case you do not want to send the information, you can supply no.
On completion, the Deployer will create a deploy.php file in the folder and it will look like as follows
Important parameters from the file,
Here you can set up the application/project name. Note that this is just an identifier, it has no impact on the script.
You can set up the git hub repository path here. Make sure to set up the git deploy key on the server.
You can use the domain name or IP addresses separated by a comma in the host section. The deploy_path contains the deployment path on the server.
Following is the updated configuration for the server. As a best practice, it is good to use the least privilege user for the deployment.
For the following script, deployment is the user with rights to restart the nginx, and php-fpm.
run('sudo /usr/sbin/service nginx reload');
run('sudo /usr/sbin/service php7.0-fpm restart');
Above command creates a function for the script named “restart-nginx-fpm’, Usually, we reload/restart Nginx and php-fpm after completion of the deployment, so the function is added after the deploy:unlock in the task list.
The run section can run any commands on the remote server. for this example, it will reload the nginx and php7.0-fpm service.
To run the install supply the following command
if the scripts throw any errors, you can run the script in verbose mode to get more details
dep deploy -v , provides default installation view with the least information
dep deploy -vv, provides some more details as compared with the default mode
dep deploy -vvv, provides detailed view of the installation output
As a default parameter, the Deployer deploys master branch. To deploy any other branch “branch” parameter can be supplied with the deployment script.
dep deploy --branch=uat
Sometimes we get multiple deployment scripts, to use any specific file “filename” parameter can be supplied
dep --filename=<filename> deploy
Multiple parameters can be supplied with one command
dep --filename=<filename> deploy --branch=<branchname> -vv
For the following example, we are switching between three different branches and applications.
Following is the sample WordPress script for php-Deployer.
Apart from the basic site deployment, the following are new variables for the script
This script is using chmod as the writable mode for the wp-content directory. For each WordPress deployment, the wp-content directory and wp-config.php files are almost consistent. We can define them as shared_files so it can be shared between different releases.
At any step, if the deployment is failed then running the following command will seamlessly rollback the application to the previous release.
If you are using the file method then supply the following command
dep --filename=<filename> rollback
Deployer keeps all the revision of the application as default parameter. However, you can override this setting by adding the following command in the deployment script.
The Deployer will check keep_releases parameter at the end of the script execution and remove any releases more than the specified number during the cleanup step.
Updating the Deployer
To update the minor version of the Deployer run,
To update the Deployer to major release version run,