WordPress to Jekyll part 5 - Hosting & building
- 📅
- 📝 910 words
- 🕙 5 minutes
- 📦 Development
- 🏷️ WordPress, Jekyll
The next stage is considering where to host the site and whether to use a content delivery network (CDN). My preferred approach on other sites has been to:
- Host the origin on GitHub pages — it’s fast to build and integrates with my source control
- Front it with Amazon’s AWS CloudFront CDN — it’s fast, cheap, and comes with a free SSL cert
Adding the CloudFront CDN was essential if you wanted SSL with your domain name, but GitHub pages added support for SSL certs with custom domains
Unfortunately, my blog is more complex than the other sites I’ve done, and two of the plugins I use have not been white-listed for use on GitHub pages. They are:
- paginate-v2 — required to get great tag & category support
- Algolia — needed for search indexing
Part of GitHub’s blazing speed comes from being a trusted environment. While I’m sure they’ll be white-listing paginate-v2 in the short term I’m not sure if the Algolia indexer is on the cards.
CircleCI build server
There are always plenty of options in the cloud so I looked for a build server. I’ve used AppVeyor, CodeShip and Travis CI before but decided to this time go with CircleCI as I wanted to try their new faster v2 docker-based infrastructure and take advantage of their free tier.
The v2 mechanism requires a new .circleci/config.yml
that splits the process into jobs that are combined with a workflow. I created two jobs — one for the build and another for the deploy. They are:
version: 2
jobs:
build:
docker:
- image: circleci/ruby:2.3
working_directory: ~/jekyll
environment:
- JEKYLL_ENV=production
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true
- JOB_RESULTS_PATH=run-results
steps:
- checkout
- restore_cache:
key: jekyll-{{ .Branch }}-{{ checksum "Gemfile.lock" }}
- run:
name: Install dependencies
command: bundle check --path=vendor/bundle || bundle install --path=vendor/bundle --jobs=4 --retry=3
- save_cache:
key: jekyll-{{ .Branch }}-{{ checksum "Gemfile.lock" }}
paths:
- "vendor/bundle"
- run:
name: Create results directory
command: mkdir -p $JOB_RESULTS_PATH
- run:
name: Build site
command: bundle exec jekyll build 2>&1 | tee $JOB_RESULTS_PATH/build-results.txt
- run:
name: Remove .html suffixes
command: find _site -name "*.html" -not -name "index.html" -exec rename -v 's/\.html$//' {} \;
- run:
name: Index with Algolia
command: bundle exec jekyll algolia
- store_artifacts:
path: run-results/
destination: run-results
- persist_to_workspace:
root: ~/jekyll
paths:
- _site
Origin hosting with S3
Given I’m going to use CloudFront for my CDN and that GitHub pages won’t work for this job I went with S3. I know it well, the command line tools are great, it’s cheap, fast and integrates well with CloudFront.
S3 did however bring a few problems with it’s own — primarily because the links on my blog had no file suffixes — I didn’t want either .php or .html and WordPress makes this a breeze.
Here’s my CircleCI job to deploy to S3. It involves:
- Starting with Python to get the AWS command-line tools
- Syncing the static site forcing everything as
text/html
to deal with the lack of file extensions - Fixing up the few files I have that require a different MIME type (css, feed, robots etc)
- Creating a few helpful redirects for backward compatibility with existing links in the wild
(This configuration requires you’ve setup the AWS access key and secret in Circle for the command-line tools to use.)
deploy:
docker:
- image: circleci/python:2.7
working_directory: ~/jekyll
steps:
- attach_workspace:
at: ~/jekyll
- run:
name: Install awscli
command: sudo pip install awscli
- run:
name: Deploy to S3
command: aws s3 sync _site s3://damieng-static/ --delete --content-type=text/html
- run:
name: Correct MIME for robots.txt automatically
command: aws s3 cp s3://damieng-static/robots.txt s3://damieng-static/robots.txt --metadata-directive="REPLACE"
- run:
name: Correct MIME for sitemap.xml automatically
command: aws s3 cp s3://damieng-static/sitemap.xml s3://damieng-static/sitemap.xml --metadata-directive="REPLACE"
- run:
name: Correct MIME for Atom feed manually
command: aws s3 cp s3://damieng-static/feed.xml s3://damieng-static/feed.xml --no-guess-mime-type --content-type="application/atom+xml" --metadata-directive="REPLACE"
- run:
name: Redirect /damieng for existing RSS subscribers
command: aws s3api put-object --bucket damieng-static --key "damieng" --website-redirect-location "https://damieng.com/feed.xml"
- run:
name: Correct MIME for CSS files
command: aws s3 cp s3://damieng-static/css s3://damieng-static/css --metadata-directive="REPLACE" --recursive
Tying together the build
Finally you just need a workflow to tie these two steps together at the end of your .circleci/config.yml
workflows:
version: 2
build-deploy:
jobs:
- build
- deploy:
requires:
- build
filters:
branches:
only: master
A complete version of my circle config is available.
CloudFront CDN
Adding the CloudFront CDN is pretty easy and well covered elsewhere. I’ll just point out that you must paste in the origin domain name from S3 and not choose the S3 bucket in the drop down. The latter ties CloudFront to the storage directly and ignores MIME types, redirects etc. By pasting the origin name in you’re taking advantage of the S3 WebSite features that make redirects etc. possible.
Also, while testing, you might want to specify a low TTL of say 120 (2 minutes) until things are fully stable.
[)amien
0 responses to WordPress to Jekyll part 5 - Hosting & building