Develop and maintain WordPress sites with Trellis and Bedrock

Perfect parity between our dev, staging and production environments.

Nov 27, 2015

At Sprint Works we have been using Trellis together with the Bedrock stack now for a couple of projects. It’s a great way of both developing, maintaining and deploying WordPress sites. We have perfect parity between our dev, staging and production environments. We wanted to share our experiences and will also help you to keep the tools in place.

This is our story.

Roots

Roots is well known in the WordPress community and helps you build better WordPress sites using a modern toolset.

Trellis?

Trellis is the newest product from Roots that aims to replace the antiquated approach to creating and managing WordPress environments.

So, whats the deal?

  • Modern LEMP stack Ubuntu 14.04 Trusty LTS, Nginx, MariaDB, PHP 5.6 or HHVM + Composer, WP-CLI, sSMTP, Memcached, Fail2ban, ferm.

  • Manage server environments with Ansible Create local development environments with Vagrant, provisioned by Ansible for development & production parity.

  • A+ SSL support The SSL implementation scores an A+ on the Qualys SSL Labs Test. Performance optimizations include SPDY, OCSP stapling, and more.

  • Automate your WordPress deployments Create a proper deployment process instead of manually FTPing files which is an error prone method. Automate your WordPress deployments and simplify it to a one command deploy process.

Bedrock

Bedrock provides an improved folder structure, easier configuration and modern development tools.

Bedrock gives you:

  • Better WordPress project structure The organization of Bedrock is similar to putting WordPress in its own subdirectory but with some improvements, including renaming wp-content/ to app/

  • Dependency management with Composer Manage your WordPress install and plugins with Composer, a PHP dependency manager. Composer will make development more reliable, help with team collaboration, and it helps maintain a better Git repository.

  • Easy WordPress configuration Environment specific configuration files and environment variables with Dotenv. (.env files)

Install dependencies

First, you will need these guys to get the party started:

Install Trellis

  1. Download/fork/clone the Trellis repository to your local machine
  2. Run ansible-galaxy install -r requirements.yml inside your Trellis directory to install external Ansible roles/packages
  3. Download/fork/clone Bedrock or have an existing Bedrock-based site ready

You should have this folder structure for your project

mywebsite.com/  - Primary folder for the project
├── trellis/    - The Trellis environment
└── site/       - A Bedrock-based site

Install Bedrock

The cool thing about Bedrock is that it enables support for managing your WordPress themes, plugins, and core install via Composer, which is yet another package manager made specifically for PHP packages.

So go ahead and install:

cd mywebsite.com/site && composer install

Easy as pie.

Git repos

Manage the Trellis and Bedrock in separate git repos.

Configure sites and WordPress

Trellis uses YML-files for confugiration, just open up group_vars/development/WordPress_sites.yml in your favorite editor.

WordPress_sites is the top-level dictionary used to define the WordPress sites, databases, Nginx vhosts, etc that will be created. Each site’s variables are nested under a site “key” (e.g., example.com). This key is just a descriptive name and serves as the default value for some variables. See our example project for a complete working example.

For more information check the Trellis docs and their roots-example-project

Get everything up and running

Now it’s time to setup everything. Trellis will use Ansible and Vagrant for provisioning and create an awesome web server in an isolated container on your machine, using a modern LEMP stack.

```bash cd mywebsite.com/trellis && vagrant up


You'll be prompted to enter your system password which will give Vagrant permission to write to your system's ``/etc/hosts`` file.


## Adding WordPress plugins

 If you have been using composer for WordPress plugin dependency management before, you can skip this section if you like.

 Bedrock will/can prevent the use of updating plugins from the WordPress dashboard, and instead, moves this process to your development environment using [Composer](https://getcomposer.org/). This allows you to check your plugin updates into your version control system and easily find the issues and perform a rollback to working code if an update goes wrong.

To add a plugin, open up ``composer.json``.

### Adding plugins from the WordPress plugin repository.

[WordPress Packagist](http://wpackagist.org) mirrors the WordPress plugin and theme directories as a Composer repository. This means we can use Packagist for installing official plugins, released in the repo.

In this file, you'll see a block of code that resembles the following:

```bash
"require": {
  "php": ">=5.5",
  "composer/installers": "~1.0.12",
  "vlucas/phpdotenv": "^2.0.1",
},

