Matt Westgate
The primary reason we don’t take the time to set up automated review environments in our development workflow is that the process of getting to automation is front-loaded and hard. It requires you to sit down and codify every decision and failsafe necessary to deploy your infrastructure. However, the benefit of doing this work is developers can now use infrastructure like they use code, and they can spin up what they need when they need it.
By investing in automating your ephemeral infrastructure, you are literally removing all technical barriers for collaboration between development and the rest of the team. And that is crucial. You are making pathways for engineers to share their work the moment it is ready, in a clean and fully isolated environment, they (and you!) didn’t have to spin up or wait in line to access. In short, you’ve made the development process visual and accessible and removed the conflict and mistakes that resulted from not being able to see the work as if it were already in production.
In this article, we’ll walk you through the shortcuts of how to codify your review environments to give you fully isolated and clean deployment Previews for any code push. That will pave the way to eventually leverage Tugboat for automated visual regression, accessibility audits, SEO reviews, and performance analysis, all within the testing cycle of your feature branches.
As we go through creating the Tugboat config file, if you have questions or concerns, reach out to us on Twitter or join our community in Slack!
For reference and a quick jump, here are the 10 tips we’re going to cover:
To get started, we’re going to assume three things:
As a developer, it can be more enjoyable to work locally with your preferred apps and setup. If you want the full range of what Tugboat is capable of, download the CLI, and get all the power of Tugboat right from your terminal. For Mac users, Tugboat can be installed using homebrew. After you’ve got the CLI, you’ll need to set an access token.
To see what the CLI can do, run tugboat from the command line. Once you’ve browsed the available commands, adding the --help parameter to any command will give you details. Say, for instance, you want to learn about the validate command. Type tugboat validate --help to see what it can do.
Here’s the help output of the high-level tugboat command:
Commands:
With the Tugboat CLI downloaded and installed, it’s time for tip number 2!
There are many starter configs for Tugboat, but if you copy and paste the whole config, you are bound to get errors since they need to be customized. You’ll need to specify data sources, for example. It’s better to test the starter config lines one by one using the tugboat shell. It will be faster this way so errors can be isolated.
You can bring your own containers to Tugboat, but when you’re getting set up, start with things that are known to work. All of Tugboat’s container images are extensions of official Docker images and have been tailored to work in the Tugboat environment. Start with them. Later, when you have a working build, you can dive into expert mode and make Tugboat images that mirror production. Our friends at Chromatic have a great article about using custom Docker images within Tugboat.
Your initial config file should be simple and straightforward: install the image you need and make it the default service. That’s it.
Say you’re installing PHP, for example; your config file might look like this:
The line default: true is not required, but it’s a good practice to have it. If you have a single service, it will be the default service with or without that line. But as soon as you have two services defined, you’ll need to specify which one is the default service to route requests to.
The above config file will give you a PHP service with your Git repository checked out at /var/lib/tugboat in that service container. Now before you commit that code to your repo, let’s validate it and do a build.
With the CLI, you can validate your config locally before you push it to Git, which then Tugboat will grab and build. This will save you time, so you don’t wait for a build to potentially error out because of a typo, or worse, tabs rather than spaces. YAML files don’t allow tabs. Validating your config can only be done through the tugboat CLI and not the Tugboat web interface.
In our PHP example above, we run this validation command from the root of our checked-out repository on our local:
And we’d receive the following output:
Notice the structured content? That is how Tugboat is parsing your YAML config. If fully structured content was returned, then you’re all set! If Tugboat could not parse your YAML config, you would not see the structured output, and instead, you’d see an error message, and in most cases, the location of the error within your YAML file.
For example, if we changed the name we gave our service from php to php yippee, Tugboat will not be happy and throw an error. Service names double as hostnames, and a host name cannot have a space character. This is the error you will see:
Invalid Preview configuration (Error 1056): service name must be a valid host name: php yippee
Some of the other standard error 1056 validation errors are:
With a clean validation, let’s create a Tugboat Preview and see how it goes. Since we’re not sure if the build will work yet, we can pass the config file to Tugboat without pushing a commit to our repository. First, we’ll grab the Tugboat Repository ID using the tugboat list command, and then we’ll create our first Preview with tugboat create.
Grab the Repository ID with this:
And if you want the full details of the repository, you can call tugboat list repos --verbose
The raw output will look something like this:
Now let’s build a Preview from the main branch of our repository using our Repository ID and pass the path to our work-in-progress Tugboat config.yml file as a parameter as well.
Note: if you want to build something other than a branch, you can also build a tag, commit, or a pull/merge request. If you want to do one of those, you’ll need to pass the type option (i.e. type=tag, type=commit, type=pullrequest, or type=mergerequest). If you don’t pass in type, Tugboat attempts to guess the type by searching for a ref that matches the provided preview name. In our case, that was main.
And here is the abbreviated output from our successful build:
Make a note of your Preview ID. It will come in handy later to shell into the build. Our Preview ID is 2348jwjwfbfcwwke2302340f.
Just a note that you won’t see anything if you visit the Preview URL. We haven’t told Tugboat where the document root is, so there is nothing to display. If your web folder was ./web in your repos, you could add the line - ln -snf “${TUGBOAT_ROOT}/web” “${DOCROOT}” in your config to serve those pages. See here for details on setting up your document root.
Now that you have build up and running, you can shell into the service container to test the subsequent build steps directly in the environment. The terminal for a service can be accessed in your browser via the Preview landing page, or through the command line using tugboat shell.
The command looks like this:
Running that command will drop you into a shell on your default service. If you need to test a command on a different service than your default, use tugboat ls services to get the corresponding Service ID, and you’d pass that instead with tugboat shell [service-id].
So you should now be in your container and able to navigate around! By default, you start at /var/lib/tugboat. If you ls that directory, you’ll see your git repository. And this will be true for any service where checkout: true is set, or you’re in the default service.
As you gear up to test your build steps, now is an excellent time to familiarize yourself with the environment variablesTugboat makes available. $TUGBOAT_ROOT, for example, points to the filesystem location where the git repository is cloned, usually /var/lib/tugboat.
You can also set custom environment variables in the Tugboat UI on the Repository Settings page. Custom environment variables come in handy when you don’t want secrets or snippets committed to your git repository to be used.
One by one, start testing out your commands. Since most of Tugboat’s images are Debian-based, a common starting place is apt-get update && apt install <foo> to install additional packages. Or you could go back to one of our starter configs and begin testing out the lines, one by one.</foo>
One thing to be mindful of: when using the shell to test your commands, the shell will remember what the current working directory is. However, the lines executed in the Tugboat are run one by one. That means doing something like this in your config.yml won’t work:
Instead, you can change that to a one-liner:
When you have a working line that does what you want it to do, add it to your local Tugboat config and then validate it again. Now is a good time to commit our work back into our Git repos. Once your updated config file is pushed into your repository, let’s delete the existing Preview and then rebuild it.
If, for some reason, you’ve made a mess of your environment and can’t remember which config file Tugboat is using, you can ask Tugboat to show you, though you won’t get the raw version of the config file. You’ll receive the config file as processed by Tugboat and broken down by service. Here’s the command:
If you also have jq, the command-line JSON processor installed, you can take this one step further.
And if you want to reset your environment back to the way it was before you started issuing shell commands to test build steps, you can issue a reset.
The Preview is reset back to the original YAML config you passed in via the command line. It’s a better way to start again without the overhead of waiting for a rebuild.
Before you move on to tip number 8, make sure you have a working config file checked into your repository, and you’ve asked Tugboat to rebuild (not reset) the Preview.
Now that you’ve got a good pattern for validating your config and testing your script lines, we can do one more thing to make the setup happen as quickly as possible. We can take a snapshot of your build and then rebuild using the snapshot as the starting place. We’ll do that with Base Previews. This is what makes Tugboat the fastest and most efficient Preview Deployment platform on the market.
Within the config file, the build script happens in different “steps.” Each service can have init, update, and buildsteps. There are other steps, but we don’t need to cover those now.
Overall, the structure looks like this:
While there’s a flowchart on the build process for Tugboat, what you need to know is that when you promote a Preview to a Base Preview, Tugboat will then use the Base Preview as a starting point for any new environments, and only run the build steps of each service, saving loads of time.
Before you make a Base Preview, commit your working build script to your repository! By default, the Base Preview will pull in new changes from your repository nightly, so you want to keep things in sync. Usually, your Base Preview is the branch you have in production.
To make a Base Preview through the UI, click on “Settings” for the Preview to promote it a Base Preview. Using the command line, we need to “update” the Preview and define an anchor point (see what we did there, how nautical of us).
To promote a Preview to a Base Preview:
Now, subsequent builds will start from this newly defined Base Preview.
At this point, make a new branch to continue working on your Tugboat build script. That branch will inherit the Base Preview you created as the starting point. And anytime you make a build or a rebuild from that new branch, you’ll notice a couple of things from the CLI output:
The extra effort of setting up a Base Preview can end up shaving hours off of build times when working with huge file assets, such as large databases and the like. All that data has been saved in the Base Preview and doesn’t need to be reimported. Time is money, friends, and waiting for builds is utterly mind-numbing.
Remember, these are ephemeral environments. If the commands are not in the YAML config, your data will not be remembered. When you have working lines, add them to your config and commit them back to your repository. When you delete a Preview, everything you worked on will be gone unless scripted. This is an essential best practice for automation and sometimes an easy one to forget.
Look, the most challenging part of automation is getting started. But putting in the effort now means everyone on your team has consistent and fully isolated environments to work and test in. It means you can make the entire development process visual and collaborative, and your whole team benefits. It’s worth it, you’ll get there, and we are here to help!
You don’t have to do it alone. Sometimes it’s hard to ask for help. We have a small community of engineers and customers who help each other get our automation scripts in place. Stop on by and say ahoy!
Tell us about your project, schedule a demo, or consult with a Tugboat Technical Account Executive.