(λ (x) (create x) '(knowledge))

Over-Engineering a Blog: Part 1

A technical overview of how LambdaCreate works · April 7, 2020

Lambda Create is written in Lua, with etlua for HTML templating and runs inside of a Lapis Docker container. I chose to build the blog in this manner because:

  • Lua is dead simple
  • Lapis services data dynamically and quickly
  • Docker allows extreme ease of deployment

From my standpoint, when I go to write a new post all I have to do is create a numbered etlua template in my posts directory, then rebuild and push the docker container and restart the LambdaCreate service on my web server. And even then, the technical overhead that allows all of that is in all honesty quite simple.

The Dockerfile

The Dockerfile itself is built on Alpine. It runs a complete Lapis server on Openresty, and is comprised of two parts. A dependency build stage, and a web server configuration stage.

#Bootstrap Lapis with luarocks, remove makedepends once compiled RUN apk update ;\ apk add openresty lua5.1 luarocks5.1 unzip openssl openssl-dev lua-dev musl-dev discount-dev gcc git;\ luarocks-5.1 install lapis ;\ luarocks-5.1 install discount ;\ apk del openssl-dev musl-dev lua-dev git unzip luarocks5.1 ;\ rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*

We start the container by bootstrapping the needed dependencies from Alpine's package repositories, then building Lapis with luarocks. I initially also bootstrapped discount to handle markdown parsing based on an old Lapis blog I found on Github, but I quickly abandoned this. To include markdown parsing I would need to pass functions into etlua templates just to render text, to me this felt unnecessary. I chose to avoid it all together and the blog posts themselves are etlua templates, which has the same syntax as regular HTML. Perfectly superfluous for the sake of writing text.

After that we build a Lapis directory, and create an Nginx user with the correct permissions to service the blog.

#Create nginx user and openresty directory structure RUN mkdir /lapis ;\ mkdir -p /var/log/nginx/ ;\ touch /var/log/nginx/error.log ;\ mkdir -p /var/tmp/nginx/client_body ;\ addgroup -g 1000 nginx ;\ adduser --system --no-create-home -G nginx -s /sbin/nologin nginx ;\ chmod 775 /lapis ;\ chmod g+s /lapis ;\ chown -R nginx:1000 /lapis /var/log/nginx /var/tmp/nginx

None of that is particularly exciting or different, but after everything is said and done the image comes out to about 65MB total. When I first started to build out the blog I was seeing container sizes of 110MB-150MB, which is about as much bloat as you'll find in a base Ubuntu container. Space isn't that big of an issue, but when you have to pull the container over and over keeping the baseline as trim and slim as possible really speeds things up. If it weren't for the rm -rf call at the end of the bootstrap, I'd likely still be looking at 100MB of unused packages sitting inside of the container.