DEV Community

Michael Lee πŸ•
Michael Lee πŸ•

Posted on

Compile a Jekyll project without installing Jekyll or Ruby by using Docker

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:3.8 jekyll build
Enter fullscreen mode Exit fullscreen mode

What this command does is:

  • --rm automatically removes the container when it exits
  • --volume="$PWD:/srv/jekyll" takes the current directory indicated by $PWD and map it to the directory at /srv/jekyll within 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/bundle and 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=production in 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_ENV to production
  • jekyll/jekyll:3.8 this tells it to use the jekyll:3.8 tagged version of the Jekyll container
  • jekyll build runs 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:3.8' locally
3.8: Pulling from jekyll/jekyll
e7c96db7181b: Pull complete
622c94c90cb1: Pull complete
5ab26e9d8a17: Pull complete
830997f3d72a: Pull complete
1956a4eaab3f: Pull complete
36a9759f9f2f: Pull complete
Digest: sha256:deb267df3f6c2b7604b0d5a5aabcb394eec1452a053e4297cf2fb13b125e0bcf
Status: Downloaded newer image for jekyll/jekyll:3.8
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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 .gitignore file.

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:3.8 jekyll serve
Enter fullscreen mode Exit fullscreen mode

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.3p62 (2019-04-16 revision 67580) [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.
Enter fullscreen mode Exit fullscreen mode

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.

β€”β€”β€”-

Thanks for taking the time to read this article! I'd love to send you more tips on programming through my newsletter. Click here to sign up.

Top comments (8)

Collapse
 
hyzyla profile image
Yevhenii Hyzyla

docker-compose setup for jekyll

version: '3'

services:
  site:
    image: jekyll/jekyll:3.8.6
    command: jekyll serve --livereload --verbose
    ports:
      - 4000:4000
    volumes:
      - .:/srv/jekyll
      - ./vendor/bundle:/usr/local/bundle

Enter fullscreen mode Exit fullscreen mode
Collapse
 
preslavrachev profile image
Preslav Rachev

As someone who has had to install the Ruby / Gem / Jekyll stack quite a few times in the past, I know the pain. There were always things that did not quite work out, and they caused hours of looking up cryptic messages in the Internet. Putting everything into a Docker image will guarantee consistency across setups and no need to always set up multiple versions. Just pull the Docker image and create a container that runs your build. There will no longer be version conflicts or consistency issues, due to the isolation at the container level.

Collapse
 
michael profile image
Michael Lee πŸ•

I agree with everything you said Preslav. Discovering that the whole process could be consistent and more predictable was a powerful realization. Hopefully this makes barrier to entry a lot lower as well. I know the first time I tried to get Jekyll running on my machine. It felt so foreign to me.

Collapse
 
tuananh_org profile image
Tuan Anh Tran • Edited

i already map volume but it's still fetching rubygems every time

--volume="/home/username/Code/myblog/vendor/bundle:/usr/local/bundle"
Enter fullscreen mode Exit fullscreen mode

still got this

Fetching gem metadata from http://rubygems.org/..
Enter fullscreen mode Exit fullscreen mode

any idea what i did wrong / missing here?

Collapse
 
aleon1220 profile image
Andres Leon

Your post truly helped me a lot. Thanks so much.

Collapse
 
michael profile image
Michael Lee πŸ•

That's awesome @aleon1220 ! I'm glad to hear it :)

Collapse
 
ssurineni profile image
sampath kumar

Thank you for the post. Installing Jekyll is really big trouble.

Collapse
 
michael profile image
Michael Lee πŸ•

Glad you found this helpful @ssurineni !