Using Capistrano for Magento 2 to Deploy

There are many different deployment strategies used to deploy code onto a Magento 2 store. One of the deployment tools used is Capistrano, specifically the Capistrano for Magento 2 package. This post will look into using Capistrano for Magento 2 to deploy onto a staging and production environment whilst using Git to version control the code.

It is assumed that you have a working Magento 2 site hosted on a staging or production environment.

Before beginning, ensure that Ruby and Composer has been installed on your computer. Please view the following links for instructions on how to do so.

Installing Ruby

Installing Composer

To install Capistrano, run the below command via a command line interface on your computer. (You may need administrative privileges to install the gem correctly)

$ gem install capistrano

You can check the version of Capistrano installed by running the cap command, passing in the -v flag.

$ cap -v
Capistrano Version: 3.9.0 (Rake Version: 12.0.0)

Now install the capistrano-magento2 gem.

$ gem install capistrano-magento2

As the documentation suggests, the next steps should be to cd to within your Magento 2’s root directory and create a tools/cap directory.

Then cd into this directory, and run the cap install command.

$ cd <project_root>
$ mkdir -p tools/cap
$ cd ./tools/cap
$ cap install

This will trigger the following commands.

$ mkdir -p config/deploy
$ create config/deploy.rb
$ create config/deploy/staging.rb
$ create config/deploy/production.rb
$ mkdir -p lib/capistrano/tasks
$ create Capfile
$ Capified

Continue following the steps on the documentation and update your newly created Capfile to look like the following.

# Load DSL and set up stages
require 'capistrano/setup'

# Load Magento deployment tasks
require 'capistrano/magento2/deploy'
require 'capistrano/magento2/pending'

# Load Git plugin
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git

# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

You’ll note that the Magento specific deployment tasks, capistrano/magento2/deploy and capistrano/magento2/pending, have been added to the default Capfile.

The next step will be to add your SSH public key on your computer to your repository hosting service such as Github or Bitbucket. Click here to find out how to access your public key.

Edit the newly created deploy.rb file to set a name for your application and add in your remote repository’s URL. You should ensure that the remote repository is changed from HTTPS to SSH.

In addition, give your application a name.

# Something unique such as the website or company name
set :application, '<Application_Name>'

# The repository that hosts the Magento 2 application (Magento should live in the root of the repo)
set :repo_url, 'git@<host>:<username>/<repository_name>.git'

In addition to the two setting above, specify the magento_deploy_languages option if you are deploying other languages than the default en_US locale.

For example, if you are using the en_GB locale, you might add the following configuration within deploy.rb.

set :magento_deploy_languages, ['en_GB', 'en_US']

In addition, Magento 2’s composer repository requires auth credentials to install. Within deploy.rb, you can set the magento_auth_public_key and magento_auth_private_key option values to your Magento public and private keys respectively.

set :magento_auth_public_key, '<your_public_key_here>'
set :magento_auth_private_key, '<your_prviate_key_here>'

You can also configure the number of release directories that are kept upon deployment. The default value is 5, however this value can be overridden by adding configuration. For example, to keep 3 releases, add in the below.

set :keep_releases, 3

The staging.rb and production.rb files are used to contain configuration regarding deployment to your staging and production environments.

In both of these files, ensure that you add in SSH connection details to the staging and production environments, and well as specifying the Magento 2 document root and which Git branch to use.

For example, the staging.rb file might look like the below, with the Git branch set to staging.

server '<hostname>', user: '<username>', roles: %w{app db web}

set :deploy_to, '/path/to/Magento/document/root'
set :branch, proc { `git rev-parse --abbrev-ref staging`.chomp }

The production.rb file might look like the below, with the Git branch set to master.

server '<hostname>', user: '<username>', roles: %w{app db web}

set :deploy_to, '/path/to/Magento/document/root'
set :branch, proc { `git rev-parse --abbrev-ref master`.chomp }

The staging and production environments also need some tweaking for the deployment process to work.

Firstly, Git and Composer should be installed should be installed on your staging and production servers. In addition, the composer command should be accessed globally.

Secondly, ensure that the staging and production environments can access the repository hosting service by adding their public keys to the list of allowed access keys in your repository’s settings.

If your environment do not have an existing key to use, you can generate a public and private key pair using the ssh-keygen command.

You can test the SSH connection between your server and the repository hosting service by running the following command.

$ ssh -T git@<host>

For Github, the command is ssh -T git@github.com and for Bitbucket, the command is ssh -T git@bitbucket.org.

If the connection is successful, you should see a message like the below.

ssh -T git@<host>
authenticated via a deploy key.

Lastly, the document root needs to be adjusted on your web server to include a current directory. This is because Capistrano for Magento 2 makes use of atomic deployments, whereby deployment releases are kept in a releases directory with the current release residing in a current directory symlinked to the latest release.

So if your document root for Magento 2 has been configured to the following directory for example.

/var/www/vhosts/magento2/htdocs/pub

Change it so it looks like the below.

/var/www/vhosts/magento2/htdocs/current/pub

Note that the :deploy_to path specified in the staging.rb and production.rb files does not need to change.

As the database connection details will differ depending on what environment of Magento 2 you are using, Capistrano makes use of a shared directory where the env.php file resides.

To setup your environment, run the following commands within your original document root.

$ cd /var/www/vhosts/magento2/htdocs
$ mkdir -p shared/app/etc
$ touch shared/app/etc/env.php

Proceed to edit your env.php file adding in the correct database connection details and other environment information.

Note that for the staging environment, it is advised that you set the Magento mode to production. This will allow you to obtain an accurate reflection of how the deployment process worked on staging before trying to deploy on the production environment.

In order to test a deployment, ensure that you have pushed up your latest code changes to your remote repository and cd into your Magento project’s tools/cap directory.

Then run either cap staging deploy to deploy to the staging environment, or cap production deploy to deploy to the production environment.

One of the advantages of using this deployment method is that downtime is minimised as much as possible. The Magento specific commands such as setup:di:compile and setup:static-content:deploy that take a while to run are run within the codebase before the current symlink is updated to point to your new release.

If, for some reason, the deployment fails, the current symlink will continue to point to the release directory it was pointed to before you began the deployment.

Should you have followed the steps above and configured your deployment settings correctly, upon deployment you should be able to browse to your newer version of your staging and production Magento environments.

Remember, run cap staging deploy before deploying to your production environment to test any changes.