Containerised local development is often the way forward for small software development teams. It allows everyone to replicate the same working environment without spending ages configuring their individual systems.
This goes especially for the nowadays more uncommon languages such as Ruby - and if you’re not ready to make the leap to Hugo - running the ruby based Jekyll in Docker is a great solution for local Jekyll web-development.
First, make sure you have docker running in the background, whether via the docker engine or Docker Desktop etc.
Then, create a
docker-compose.yml file in the root of your Jekyll project with the below YAML content.
Run this docker compose file to launch a container with the official Jekyll docker image, and your Jekyll sites files.
Once the container has fully loaded, you can access it via
http://0.0.0.0:4000 and since we’re only running this locally the lack of SSL/HTTPS should be fine in most cases.
services: jekyll: image: jekyll/jekyll volumes: - .:/srv/jekyll - ./vendor/bundle/:/usr/local/bundle ports: - "4000:4000" command: jekyll serve --force_polling --drafts
Tip: If you’re using Visual Studio Code (aka VS Code, the most popular IDE at the time of writing), you can install the official Docker extension and run “Docker Compose: Up” from the “Ctrl+Shift+P” command menu. This docker extension also makes it easy to access the containers logs etc too.
Tip 2: You may also want to add the following exclude command to your Jekyll
_config.yml file, it’ll prevent the new docker-compose file from being deployed into your static site.
exclude: - docker-compose.yml
Here we’ll walk through the
docker-compose.yml config file to explain what’s going on.
This asks Docker to pull down and run the official Jekyll docker container image. You can be reasonably sure this official docker image is safe when compared to a customised docker image made by someone else.
volumes: - .:/srv/jekyll - ./vendor/bundle/:/usr/local/bundle
Here we’re asking Docker to create a live mapping from our current working directory a.k.a
/srv/jekyll which is the serving location inside of the docker container. This means that any time we update a file locally in our IDE, the changes are applied live inside the docker container also. The vendor part simply speeds up the docker setup by caching some files locally.
ports: - "4000:4000"
This one is pretty self explanatory, it asks Docker to map the container’s port
4000 to our local port
4000, allowing us to access the site in our browser on
command: jekyll serve --force_polling --drafts
This is the
serve jekyll command that you may be used to when working with jekyll. It builds the site and serves it live via a mini built-in web-server. It’ll also watch for changes in your files and rebuild the site live after each change (excluding the
_config.yml file). After changing a file, all you need to do is reload the browser page.
--force_polling simply forces jekyll to watch for file changes that would not usually be passed through docker in the same way they would be locally. This is a small quirk of running
jekyll serve in a container like this.
--drafts flag asked Jekyll to include any posts under
_drafts in the development site as if they were real posts, handy for previewing drafts locally before committing.