Auto deploying my website using Travis CI
Since I set up this blog, I wanted two things: owning my data and remove any unnecessary manual operation. Using Jekyll, I already achieved the former. Let’s achieve the latter in 50 lines of code.
While figuring things out, I decided to document my solution, so that others could do the same, without the burden part.
Continuous Deployment
Continuous Deployment is the practice of deploying small changes frequently — rather than deploying a big change at the end of a development cycle. For example, GitHub deploys into production about 80 times a day.
The goal is to build healthier software by developing and testing in smaller increments. The same apply to content delivering.
Say hi to Travis
Travis CI is a free Continuous Integration service for building, testing and deploying your GitHub projects. The service is free for open source repositories.
Travis allows us to have reproducible and clean builds, notifications, conditionals and a lot more. This is exactly what I want.
Workflow
Our workflow will be simple, a single job with several phases.
- Configuring the job
- Installing the dependencies
- Building the site
- Deploying
Configure
To tell Travis CI what to do, we have to declare a .travis.yml
file. Begin to fill it with the following content.
This is quite self-explanatory. We want to use macOS, our project is Ruby based and we wish to have email notifications. That our environment.
The first phase also takes place, before installing our dependencies, we make our Gems up-to-date.
Install
Next up, we install the dependencies.
Build
In this phase, we build our website.
First, we declare a new type of environment variable. This one is located inside the .travis.yml
file, because there is no sensitive information. JEKYLL_ENV
is a Jekyll variable, JEKYLL_CONF
and LOCAL_FOLDER
are ones of mine.
Coming next, the generation of the blog.
I don’t have tests (yet), but I could have run them in the before_script
phase, for example. If they’d fail, my job would also fail. The build and deploy phases would not occur.
At the moment I use HTMLProofer to check the HTML validity (links, etc.).
$REMOTE_FOLDER
is an environment variable.
Deploy
We are at the core of the job. Our content is ready, we need to deliver it onto our web server.
Travis offers a plethora of deployment strategies, to numerous providers like AWS or Heroku. But I want to deploy to my own provider, using rsync
through SSH. Fortunately, Travis provides features we can use to achieve that.
Using SSH implies having the private key available in the Travis build. But we don’t want having this highly sensitive information in the GitHub repository. Well, not in that form. So first, we need to encrypt the private key to make it readable only by Travis.
One-time configuration
The steps are:
- Generate a new, dedicated SSH key
- Copy the public key onto the remote SSH host (web server)
- Encrypt the private key and add it to Travis
- Commit the encrypted key in the repository
The Travis CLI utility created an encrypted version of the private key and store the decryption key as an environment variable on Travis. It also added some lines to the .yml
file which will decrypt the private key file during the build.
Job configuration
rsync
is a powerful utility for efficiently transferring files between two computers. On macOS, the utility is available through HomeBrew. The package will be installed before our workflow kicks in, at environment configuration. Don’t forget to add these two new environment variables as well.
The last step of our configuration will be composed of three phases:
- Before deployment, where we prepare the SSH configuration: we ensure the private key is decrypted and added to the build host.
- Deployment, this is where
rsync
does its part, uploading the blog into our web server, securely. I choose to only deploy themaster
branch. - After deployment, we do some house cleaning, for safety purpose, even if Travis’s builds are destroyed afterwards.
Same as before, notice the new environment variables. Add the three of them as “Repository Environment Variable”, with the proper values: $HOST
, $USERNAME
and $REMOTE_PATH
.
Wrapping up
or here for an up-to-date version.
You can now deploy automatically by pushing new content on the master branch, multiple times a day, and, avoiding any misfortune from using your own machine.
Isn’t that marvelous?
Last updated on 01st October 2019