About two weeks ago, one of my coworker recommended me Hugo to me. I immediately like it and chose to start my blog again with it as my blogging engine. After some reading and experiments I finally set it up and was able to:

I will walk through how I set up hugo and share some tricks I found in this post.

Table of Contents

Why these componets?

Let’s talk about why I chose Hugo, Tranquilpeak, Firebase Hosting, and Gitlab.

Hugo

  • supports Markdown (very important)
  • compiles content statically (fast when viewing the content)
  • supports local server (so that you can preview the result locally and host the site anywhere)
  • has many plugins and themes (you choose how your site looks)

Firebase Hosting

I started with Github Pages but ended up with Firebase Hosting. I also thought about Amazon S3, but it’s only free for first 12 months. (see pricing)

Firebase Hosting has these adavatages:

  • Free for Spark level (1GB storage and 10GB bandwith per month)
  • Supports custom domain and SSL
  • Built-in CDN worldwide
  • Has Firebase Tools to help you upload content via command line

Tranquilpeak

  • Fully responsive
  • Supports Google Analytics
  • A beatiful about panel (nice for personal blogs)
  • Github syntax highlighting
  • Excerpt and Table of Contents

Gitlab

  • Unlimited private repos
  • Native supported CI with pipeline and docker
  • A very transparent company. lol (see this)

Setup your site step by step

Basic Hugo

I followed this toturial Hugo Quickstart Guide, and it’s pretty basic and comprehensive for setting up the new site.

Short version:

# install hugo
brew update && brew install hugo

# create a new site
hugo new site <name of your new site>

# create a new content under post/ folder
hugo new post/<name of the post>.md

# clone the desired theme
cd themes; git clone <url to your theme>

# modify the hugo configuration
atom config.toml

Tricks here are:

  • your content will not show up if you don’t specify the theme
  • images may not display properly if your baseURL is not set correctly

Tranquilpeak theme

You can reference the sample config.toml from the github to setup the theme.

Some notes:

  • you must configure the side menu first to see the site properly
  • the Disqus panel will not show up at your local machine
  • the background image of menu is set by attribute coverImage and it can be a full http URL

Firebase Hosting

After writing your content you can preview the output locally by using hugo server -t <name-of-theme> and then browse to http://localhost:1313

If you are happy with result you can compile the content using hugo -t <name-of-theme> and the compiled content will be generated in public folder.

Now it’s the time to setup Firebase.

Create a new project

Log into Firebase Console and create a new project.

create new project

Install Firebase CLI Tools

The firebase tools allows us to upload content directly via command line so that we can easily automate the process.

To install the tools, enter the following command:

# Node JS is required, install it first if you don't have it yet
# You can use homebrew or download the installer from the official site https://nodejs.org

npm install -g firebase-tools

# check firebase tools version
Eric-Lin:~ eric.lin$ firebase -V
3.2.2

Initialize project directory

Just like git repositories, firebase projects have to be initialized before you can deploy (upload) the content.

You can simply type firebase init to initialize the directory. It will ask you some questions regarding your project, you can configure it differently or just use the default values.

Remeber to use public diretory as the public directly since hugo generates content in that directory too.

Eric-Lin:tmp eric.lin$ firebase init

     🔥🔥🔥🔥🔥🔥🔥🔥 🔥🔥🔥🔥 🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥 🔥🔥🔥🔥🔥🔥🔥🔥     🔥🔥🔥     🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥
     🔥🔥        🔥🔥  🔥🔥     🔥🔥 🔥🔥       🔥🔥     🔥🔥  🔥🔥   🔥🔥  🔥🔥       🔥🔥
     🔥🔥🔥🔥🔥🔥    🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥   🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥
     🔥🔥        🔥🔥  🔥🔥    🔥🔥  🔥🔥       🔥🔥     🔥🔥 🔥🔥     🔥🔥       🔥🔥 🔥🔥
     🔥🔥       🔥🔥🔥🔥 🔥🔥     🔥🔥 🔥🔥🔥🔥🔥🔥🔥🔥 🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥     🔥🔥  🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥

You're about to initialize a Firebase project in this directory:

  /Users/hugo-project

