Bootstrapping a blog with lisp

Tagged as lisp, web

I recently participated in the 2019 Lisp Game Jam. I wanted to share some of the things I learned in the process. So I decided to start a lisp+gamedev blog.

But before I can post anything I need to actually set up a blog. And what better way to blog about lisp than with lisp itself?

Update: 7/8/2019: Added instructions for using nginx for ssl termination.

Goals

Use common-lisp (sbcl) to host the blog Write posts in a markdown format (ideally org-mode) Deploy the blog with git (push origin/master to automatically refresh the blog)

The result? I was able to get 99% of what I wanted.

Here's what I ended up using:

namecheap to register the domain

linode VPS for the server.

sbcl 1.5.1 for the common-lisp implementation

roswell for scripting

hunchentoot for the webserver

let's encrypt to manage the ssl certs

coleslaw for the blogging software

git-hooks to manage deployment

nginx for ssl termination

So why am I only 99% happy? Well, coleslaw doesn't support org-mode source files for blogging (only md and html). However, there is an api which seems capable of supporting additional formats. If I'm feeling ambitious I could try writing an org-mode plugin. For now, markdown is good enough for me.

Detailed Setup

If you're interested in my setup, here's what you can do:

Set up the server

Set up your domain+VPS. I used Namecheap and Linode. I can't say I recommend either over similar alternatives, but they suite my needs.

Install the webserver

Follow these instructions on the server (or a dev machine):

Set up roswell with sbcl

Clone my template from gitlab

Copy settings.lisp.example to settings.lisp and change the appropriate settings.

to and change the appropriate settings. Modify .coleslawrc with your desired settings.

with your desired settings. If you want to run the server as a non-root user (recommended for security reasons), give sbcl permission to bind ports 80 and 443

# run as root setcap CAP_NET_BIND_SERVICE=+eip (probably /home/<lispserver-user>/.roswell/impls/x86-64/linux/sbcl-bin/1.5.1/bin/sbcl)

Open up ports 80 and 443 in the firewall. Note that you may have to change zone=FedoraServer

# run as root firewall-cmd --permanent --zone=FedoraServer --add-port=80/tcp firewall-cmd --permanent --zone=FedoraServer --add-port=443/tcp firewall-cmd --reload

Should now be able to run server.ros and access your domain from a web browser.

and access your domain from a web browser. (optional but recommended) Set up ssl. Let's encrypt is free and has great documentation. Be sure to set *enable-ssl* in settings.lisp .

Set up the proxy

Copy site config (see nginx-site in git repo) to /etc/nginx/sites-available/

in git repo) to symlink to site from /etc/nginx/sites-enabled/

Ensure /etc/nginx/nginx.conf reads from sites-enabled. sh http { .... include /etc/nginx/sites-enabled/*; .... }

Set up automatic git deployment on the server

Set up a bare git repo on the server: https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server

Add the server as a remote on your personal machine

git remote add origin your-server:/path/to/your/blog.git

Copy example.post-receive to /path/to/your/blog.git/hooks/ and edit the file to finish the setup (instructions in the hook's comments)

to and edit the file to finish the setup (instructions in the hook's comments) Your blog should now automatically redeploy every time master is pushed.

Optional: Set up a systemd service for your server

If you're using systemd on your server, I've also included a sample lispserver.service file. Instructions to set it up in the file's comments.

If you'd like to follow my indie game, Syn, please consider Wishlisting on Steam or Subscribing to Syn's email list