These are some posts from the old Meat and Networking blog. They're archived here for posterity, for random search traffic that might come rolling by.
get in touch
(But I’m not really tweeting much these days)
Jekyll, Docker, and Nginx Reverse Proxy for Static Blogs
I have no self control, so last week I bough https://www.reenginee.red/. I’m probably going to use it as a home for some sustainable energy/micro-grid/open hardware projects.
Here’s what I started out with:
- A DigitalOcean droplet running Docker (hosting this site, too, actually!)
- With docker-compose for bringing up multiple coordinated services!
- Nginx-Proxy (https://github.com/jwilder/nginx-proxy)
- LetsEncrypt Companion for Nginx-Proxy (https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion)
- The official Jekyll Docker image (https://github.com/envygeeks/jekyll-docker/blob/master/README.md)
- The 101 level Jekyll documentation (https://jekyllrb.com/docs/)
Here’s the docker-compose.yml the Jekyll Docker image recommends:
What are all the ports for? Digging into the Jekyll docs, it’s fairly simple to find that:
- 4000 is the default port that Jekyll uses to serve pages via the
- 35729 is the port used by livereload, which you may or may not use? I’m not using it.
- 3000? IDK
- 80 is just remapping port 4000 externally.
nginx-proxy takes care of all the port issues, though, and uses internal networks to route the reverse-proxy HTTP traffic, so we don’t actually need to expose anything but 35729. We do need to tell nginx-proxy that we’re running on port 4000, though, and not port 80.
I had problems with jekyll simply returning 0 if I tried to cache gems. So I had to remove the gem caching directory. I couldn’t find any bug reports for this issue, and cached gems aren’t necessary (they speed up the initial load time of the container). Later, I discovered that in order for relative URLs to resolve properly, you must run jekyll in “production” mode (default mode is “development”), so I also added an environment variable to bring up jekyll in “production” mode. The final docker-compose.yml looks something like this:
The config sections for nginx-proxy and nginx-letsencrypt are really, really, really exactly from the tutorials for those two containers. They work really incredibly well, and I can’t recommend those two packages enough.
They key things are to include, in each proxied container:
- This is a comma separated list of what URLs nginx will proxy. This means any incoming request for reenginee.red or www.reenginee.red will go to this container.
- Same, but for pulling Let’s Encrypt certificates
- Email address for bothering you if Let’s Encrypt fails for some reason. I haven’t had a failure yet, so I actually don’t know how well this function works!
Okay, home free, right?
The jekyll docs and the docs included with the jekyll docker container are pretty unclear about bringing up a new site. The instructions read:
docker-compose run site jekyll new mysite, which works. But jekyll won’t, by default, be able to get to the generated _config.yml, so when you run
docker-compose exec site jekyll build later, you’ll get a bunch of errors, and a half-built site. Additionally, the half-built site will live at https://[YOURURL]/mysite, and you PROBABLY want it to live at https://[YOURURL]/.
What you really want to run is
docker-compose run site jekyll new . which creates a new site at the root directory.
Now you end up with a
_config.yml file at the
/PATHTO/srv/ directory configured in the docker-compose.yml:
Most importantly, configure the “url” to the correct url, and you should be off to the races, and caught up with all the other Jekyll documentation that lives on the internet!
Any time you change your _config.yml, you’ll have to restart the jekyll container (
docker-compose restart [containername]), but otherwise, changes will auto-refresh!