Before we get started, keep in mind:

  * You are currently outside your home directory

? What Firebase CLI features do you want to setup for this folder? Hosting: Configure and deploy Fireba
se Hosting sites

=== Project Setup

First, let's associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add,
but for now we'll just set up a default project.

? What Firebase project do you want to associate as default? [don't setup a default project]

=== Hosting Setup

Your public directory is the folder (relative to your project directory) that
will contain Hosting assets to be uploaded with firebase deploy. If you
have a build process for your assets, use your build's output directory.

? What do you want to use as your public directory? public
? Configure as a single-page app (rewrite all urls to /index.html)? No
✔  Wrote public/404.html
✔  Wrote public/index.html

i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...

✔  Firebase initialization complete!

The init command will generate a firebase.json similar to

{
  "hosting": {
    "public": "public"
  }
}

Make sure you commit this file into your repository. Otherwise you might have to intialize the project everytime you want to use firebase.

Deploy Content

Once you review your content and compile your content locally, you can deploy the site to firebase using firebase deploy. But before you can actually do so, you need to login to firebase by firebase login. It will ask you for username and password.

21:18 $ firebase login
Already logged in as nohitme@gmail.com
✔ ~/git/ask-hugo-sources [feature/001 L|✚ 1…1]
21:18 $ firebase deploy

=== Deploying to 'ask-eric'...

i  deploying hosting
✔  database: rules ready to deploy.
i  hosting: preparing public directory for upload...
Uploading: [=                                       ] 2%✔  hosting: public folder uploaded successfully
✔  hosting: 45 files uploaded successfully
i  starting release process (may take several minutes)...

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/ask-eric/overview
Hosting URL: https://ask-eric.firebaseapp.com

Configure Gitlab CI

Gitlab provides shared CI runners for all repositories including your private repos! You can read the full documentation to learn how to configure CI.

But for our use case, you can reference my .gitlab-ci.yml:

variables:
    GIT_SUBMODULE_STRATEGY: recursive
    GIT_SSL_NO_VERIFY: "true"

stages:
    - deploy

deploy:
    stage: deploy
    image: nohitme/hugo-firebase
    script:
        # build site
        - cd ${CI_PROJECT_DIR}
        - hugo --theme=hugo-tranquilpeak-theme
        # upload
        - firebase deploy --token ${FIREBASE_TOKEN}
    only:
        - master

Some notes here:

  1. GIT_SUBMODULE_STRATEGY is required if you use submodule to clone the latest theme from other git repo.
  2. GIT_SSL_NO_VERIFY has to be true if you try to clone other repository from anywhere other than gitlab itself (i.e. github)
  3. image: nohitme/hugo-firebase this is the docker image I created. It has both hugo and firebase tools installed so that I can compile and deploy content directly. Feel free to use it.
  4. FIREBASE_TOKEN is the token you will need to generate via firebase tool and assign this variable into gitlab before you run the job.
  5. only: - master is to ask CI to run only on /master branch

Generate FIREBASE_TOKEN

To generate the token, you type firebase login:ci

21:42 $ firebase login:ci

Visit this URL on any device to log in:
https://accounts.google.com/o/oauth2/auth?client_id=563584335869-fgrhgmd47bqnekij5i8b5pr03ho849e6.apps.googleusercontent.com&scope=email%20openid%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloudplatformprojects.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Ffirebase&response_type=code&state=1038956293&redirect_uri=http%3A%2F%2Flocalhost%3A9005

Waiting for authentication...

✔  Success! Use this token to login on a CI server:

<your token will be shown here>

Example: firebase deploy --token "$FIREBASE_TOKEN"

To assign this token in gitlab CI’s environment variable:

Login to gitlab and click settings -> variables

variables

Enter the name and value of the variable

key-value

At this point, you shoule be able to push changes to /master branch and see your deployment automatically!

Conclusion

I think so far Hugo has been fun and the best personally blogging tool in my opinion. It has many documentation and online tutorials. It is also being actively supported in terms of development and themes. Also gitlab and firebase make the deployment easy and fast. Hopefully this tutorial can help you set of your personal site easily and quickly too!