As you may already know, Windows is my preferred operating system. Ever since Windows 10, the UI has been super slick and Microsoft as a company has been making moves in the right direction.
It used to be an issue for us, developers, to be able to get work done, but now that we have virtualization, Docker, and Windows Subsystem for Linux that’s no longer an issue.
This blog was initially written to be used with Ghost, but I found that managing a Ghost service was way too much overhead for what I wanted to accomplish. I never ever wrote anything and spent most of my time tweaking the darned thing (hence the reason this is the second post). However, because it was just Node.js, it was fairly trivial to run on Windows. Still, I wanted out and that’s when I turned to Jekyll.
Ruby on Windows
Right off the bat, I hit a wall trying to get Jekyll to work on my machine. Installing Ruby is no longer an issue with package managers like Chocolatey, yet installing some of the gem packages require the Ruby development libraries to be built so setting up an environment that I could work with was turning out to be challenging.
In the past, I’ve been a big fan of Vagrant, but as I kept using Vagrant I started creating an explosion of VMs that small things. Usually that’s not an issue, but then disk space starts to run out. Fortunately, there’s an alternative – Docker!
Jekyll Docker Container
Thanks to the community around Docker, one can go to Docker Hub and quickly search for a container that does includes the technology you’re seeking to use, in this case it’s “Jekyll”.
I was able to locate the Jekyll Docker Github repository, which points to three available Jekyll images:
jekyll/jekyll
: Default image.jekyll/minimal
: Very minimal image.jekyll/build
: Includes tools.
The minimal build only contains Jekyll which is good, but some of the dependencies in my Gemfile
require that I have the Ruby development libraries available, which aren’t included with the minimal Docker container. These libraries are in the default image. So we’ll stick to using that one. The build image contains other dependencies that we will not be using.
Creating a Jekyll Blog
Before we get started, Docker for Windows must be installed with access to the drive that will contain the blog source.
Let’s get started by cd
ing into the directory in which we want to create the blog, then let’s run the container with a few flags:
docker run --rm -it --name jk -p 4000:4000 -e POLLING=true -v %cd%:/srv/jekyll jekyll/jekyll:3.5.0 bash
Let’s dissect this command:
--rm
will remove the container when stopped, stopped containers remain on disk if not removed-it
run the Docker container in interactive mode--name
sets a name for the container instead of having Docker create a name for us-p 4000:4000
binds host port to container port, so that we can view the blog locally-e POLLING=true
enables force polling on Jekyll- More on this on the Caveats section of Docker Jekyll
-v ...
binds%cd%
to/srv/jekyll
%cd%
is the way Windows gives you the current working directory/srv/jekyll
is the default directory used by the container
jekyll/jekyll:3.5.0
the name of the container that we’ll be creating an image for along with the versionbash
the command that the container should run when created
These are quite a few flags, but it’s much more tenable than having to create a Jekyll environment on Windows.
Now that you have a bash
shell in the Jekyll container, we can start executing commands, so let’s create a Jekyll blog and serve it:
> jekyll new .
Running bundle install in /srv/jekyll...
...
New jekyll site installed in /srv/jekyll.
> jekyll serve
Configuration file: /srv/jekyll/_config.yml
Configuration file: /srv/jekyll/_config.yml
Source: /srv/jekyll
Destination: /srv/jekyll/_site
Incremental build: disabled. Enable with --incremental
Generating...
done in 0.945 seconds.
Auto-regeneration: enabled for '/srv/jekyll'
Configuration file: /srv/jekyll/_config.yml
Server address: http://0.0.0.0:4000/
Server running... press ctrl-c to stop.
This should create a blog from a template and serve it on http://localhost:4000. Since we bound the port in the container to our host machine, we should have no issues opening the link in our browser.
That’s it!
You can go ahead and open the _posts
directory on Windows using your favorite editor and edit away!
On a separate post, I’ll go over deployment to an S3 bucket using s3_website
.
Bonus: Live Reload!
Even with POLLING
enabled, you’ll notice that when you edit a file, you’ll still need to reload your browser to see any changes. For a much more enjoyable experience we can use BrowserSync. On a separate command line session run:
> browser-sync start -s %cd%\_site -f %cd%\_site --reload-delay 300 --no-open
[BS] Access URLs:
----------------------------------
Local: http://localhost:3000
External: http://10.0.75.1:3000
----------------------------------
UI: http://localhost:3001
UI External: http://10.0.75.1:3001
----------------------------------
[BS] Serving files from: C:\Users\jvtrigueros\workspace\blog.jvtrigueros.com\src\_site
[BS] Watching files...
This will create another server that will listen on changes on the _site
directory and reload after 300 ms of a change. So instead of visiting the blog on port 4000, you should instead go to http://localhost:3000.