Picture of roots.io ecosystem logos on black background
Development & Coding

Getting Started with Trellis, Bedrock and Sage

My introduction to the Roots ecosystem occurred when I was asked to migrate a WordPress website which uses the Bedrock framework.

During the process I encountered many stumbling blocks. This is due to my lack of knowledge of the framework and the way in which it works.

After doing a bit of research I learnt about Bedrock’s partners Trellis and Sage, and the Roots ecosystem and wanted to test them out.

I found that there are a few challenges to overcome while setting up. This is why I am writing this article.

What are Roots, Trellis, Bedrock and Sage?

Roots is a team of WordPress developers who have united in order to work on open source projects.

Trellis, Bedrock and Sage are essentially a suite of free tools designed to improve the WordPress development process.

Bedrock – The brains

Bedrock describes itself as a “WordPress boilerplate with modern development tools, easier configuration, and an improved folder structure”. To lesser versed developers this might just seem like a load of jargon so I will do my best to explain a bit.

In its essence, the most notable changes which you might notice when using Bedrock are going to be to do with the package’s folder structure.

Traditionally WordPress’s entire body lives inside a web domain’s root directory. With Bedrock, however, your website’s root directory will look a little different.

You will find that your WordPress installation lives inside a folder titled web while any packages you wish to add with composer (package manager) live inside a folder titled vendor and your WordPress config files live inside a folder named… you guessed it…. config.

But Why?

This might seem a little strange at first but it does make sense. Separating your project’s config, dependencies and content makes it a lot easier to manage, and adds it own level of security.

Using a package manager such as Composer means you can ensure any plugins or packages which you add to your project are compatible with it. While rearranging the traditional WordPress folder structure will stifle attackers which exploit many well known vulnerabilities.

Sage – The skin

Sage is essentially a WordPress theme boilerplate which uses the Blade templating language.

It is not essential to use the Sage boilerplate in order to reap the benefits of Bedrock and, if I am honest, getting it setup was the part of the Roots ecosystem which caused me the biggest headache.

Personally I preferred using the Underscore starter theme from Automattic but that is a personal preference and, as such, I will explain how to get going with Sage within this article.

Trellis – The engine

Finally, Trellis. It is easiest to think of Trellis as the Swiss Army Knife of server managers. It allows you to seamlessly switch between development, staging and production without needing to use the dreaded MAMP (sorry, it’s just not a pleasant experience), or copy-paste bash scripts you found online.

As it utilises the VirtualBox software it allows you to setup your dev environment to mimic your production server. This is a game changer for me as it means I can deploy a project with confidence, and without surprises.

Further to this it also allows for you to make changes to your WordPress project and deploy it with 0 downtime by automatically deploying it with git clone.

Setting up Trellis, Bedrock and Sage

Before we start I should note that I have only completed this using an apple mac. If you are using a Windows or Ubuntu based system the steps required might differ.

Anyway, to keep this simple I will suggest to go to the Roots docs and follow their setup guide.

Once you have completed this you will need to install Node 10 in order to use the Sage theme boilerplate. This is something which took me a long time to figure out. It is also one of the reasons why I eventually decided to not use the Sage boilerplate.

I know that Node, in this case, is only used in the development stage of the theme but we’re now on Node 15. That’s a whopping 5 major versions ahead.

Even if you go with the recommended LTS release of Node we’re on version 12. I just prefer to use up to date tools. Rant over.

If you followed the linked documentation you will have installed NVM (Node Version Manager) and the latest LTS release of Node. Your next step is to install Node 10.

Open up terminal and type the following:

nvm install v10

Now that this is complete we are ready to begin setting up our first Roots based WordPress project.

Setup a Project

What we are going to do now is setup a project in your home directory. First we are going to navigate there in terminal, just in case you have navigated away from there:

cd ~/

Now we need to make a folder for our Roots based websites. Let’s make a folder called roots-projects:

mkdir roots-projects

And now navigate into it:

cd roots-projects

Setting up Trellis

Next we need to install Trellis:

git clone --depth=1 git@github.com:roots/trellis.git && rm -rf trellis/.git

If all went to plan you should now be able to run an ls command a see a folder called trellis. Enter it:

cd trellis

What we are going to do now is setup the Trellis variables file for the development environment. We are going to tell Trellis that we want to make a website called roots-example.com.

We are also going to tell Trellis that we want our development site to be served from roots-example.test and that we want to use an SSL which is self signed.

Run the following command to open the variables folder:

open group_vars

You are going to see four folders: all, development, staging and production. As I am sure you have already presumed, they represent each respective environment’s variables.

Open the development folder and then open the file named wordpress_sites.yml in your preferred code editor. On line 6 you are going to see example.com.

This is the name of your site, it doesn’t have to be a website and is only used as an identifier within Trellis, however it is recommended to set this as the domain of the site you are developing.

