Deploying WordPress Applications with Envoyer
Occasionally I feel nostalgic about some of the “old” things from my early days in Web Development—like building websites on Yahoo! Geocities or customizing MySpace profiles via HTML and CSS. One thing that I’ll never feel nostalgic about is deploying website changes via FTP or SFTP. No way do I miss keeping track of which files need to be drag and dropped into Cyberduck, or splitting file uploads to avoid timeout errors. Deployment tools such as Envoyer have made life so much easier.
What is Envoyer?
Envoyer is an atomic deployment tool that allows us to deploy code changes quickly and without any downtime. We say atomic because the changes are made available once the build is complete, without impacting the active codebase. As their website says, Envoyer is for PHP deployments and was created primarily for Laravel apps, but you can easily use Envoyer to deploy WordPress sites, static HTML sites, and a variety of other projects with a few small tweaks.
Envoyer can be used with all sorts of hosts, so long as you have SSH access. We even use Envoyer on a number of small shared hosting accounts at SiteGround.
Plans range from $10–$50 a month or $100–$500 a year, based on the number of projects that you require. They also have a 5 day trial period which allows you to take the tool for a test spin.
Why Envoyer?
Until about a year and a half ago we were using Capistrano to deploy our projects from the command line. This worked well, but was tedious to setup and didn’t offer great visibility into our deployments. I wanted to find a tool with a GUI that was easy for all members of our team to not only make deployments, but also configure new projects, and view all recent deployments at a glance.
We love Laravel at Storyware and use a lot from the Laravel ecosystem in our WordPress projects. Our WordPress projects are actually structured a lot like Laravel apps thanks to the wonderful Themosis framework. So when Taylor Otwell (the creator of Laravel) announced Envoyer, I immediately wanted to check it out.
How Does it Work?
Envoyer deploys your git repository to a “releases” directory on your server. Next, Envoyer works through its build commands such as running composer install and linking shared folders. You can even add your own build commands for doing things like compiling assets. Once Envoyer is done, the “current” directory is symlinked over to the latest release folder which is named based on the timestamp.
So let’s say your project’s webroot should be “public”—then you would point your web document root to {your deployment path}/current/public
, which will always reference the latest version of your codebase.
How do we use Envoyer with WordPress?
I’m going to walk you through the basic steps required to deploy a WordPress site with Envoyer. Before we get started, here’s what you need:
- Code repository hosted via GitHub, Bitbucket, or GitLab.
- SSH access to your server
- A bit of experience in basic DevOps activities and using the command line.
Here are a few things to keep in mind:
- It’s ridiculously easy to configure deployments for Laravel or Lumen applications. We need to do a little manual work for WordPress, but it’s not too hard. We’re going to use Envoyer’s deployment hooks to add some commands to make our WordPress application running.
- We use Composer to manage our PHP dependencies, including WordPress and WordPress plugins. Not using Composer? Check this out.
- In this case, our web app runs within the
/public
folder of our codebase, and WordPress gets installed into a subdirectory. We keep our environment information outside of the web root, one level above/public
. - We are adding a few cache related folders and files required by WP-Rocket. If you’re using a caching plugin, you will need to do some similar steps.
- We’re using Themosis, and in this case it’s version 1.3 (we just started exploring the 2.0 version of Themosis which is still in beta, but really great!). This means we have a views folder which contains our compiled blade template files.
Okay, let’s go.
- Create a new project in Envoyer
- Click “other” for project type.
- Once your project has been setup, click into the project to continue configuration.
- First we need to add a server. Click “Servers” -> “Add Server”
- Enter in your server/SSH connection information.
- Before clicking “Save Server” be sure to enable “receives code deployments” add in your deployment path. This is where your code is going to be deployed on your server. In the case of most basic hosting accounts, it’s going to be
/home/{user}/deploy
, assuming you’ve created a folder specifically called “deploy” for Envoyer to utilize. Also, don’t forget to specify which PHP version you’re using! - In the case of working with an SSH user that has limited permissions, we need to disable FPM Reload under deployments. Do this by clicking the edit icon next to the server info, and then unchecking “Restart PHP FPM After Deployments”
- When the server is saved you need to grab the SSH key to add to your server which will allow Envoyer to connect for deployments. Click the key icon next to your server details for this.
- If you’re using C-Panel (or Plesk for that matter), then it’s simple to add the Envoyer public key to the server. Just go to manage SSH keys, and paste in the public key from Envoyer. Depending on the typer of server, you may need to authorize the key after adding it. If you need to add the key manually via SSH, then this will point you in the right direction.
- Check to make sure that Envoyer can connect to the server by clicking the refresh icon under Connection Status. If all went well, then you’ll get a green light and see “success” under connection status.
- Now let’s hop on over to the server side of things to create some files and folders. Also, I’m assuming that you have already created a database and database user.
- Let’s SSH into our server and create the deployment directory. For today’s purposes I’m assuming that when you login you’re confined to the user’s directory, so you’re working in something along the lines of
/home/{user}
.$ cd ~/ $ mkdir deploy $ cd deploy
- Now let’s created a shared folder when we’re going to store things that are shared between our releases: uploads, cache related folders, view files compiled by Themosis, .htaccess, and your environment file that holds database credentials etc..
$ cd shared $ touch .htaccess $ touch environment.php $ mkdir content $ cd content $ touch advanced-cache.php $ mkdir cache $ mkdir -p storage/views $ mkdir wp-rocket-config $ mkdir uploads
- Populate the contents of your .htaccess like you normally would for a WordPress application.
- Populate the contents of your environment file. In this particular case we’re using environment.php which we store outside of the web root and include in wp-config.php. This is key for security. Read more about this practice here.
Sidenote: many of our projects are using .env files. For these projects, we actually manage the environment file variables within Envoyer by clicking “Manage Environment” under the project’s servers tab. Read More on using .env files with PHP dotenv. - Now let’s dive into setting up our linked folders and files within Envoyer. We need to link the uploads folder, wp-rocket-config, cache, and views. Go to Deployment Hooks -> Linked Folders. We rename the “wp-content” folder to “content” in our projects, so we’re going to setup the links like so:
- This is probably the trickiest part of deploying WordPress sites with Envoyer—there isn’t a way to create linked files, just folders. Let’s do this manually. Go to “Deployment Hooks” and click the settings cog next to “Clone New Release”
- Let’s click add hook “After This Action”
- Fill in the SSH info, and then use the following commands to create symlinks between the shared files and your directory. Note that advanced-cache.php is deleted on each deploy before getting re-linked, as we need to reference the latest path in the releases directory. {{ release }} and {{ project }} are both variables available to us in Envoyer deployment hooks. Read more about Deployment Hooks in the Envoyer Docs.
ln -s {{project}}/shared/environment.php {{release}}/environment.php ln -s {{project}}/shared/.htaccess {{release}}/public/.htaccess file={{release}}/public/content/advanced-cache.php if [ -f $file ] ; then rm $file fi ln -s {{project}}/shared/content/advanced-cache.php {{release}}/public/content/advanced-cache.php
Sidenote: Envoyer just made it possible to copy Deployment Hooks from one project to another. Save time when setting up future projects by using this feature.
- For a basic WordPress install, you’re now set to trigger a deploy by clicking the large Deploy button. If you’ve set everything up correctly then you should see a “Finished” status with a green checkmark next to the deployment on the project home page.
- But wait, what if your host is pointing the web root to
public_html
, and notdeploy/current/public
? SSH into your server and perform the following commands:$ cd ~/ $ rm -rf public_html $ ln -s /home/{user}/deploy/current/public /home/{user}/public_html
- Now you should be all set to navigate to your freshly deployed application!
Spend less time deploying, and more time building.
We’ve been pretty happy with Envoyer since moving our deployment workflow to the platform almost a year and a half ago. Our clients are often impressed when we contact them just minutes after a major deployment to tell them that everything is all wrapped up.
If you’re Interested in bringing Envoyer or some of the practices outlined here to your team’s WordPress workflow then feel free to give Storyware a shout. We’ve been architecting and deploying enterprise-level WordPress applications for years.