Setting Up a Personal Website/Blog For First Time Users of Jekyll

7 minute read

Context

Over the years I have built various versions of my personal website from scratch. This got easier with the introduction of Bootstrap and other CSS/js frameworks. As a developer, I’ve resisted using out of the box solutions like Wordpress or Squarespace. With renewed inspiration to get a personal blog going, I came up with a solution I’m pretty happy with. In less than a day I have rebuilt the content I previously had hosted, and have an easy platform for writing new blog posts.

This is a step by step guide to get a personal site with blog post capabilities up and running using Jekyll, a template for Jekyll called Minimal Mistakes, and Circle CI for deployment.

Note: all of these steps can be found throughout the Jekyll, Minimal Mistakes, and Circle CI docs. I just pulled a quick start guide together in an all in one. If you want to do anything more custom I encourage you to utilize the original docs!

Technologies

Jekyll
A ruby framework to generate static websites. Makes creating blogs and site content easy, and is extremely customizable.
Minimal Mistakes
A robust, free, jekyll theme. The author, Michael Rose does a fantastic job with his documentation, examples, and layouts that are available. It’s beautiful and easy to get up and running. By far the best free jekyll theme I could find!
Circle CI
Continuous integration service. Used to automate deployment of static files from github to AWS s3.

Initial Setup

You can see a commit history for these steps in an example project on github.

Pre-requisites

Make sure you have a working ruby development environment.

Some hints:

  • Ruby (I use rbenv to manage my ruby versions)
  • Bundler (a ruby gem)
  • Git with SSH keys setup to Github

Install Jekyll

Simply install the gem:

gem install jekyll

I ultimately chose NOT to utilize the jekyll new <project name> command, because of how I wanted to use the minimal mistakes template.

Clone minimal-mistakes

I started by using the Gemfile installation option in a new jekyll project with minimal-mistakes, but after playing around with it some realized I am going to want to eventually customize these templates to fit my needs, and long term didn’t want to be overriding the styles and include files.

If you would like to just utilize the existing styles without much configuration, follow the instructions to configure from jekyll new and an include gem here.

# Clone the theme repository
git clone git@github.com:mmistakes/minimal-mistakes.git my_jekyll_site_example

cd my_jekyll_site_example

# Remove the unnecessary files and directories
rm -rf docs/ test/ .github/
rm .travis.yml CHANGELOG.md README.md .gitattributes .editorconfig minimal-mistakes-jekyll.gemspec screenshot-layouts.png screenshot.png Rakefile banner.js package-lock.json package.json staticman.yml

# Remove the existing git config and setup your own
rm -rf .git
git init
git add .
git commit -am "Initial commit"
git checkout -b develop
git remote add origin git@github.com:<your github username>/my_jekyll_site_example.git
git push -u origin develop # I want develop to be my default branch for working, I will use master for deployment

Initial Configuration

Modify the .config.yml file in the root of your project to reflect your personal information. (E.g. your name, email address, social links, site title, etc.)

Edit the Gemfile to look like this:

source 'https://rubygems.org'

# Hello! This is where you manage which Jekyll version is used to run.
# When you want to use a different version, change it below, save the
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
#
#     bundle exec jekyll serve
#
# This will help ensure the proper Jekyll version is running.
# Happy Jekylling!
gem 'jekyll', '~> 3.8.5'
gem 'html-proofer'

# This is the default theme for new Jekyll sites. You may change this to anything you like.
# gem 'minima', '~> 2.0'
gem 'minimal-mistakes-jekyll'

# If you want to use GitHub Pages, remove the 'gem 'jekyll' above and
# uncomment the line below. To upgrade, run `bundle update github-pages`.
# gem 'github-pages', group: :jekyll_plugins

# If you have any plugins, put them here!
group :jekyll_plugins do
  gem 'jekyll-feed', '~> 0.6'
  gem 'jekyll-paginate'
  gem 'jekyll-sitemap'
  gem 'jekyll-gist'
  gem 'jemoji'
  gem 'jekyll-include-cache'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

# Performance-booster for watching directories on Windows
gem 'wdm', '~> 0.1.0' if Gem.win_platform?

Start it up

Let’s make sure it runs locally! Install the gems, and run the server. This will be the bare bones site.

bundle install
bundle exec jekyll serve

will start your server on localhost:4000

Personalize Your Site

Update content to your site as desired. Here are a few things I did.

Update your home page

Add content to your index.html site.

Added a collection