Since we are going to make a site called roots-example.com we should use this as the identifier. Change line six to reflect this.

The next line down reads site_hosts, this is essentially where we will define the address from which we want our development site to be served.

As I said we want to serve our development site from roots-example.test, we will need to change this section to reflect that.

On line 8 change the text which reads example.test to roots-example.test. This is telling Trellis to serve our development site from our desired address.

On line 10 you will see that is reads - canonical: www.example.test, change it so that is reads - canonical: www.roots-example.test. This is telling Trellis to redirect the www. subdomain to our websites top level domain. Just like in a production server.

The next line down defines where the files of our site are held. It is currently set as ~/roots-projects/site.

In order to allow for multiple projects to be handled by this Trellis installation we are going to serve our website from ~/roots-projects/roots-example.com. To do this we simply need to alter the line so it reads local_path: ../roots-example.com.

The last thing we need to do in this file is tell Trellis to use a self signed SSL certificate. To do this alter line 16 so that it reads enabled: true.

If you wish to use this Trellis installation to manage another website you can simply duplicate lines 6 – 20 and change the respective variables.

Save and close this file and then, while still in ~/roots-projects/trellis/group_vars/development, open a file called vault. This is where we will set our WordPress admin password and our database password.

As we are only setting up a local development environment we don’t really have much of a need to alter passwords so we are only going to make one change in the file and that is on line 7.

You’ll see that it currently reads example.com. As you probably can expect, this is the name of the respective site to which these passwords belong. Change it so that it reads roots-example.com.

When you add new sites you will need to ensure you set the passwords in this file. You can simply copy from line 7 and then change the domain name to match what you enter in the wordpress_sites.yml file.

We are now done with setting up Trellis for our project so let’s setup Bedrock.

Setting up Bedrock

Open up your terminal window again and ensure you are in the roots-project folder ~/roots-projects/.

Once you are in the right place you will need to use composer to create the project, run the following command:

composer create-project roots/bedrock roots-example.com

By running the above command we have created a folder called roots-example.com and then used composer to create a Bedrock project within it.

Setting up Sage

Finally, to setup Sage. This is where we will need to use Node v10. To do this we will first navigate to the themes directory. Run the following command from your terminal window:

cd ~/roots-projects/roots-example.com/web/app/themes

Now we will use composer to install Sage. Run the following command:

composer create-project roots/sage sage

You will be prompted to input some information. Just press enter to leave the default settings until you see Local development URL of WP site. This is where we tell Sage to find our development website.

Our website is being served locally from https://roots-example.test so input that.

The next prompt will ask where Sage can find your theme files, as our theme is in a folder named sage we can leave this as the default. However, if you name your folder something different you will need to reflect that here.

We are not adding any CSS frameworks so enter 0 when asked which framework you wish to use.

Next you will be asked if you wish to overwrite the default SCSS variables, enter y.

Finally tell Sage whether you wish to allow them to collect data on you. You’re almost ready!

Building Sage

Navigate to the directory of your theme:

cd ~/roots-projects/roots-example.com/web/app/themes/sage

Then install all PHP packages and dependencies using composer:

composer install

Now we need to tell NVM to use Node version 10 which we installed earlier:

nvm use v10

And, finally, build the theme:

yarn && yarn build

You will see a bucket load of warnings, this is to be expected since we are using an outdated version of Node.

Test it Out

We are almost ready to test our development environment. Navigate back to the trellis installation’s directory:

~/roots-projects/trellis

We now need to install a plugin for the vagrant dev server which allows our browser to accept Trellis’s self signed SSL certificate. Run the following command to do so:

vagrant plugin install vagrant-trellis-cert

Before we can use this plugin we need to fire up our vagrant server, to do so run the following command:

vagrant up

If you run into an error which states something along the lines of:

The "roots/wordpress-core-installer" plugin was skipped because it requires a
Plugin API version ("^1.0") that does not match your Composer installation
("2.0.0")

You can solve this issue by executing the following command:

cd ~/roots-projects/roots-example.com && composer update --no-plugins

What we are doing here is updating the plugins which are used by our Bedrock project.

Now navigate back to the Trellis folder and run the vagrant up command with the provision flag:

cd ~/roots-projects/trellis && vagrant up --provision

Finally, use the trellis-cert plugin to allow our self signed certificate:

vagrant trellis-cert trust

And that is it! You should now be able to head on over to https://roots-example.test and see our development site.

Something to note is that you should always kill the server using vagrant halt when you are done for the day. Another note is that anytime you wish to add a new site you will need to add the provision flag when you run vagrant up, for example:

vagrant up --provision

You will also need to run vagrant trellis-cert trust every time you have added a new site.

There you have it. I hope this helps someone.

Peace, love and happiness.