We've been using Jekyll for all kinds of projects over the last five years. It's been good to us. Setting up and maintaining local installations, however, has not been the most pleasant experience. We would have remember to have the right permissions for global and user gems, execute commands by prepending
bundle exec when appropriate, and remember to update our PATH whenever we upgrade Ruby, etc. There was also the occasional system upgrade like when macOS implemented "System Integrity Protection," which required extra plumbing. It was therefore a great opportunity to improve this experience when I recently upgraded my machine.
Old Method: Local Installation
In the old days, I would install
Homebrew and use that to install
Jekyll. It seems easy enough. But those who have tried it know that one wrong command could mean having to dig through various paths to fix permissions, etc. Here are the steps I used to follow:
# Install brew. ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" # Install command line tools. xcode-select --install # Update path to use brew install. export PATH=/usr/local/bin:$PATH # Modify path for GUI apps. launchctl setenv PATH “/usr/local/bin:$PATH” # Install a sandboxed ruby with brew. brew install ruby # Tell Rubygems not install docs echo "gem: --no-ri --no-rdoc" > ~/.gemrc # Add user gem dir to your path. echo 'export PATH="~/.gem/ruby/2.6.0/bin:$PATH"' > ~/.bash_profile # Now install bundler and jekyll for current user. gem install --user-install bundler jekyll # Install bundles for existing project (ensure vendor is excluded in _config.yml). cd project/site/ bundle install --path vendor/bundle # Verify version (prepending 'bundle exec' allow us to use project-specific version) bundle exec jekyll --version
New Method: Docker
My first step was to create a Dockerfile inside a Jekyll repo and build an image from it:
FROM jekyll/jekyll:3.8 ADD . /srv/jekyll RUN jekyll build EXPOSE 4000
Building the image:
docker build -t blen_jekyll .
Running the container
docker run -d -p 4000:4000 -p 35729:35729 -it --volume="$PWD:/srv/jekyll" --name blen blen_jekyll /bin/bash
That seemed to work just fine. So the next step was to create a docker compose file and optimize our workflow by adding
--drafts options to the
serve command. Plus, we don't want to have to remember the long command for
Here is our
jekyll: image: jekyll/jekyll:3.8 command: jekyll serve --livereload --drafts ports: - 4000:4000 - 35729:35729 volumes: - .:/srv/jekyll
Now all we have to do is run
docker-compose up and point the browser to
One difference I noticed is that the regeneration and auto-reload processes take longer with Docker than when using a local installation of Jekyll. That may have something do with performance issues of volume mounts. And there may not be much we can do about that.