My current choice for running my site is Jekyll, a static-site generator written in Ruby. Since I ditched Wordpress back in 2013, I’ve been using Jekyll exclusively. It is a lot easier to get up and running on Jekyll instead of setting up Wordpress, it does still have some road blocks in getting it up and running.
Since 2013, there’s been numerous times that I’ve had to set up a new computer, which meant getting Jekyll up and running from scratch. That usually means installing Homebrew, rbenv, Ruby and then Jekyll and crossing my fingers and hoping that everything runs the first time. Not to mention also getting git configured so that I could commit back to the Github repo that has all the files for the site.
Last week I started taking another look at Docker. Docker is a technology that lets you run your application in containers all from a configuration file. This is mighty powerful because it allows you to avoid the old dev adage of, “It worked on my computer”.
With Docker I discovered that I could compile or even serve my Jekyll site locally without going through the entire fuss of getting Jekyll up and running on my local machine. Although you don’t have to install any Jekyll dependencies, there is the need to install Docker to get Docker running. But I’ve found it really straightforward because they provide an app which provides the CLI and setup.
Building your Jekyll project with Docker
Once Docker is installed and set up on your machine, you can build your Jekyll project by running this command from the command line within the project folder,
docker run --rm -it --volume="$PWD:/srv/jekyll" --volume="$PWD/vendor/bundle:/usr/local/bundle" --env JEKYLL_ENV=production jekyll/jekyll:4.0 jekyll build
What this command does is:
--rmautomatically removes the container when it exits
--volume="$PWD:/srv/jekyll"takes the current directory indicated by
$PWDand map it to the directory at
/srv/jekyllwithin the container so that it could build it
--volume="$PWD/vendor/bundle:/usr/local/bundle"this option maps the contents of the current directory’s
/vendor/bundleand maps it to
/usr/local/bundle. The reason for this option is so that gems could be cached and reused in future builds
--env JEKYLL_ENV=productionin various parts of my Jekyll project, I’ve designated for it to only render if it’s for production. For example analytics shouldn’t be muddied up by my local development. This sets the environment variable for
jekyll/jekyll:4.0this tells it to use the
jekyll:4.0tagged version of the Jekyll container
jekyll buildruns the build command for Jekyll
If you’re running this command for the first time, the image for this container won’t be on your system, so it’ll grab it from the Docker registry first before it runs the container.
Unable to find image 'jekyll/jekyll:4.0' locally 4.0: Pulling from jekyll/jekyll 9d48c3bd43c5: Pull complete 9ce9598067e7: Pull complete 278f4c997324: Pull complete 867dd521f6d0: Pull complete c69cba5b7867: Pull complete 828c8f2de574: Pull complete Digest: sha256:d1bf33637d476e3cb2d5858038673cc93bc961e9390d31171d9febde5c5d24fd Status: Downloaded newer image for jekyll/jekyll:4.0
One thing I ran into was this warning,
Error: could not read file /srv/jekyll/vendor/bundle/gems/jekyll-3.8.5/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb: Invalid date '<%= Time.now.strftime('%Y-%m-%d %H:%M:%S %z') %>': Document 'vendor/bundle/gems/jekyll-3.8.5/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb' does not have a valid date in the YAML front matter. ERROR: YOUR SITE COULD NOT BE BUILT: ------------------------------------ Invalid date '<%= Time.now.strftime('%Y-%m-%d %H:%M:%S %z') %>': Document 'vendor/bundle/gems/jekyll-3.8.5/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb' does not have a valid date in the YAML front matter.
To fix this I had to modify my project’s
_config.yml file. Within your project if you’ve got an
excluded section defined, add
vendor to it.
exclude: - "package.json" - "README.md" - "publish.sh" - "vendor"
Now running the
docker run command from above should work and you should see your site built within the
_site folder within your project. If you’ve got your project versioned with
git it’s probably also a good idea to now add the
vendor folder to your
Serving your Jekyll project with Docker
Instead of compiling if you’d like to instead serve your Jekyll site to do some local development, you can also do that using Docker by running this command,
docker run --rm --volume="$PWD:/srv/jekyll" --volume="$PWD/vendor/bundle:/usr/local/bundle" --env JEKYLL_ENV=development -p 4000:4000 jekyll/jekyll:4.0 jekyll serve
The only difference between the
serve command versus the
build command above is that I pass it an environment variable of
JEKYLL_ENV=development, as I mentioned this is because I have certain sections of my site set up to build only in a production environment.
Upon running the command above, you’ll see the same output as if you had Jekyll locally installed on your computer,
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux-musl] Configuration file: /srv/jekyll/_config.yml Source: /srv/jekyll Destination: /srv/jekyll/_site Incremental build: disabled. Enable with --incremental Generating... done in 19.698 seconds. Auto-regeneration: enabled for '/srv/jekyll' Server address: http://0.0.0.0:4000/ Server running... press ctrl-c to stop.
Only difference is now, your Jekyll project is being generated and served from the Docker container and you can point your browser to
localhost:4000 and see the Docker served site.