I want to keep track of past projects I have worked on. These are not blog posts, but site pages. They have slightly different properities, and will not show up in your categories or tags pages.

Add a top level folder, in this example, mine is _projects.

Add the collection to your project config.yml:

# Collections
collections:
  projects:
    output: true
    permalink: /:collection/:path/

Don’t forget that any config change will require you to restart your webserver.

Added a _drafts folder for in-progress blog post pages

Jekyll has out of the box support for drafts. By simply adding a _drafts folder to the top level of your project, you can create content that is not published until it is moved to the _posts folder.

To see these locally, use

bundle exec jekyll serve --drafts

Edit _data/navigation.yml and edit your navigation to reflect the structure of your site you’d like.

Add a favicon

There are loads of sites that help you create a favicon for your site. Do that, then come back here. If you want to take a shortcut, just use a png with correct naming (this matters so the browser can pick it up), add it to your root folder.

Open up _includes/head/custom.html and add your favicon html there:

<!-- Quick fix and use a png instead: -->
<link rel="shortcut icon" type="image/png" href="favicon.png"/>

<!-- Or use the favicon: -->
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico" />

Deploy your site

Setup circleci config for site deployment

If you don’t already have AWS hosting your site, I encourage you to take advantage of Jekyll’s out of the box support Github Pages for your site deployment. Because I already had a static site hosted on AWS with S3, I chose to use a CI integration to automatically upload my new and changed files when I make a git commit.

Add a circle ci config file to your project

mkdir .circleci && touch .circleci/config.yml

Modify .circleci/config.yml to look like this (note there are two backslashes that need to be removed):

defaults: &defaults
  working_directory: ~/repo
version: 2.1

orbs:
  aws-s3: circleci/aws-s3@1.0.4

jobs:
  build:
    <<: *defaults
    docker:
      - image: circleci/ruby:2.5
    environment:
      BUNDLE_PATH: ~/repo/vendor/bundle
    steps:
      - checkout
      - restore_cache:
          keys:
            - rubygems-v1-{\{ checksum "Gemfile.lock" }} # ACTION: remove the backslash between the curlies
            - rubygems-v1-fallback
      - run:
          name: Install Bundler
          command: gem install bundler
      - run:
          name: Bundle Install
          command: bundle check || bundle install
      - save_cache:
          key: rubygems-v1-{\{ checksum "Gemfile.lock" }} # ACTION: remove the backslash between the curlies
          paths:
            - vendor/bundle
      - run:
          name: Jekyll build
          command: JEKYLL_ENV=production bundle exec jekyll build
      - run:
          name: HTMLProofer tests
          command: |
            bundle exec htmlproofer ./_site \
              --allow-hash-href \
              --check-favicon  \
              --check-html \
              --disable-external
      - persist_to_workspace:
          root: ./
          paths:
            - _site
  deploy:
    <<: *defaults
    docker:
      - image: circleci/python:3.6.3
    steps:
      - attach_workspace:
          at: ./
      - aws-s3/sync:
          from: ./_site
          to: 's3://<s3 bucket name>'
          arguments: |
            --acl public-read \
            --cache-control "max-age=86400"

workflows:
  version: 2.1
  build-test-deploy:
    jobs:
      - build
      - deploy:
          requires:
            - build
          filters:
            branches:
              only: master

SIDEBAR: To add html validation, add html-proofer to your Gemfile. This took me a few tries to get it to pass. (For example, make sure to add a favicon - outlined in Customizing above).

(If you want to skip this, simply comment out the HTML proofer tests step in the .circleci/config.yml)

gem 'html-proofer'

Bundle install the gem:

bundle install

Run htmlproofer locally:

bundle exec htmlproofer ./_site --allow-hash-href --check-favicon --check-html --disable-external

Fix the errors.

Setup CircleCI

Create an account (if you don’t already have one) with Circle CI

Follow your github project. It will automatically start building using the configuration file in the repo.

With the above ci file, this will only try to deploy to s3 when you are on the master branch. If you have not pushed to master yet, do so now. This will automatically trigger a build in circle ci.

Add in your AWS credentials to your project’s settings:

  1. Go to your project settings by clicking on the gear icon in the top right of the left bar at the project’s header
  2. Under Build Settings, select Environment Variables
  3. Add 3 environment variables:

    • AWS_ACCESS_KEY_ID
    • AWS_SECRET_ACCESS_KEY
    • AWS_REGION
  4. Re-run the failed build and make sure these are working

Assuming you have everything configured properly, this should “just work”!