Setting Up a Personal Website/Blog For First Time Users of Jekyll
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
Modified my navigation links
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:
- Go to your project settings by clicking on the gear icon in the top right of the left bar at the project’s header
- Under Build Settings, select Environment Variables
-
Add 3 environment variables:
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- AWS_REGION
- Re-run the failed build and make sure these are working
Assuming you have everything configured properly, this should “just work”!