Wrapcode

Build Jekyll site, deploy to Firebase with Travis CI

| 10 min read

Jekyll and Github pages, a match made in heaven

I had a very old unused domain name lying around and I did not really know what to do with it. I didn't want to spend money on hosting just for hosting a site which will not be updated / changed that frequently. For some reason, I wanted it to be a static website with a little power to it. Jekyll was the first thing in my mind. Jekyll with Github Pages is just AWESOME however a techie inside me always want to have little control over things . With Github Pages and Jekyll, I found few limitations as per my need.

Then why Firebase?

Here's why I chose Firebase over Github Pages.

  1. No out of the box free SSL
  2. GH pages are little slower than Firebase.
  3. Google CDN. It is fast .
  4. Firebase  is awesome .
  5. Because we can.

This is how the process roughly looks like -

2017 05 29 18 41 17 Presentation1 PowerPoint

So let's build a Jekyll site which gets built and auto deployed upon commit.

Prerequistics

Following things are required (at least on Windows). I have provided links for download.

 

Setting up Jekyll

Before moving ahead, let's see how we can set up Jekyll blog. I am covering steps required for Windows platform but you can easily find steps for other platforms online.

  • Assuming you have installed **Chocolatey, **run following commands. These commands will fetch bundles required for Jekyll. -

choco install ruby -y
gem install bundler
gem install jekyll

 

  • Go to location where you want to create a new instance of Jekyll blog, in my case it is D:/jekyll/.
  • Open command prompt or PowerShell window and type this command

> jekyll new my-site (you can replace my-site with your project name)

2017 06 09 20 25 58 my site

  • This will create a my-site folder under provided path. 2017 06 09 20 26 22 my site
  • Jekyll comes with it's own development server. Use command jekyll serve to preview generated site. The console output will provide you with the address where the site is hosted. 2017 06 09 20 31 01 Windows PowerShell
  • Notice that it creates a folder called "_site" after you run command jekyll serve. Jekyll serve internally use jekyll build command which generates the static site which is ready to be deployed. We are going to treat this _site folder as public folder for Firebase hosting.

If you can see the jekyll site on provided server address. Congrats! You have a jekyll site up and running on your local machine. Next step is to set up Firebase project

Creating and configuring Firebase project

Now, we need to add a firebase configuration which will let TravisCI know the desired public path for Jekyll site. Before doing that, we need to create a Firebase project.

  • Go to http://firebase.google.com
  • Click on Add Project and provide a name and a region.
  • For this article, I am creating a project called my-jekyll-site.

Now let's go back to our local jekyll site folder. We will install Firebase CLI. Firebase CLI can be used to deploy code and assets to our firebase projects, preview firebase websites locally or even interact with database from our development machine.

As we are relying on Travis CI, we are using Firebase CLI only to create a basic configuration file.

  • Open command prompt (anywhere but preferably under project folder) and run this command -

> npm install -g firebase-tools

  • For Firebase CLI to be able to access your projects, you need to log in through CLI. Use following command to log in

> firebase login

  • We will be redirected to a login page. Firebase app will ask for user consent. Click Allow. After granting those permissions, you will be logged in. Just go back to Powershell or command prompt. 2017 06 09 20 55 59 Sign in Google Accounts
  • Once logged in, we can initialize the Firebase project under jekyll directory (root directory i.e. D:\jekyll\my-site)
  • Run command to initialize firebase project -

> firebase init

  • Aha, we get welcomed with nice looking console message. Enter Y to proceed. 2017 06 09 21 03 30 Windows PowerShell
  • Navigate to Hosting by pressing down arrow key and press space bar key to select it. 2017 06 09 21 04 23 Windows PowerShell
  • Now we will select the project that we just created in Firebase web console. 2017 06 09 21 05 51 Windows PowerShell
  • Once we select the project, CLI will ask us to chose public folder. Type in "_site" without quotes.
  • Configure as a single-page app (rewrite all urls to /index.html)? - Press Y
  • File site/index.html already exists. Overwrite? - Press N **(Important - We do not want to overwrite jekyll generated index.html)** ![](2017-06-09-2114_56-Windows-PowerShell-1.png)

The steps above create two files under root folder of jekyll site named firebase.json and .firebaserc. The file firebase.json contains information about public folder, route rewrites whereas .firebaserc holds information about firebase project -