This code is defining the required packages that your WordPress site depends upon. These dependencies will all be installed/updated on your server whenever you or ansible runs the composer install and composer update commands in your CLI.

For adding a new plugin, add a new section in the requre block like this:

"wpackagist-plugin/WordPress-seo": "*",

Install using composer update

This will tell Composer to install Yoast SEO

Adding premium plugins via Composer

For example, we like Advanced Custom Fields and use the plugin a lot. For installing the regular ACF plugin, just follow the example above.

For installing the paid version of ACF, ACF PRO, we have to specify this in a slightly different way.

Make a new chunk in the repositories: {} section:

{
   "type": "package",
   "package": {
     "name": "advanced-custom-fields/advanced-custom-fields-pro",
     "version": "5.3.2.2",
     "type": "WordPress-plugin",
     "dist": {
       "type": "zip",
       "url": "http://connect.advancedcustomfields.com/index.php?p=pro&a=download&k=***********************************************************
     }
   }
 }

Remember to replace the api key with your own.

Then, under reqire: {} specify the package like this:

"advanced-custom-fields/advanced-custom-fields-pro": "^5.0",

Install using composer update

Adding your own plugin from a private repo from Bitbucket

Add a new section in repositories: {}:

{
    "type": "vcs",
    "url":  "https://bitbucket.org/username/reponame.git"
}

Then, under reqire: {} specify the package like this:

"user/reponame": "dev-master"

Install using composer update

Adding 3rd party plugins from Github

Some plugins only exists on Github, and we can install these via Composer as well.

Add a new section in repositories: {}:

{
  "type": "package",
  "package": {
   "name": "cferdinandi/html-minify",
   "version": "1.1.0",
   "type": "WordPress-plugin",
   "dist": {
    "type": "zip",
    "url": "https://github.com/cferdinandi/html-minify/archive/master.zip"
    }
  }
}

Then, under reqire: {} specify the package like this:

"cferdinandi/html-minify": "1.1.0"

Install using composer update

Read more about managing WordPress via composer

Deploy settings

Up until now, we’ve been working on our website locally, meaning that it isn’t actually published anywhere that is publicly accessible. Let’s change that and get you running on a real live webserver.

Open up the file trellis/hosts/production in your preferred editor. In this file is where we’ll tell ansible to deploy all of our WordPress code.

[web]
123.456.789

[production:children]
web

Where 123.456.789 is the ip address to your server.

Turn off root user login

Consider setting sshd_permit_root_login: false in group_vars/all/security.yml

Read more: Security docs

SSH-keys

Each Trellis playbook uses a specific SSH user to connect to your remote machines (or guest VM).

users:
  - name: username
    groups:
      - primary_group
      - other_group
    keys:
      - ""
      - https://github.com/username.keys

The users dictionary tells Trellis which users can deploy code. You can specify the public ssh keys for every user that should deploy code. If you will be the only person provisioning and deploying, and your SSH public key is available at ~/.ssh/id_rsa.pub, you will probably not need to modify the Trellis defaults for users.

For multiple users, you can paste all the keys under keys:, or just point to the key file on the users Github account. Smart and simple!

Read more

Specify git repo and branch

  • Add the repo (Git URL) of your Bedrock WordPress project in the corresponding group_vars/<environment>/WordPress_sites.yml file.
  • Set the branch you want to deploy (optional - defaults to master).

Setup server environment

ansible-playbook -i hosts/<environment> server.yml

Ship it!

Ok, so you’ve built some awesome stuff. But what about the actual deployment?

The first thing you’ll want to do is make sure that all of your latest and greatest code is up on your GitHub or Bitbucket repository. (Or whatever VCS your’e using).

git push origin master

If everything looks good, go to your trellis folder:

./deploy.sh staging mywebsite.se

For deploying to production, change production to staging

./deploy.sh production mywebsite.se

Great success!

Need to do a rollback?

ansible-playbook -i hosts/production rollback.yml --extra-vars="site=mywebsite.se"

Tips and tricks

Hosting

We recommend using Digital Ocean is great. It’s reliable and available and built to scale. Another great recommendation is Glesys.

Vagrant Manager

Vagrant Manger is a nifty little Mac app, wich will manage your vagrant machines in one place. Handy!

Read more