{
"hosting": {
"public": "_site",
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
view raw firebase.json hosted with ❤ by GitHub

Now, we are all set with Firebase configuration. Wasn't that easy? Firebase CLI has made life very easy .

Now just for fun, try running command "firebase deploy". This will auto deploy your site to Firebase and you can see it live on the provided Hosting URL -

2017 06 09 21 25 11 Windows PowerShell

This is super cool. However, we don't want to run the commands manually every time we write something down. Ideally, I would want to write a markdown and commit and forget about publishing part. Travis CI comes in picture here. We want to trigger it on every git commit.

We have the Jekyll source ready. Let's move it to GitHub. As a software programmer and a part time blogger, I like to maintain history of all the changes overtime. I find Github the best place for our jekyll site content to rest. Why? Github has wide variety of third party connectors to automate the build processes. Travis CI is one of them.

Moving Jekyll source to Github

Some of the reasons why I prefer it to be under source control, especially Github.

  1. Jekyll is widely used for public facing website e.g. blog. A public facing website does not require a private repository ;-)
  2. Hard drives on local machine are prone to failure and we do not back them up quite frequently.
  3. We want an ability to roll back if mishap happens.
  4. We may want to correct old articles in markdown and republish them.
  5. Huge number of third party connectors for CI and CD. TravisCI being one of them.

We already have git installed on our local machine. Below steps will move our Jekyll source to Github Repository

  • Create a github repository. I have created https://github.com/r4hulp/my-jekyll-site for this article
  • Go to Jekyll site root (D:\jekyll\my-site)
  • Open Command Prompt or Git bash and run following commands -

git init
git add .
git commit -m "First commit"
git remote add origin {remote_repository_url}
git remote -v
git push origin master
view raw Jekyll-to-Github.bat hosted with ❤ by GitHub

(Replace {remoterepositoryurl} with github repository url)

  • We have the Jekyll site source pushed to Github repository.

We can now move ahead and start configuring Travis CI.

Delivering Jekyll build to Firebase using TravisCI

So far we have covered two steps from our earlier process chart.

Now comes an interesting part. We will use TravisCI to build and deploy Jekyll site to Firebase.

  • Log in to TravisCI with Github
  • Go to profile and flip the switch of the Jekyll repository 2017 06 09 22 18 08 Rahul Patil Profile Travis CI
  • Once you flip the switch, the repository is ready to be configured.

Configuring Travis build script

Travis uses YAML script which is very easy to understand. Once you flip the switch and make the repository available for build triggers. Travis will look for travis.yml file under provided repository. The travis.yml file contains all the required commands to install dependencies and build Jekyll site. I have prepared the script which is fairly easy to understand. We will just copy it in our Jekyll site source.

#use node_js
language: node_js
#define node js version to use
node_js:
- "7"
#choose branch on commit of which this script should excecute
branches:
only:
- master
#set notifications frequency
notifications:
email:
on_success: never
on_failure : change
before_install:
#install rvm 2.2
- rvm install 2.2
#use rvm 2.2
- rvm use 2.2
#set home varaibles
- . $HOME/.nvm/nvm.sh && nvm install 6.1 && nvm use 6.1
#install gems through bundler
- gem install bundler
#if gems are missing this script will get the missing gems.
- bundle check || bundle install
install:
#install firebase tools, required to deploy on firebase hosting
- npm install -g firebase-tools
# Assume bundler is being used, therefore
# the `install` step will run `bundle install` by default.
script:
#continue even after error
- set -e
#build jekyll site
- jekyll build
after_success:
#deploy to firebase using stored token.
- firebase deploy --token "$FIREBASE_API_TOKEN"
env:
global:
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true # speeds up installation of html-proofer
sudo: false # route your build to the container-based infrastructure for a faster build
#Visit article at - http://wrapcode.com
#Cheers, Rahul.
view raw travis.yml hosted with ❤ by GitHub

While this script is quite explanatory. I will try to explain what it does.

  1. It installs ruby 2.2 using RVM and bundler using gem before building.
  2. Command bundle check || bundle install makes sure the environment has all the dependencies installed. If not, bundle install makes sure that it gathers all the dependencies before we move ahead.
  3. The command jekyll build builds the site. Basically converts markdown posts, configuration to html, css static web page. All these pages and assets are stored in _site folder as expected.
  4. As we have configured _site **as public folder in our firebase.json earlier, we can directly run firebase deploy **command with access token (we'll come to this in a moment) which will deploy the site to Firebase hosting.

Now we need to add this file to Github repository. Following git commands will add the file to repository.

git add .
git commit -m "added travis.yml"
git push origin master

This will add the provided travis file to git

Generating Firebase Token

We always have a logged in user on our local machine. Firebase CLI manages to store the context of logged in user. However, the build agents are containers and they get recreated every time a build triggers.There is no definite way to store the user context. Fortunately, Firebase CLI has given us an option to use tokens for deployments. Once generated, these tokens can be used as secret keys for deployment. These are specifically made for CI purpose. To generate Firebase Token, you need to go to your project root folder on your local machine and run this command -

> firebase login:ci

This will redirect user to browser and we will be asked to log in and grant the permissions. Once we are logged in we will see below message in console.

2017 06 09 22 38 35 Firebase CLI

You have got the token. But wondering where to store it? Obviously you can not keep it in plain sight in build script. We will use Travis environment variables to store the CI token.

Creating environment variable for repository

  • TravisCI dashboard should show us the repository. Hover over three dashes and click on Settings. 2017 06 09 22 48 29 Travis CI Test and Deploy Your Code with Confidence
  • Under environment variables. Provide following values - Name : FIREBASEAPITOKEN (if you want to changes this, make sure you change the variable name in build script) Value : CI Token you generated above 2017 06 09 22 55 44 Settings rahulrulez my jekyll site Travis CI
  • Make sure you turn off "Display value in build log" to avoid leaking secret token if your repository is public. Otherwise you may end up exposing your site end point.

Now try triggering the build. The build should pass with a success message.

 

That's it. You have configured the later two stages of the build process. This is how the continuous delivery will work -

  1. Clone the github repo to local system.
  2. Use Markdown editor to write new articles / posts under **_posts **folder. Jekyll documentation on writing -  https://jekyllrb.com/docs/posts/
  3. Add file and commit
  4. Go, grab a coffee  and wait for your article to be published on your spanking new Firebase site.

 

Source code and site -

Github source code - https://github.com/r4hulp/my-jekyll-site

Travis CI - https://travis-ci.org/r4hulp/my-jekyll-site

Next steps