Hosting a website using Common Lisp

This site used to be written in Clojure, until last week when I applied some updates to my server and then it wouldn't start up. Unfortunately the error was 50 stack frames deep, and I haven't looked at Clojure code for about half a decade, so I decided that the best thing to do would be to just re-roll the site in Common Lisp. And give it a bit of a face lift while I was at it.

In the next decade when I decide to make updates to how this site works again, hopefully this post will help me recall what I was doing, so with that in mind, this post will go over how to set up a web server generally, and then over the Lisp frameworks that made my life easier.

Web Technologies Used

  1. Linode
  2. Nginx
  3. Lets Encrypt
  4. Roswell
  5. NoHup

Why Linode?

Linode is a "Linux as a service" platform, that lets you run Linux virtual machines on the web. Linode is a great choice for personal projects because it has a fixed monthly price, so unlike pay-by-use cloud services, you can never fuck up and cost yourself thousands of dollars. Like this guy. The only risk to using Linode is that you explode with popularity and your server is hugged to death.

I run arch on my Linode, because it has the best command-line package manager, and this is all you have access to when setting up a remote server on the cloud.

If you're reading this and you don't know enough Linux to navigate and install packages via the command line on a server, a lot of the rest of this post will probably go woosh so you might want to get on it.

Why Nginx?

Nginx is a very fast web server that can run on Linux. You almost always want to have a server like Nginx or Apache sitting in front of your real website. The simplest reason why, is because the people that wrote Nginx know Linux very well, and they make it easier configure port binding and ssl. The other important trick is being able to route incoming requests to multiple different applications on the same server. If for example you need to host two websites on the same server, Nginx can do this for you.

And How?

First, install Nginx with pacman -S nginx.

Then you're going to need to set up the config file. On arch this is in /etc/nginx/nginx.conf.

There are two things that you'll want to keep in mind when you are setting up the config file.

First, there is chance you will screw up and do a typo or something. The Nginx people thought of everything and provide the command sudo nginx -t, which parses the config file for errors.

Second, changes to your config file will not be read into the server until you restart nginx. (If you're a cool and you use arch, that's systemctl restart nginx).

Configuration can generally be classified into two categories. Those are:

  1. Bullshit boilerplate that you don't need to understand.
  2. The config that you might need to think about.

For the bullshit boilerplate, I just grab whatever is on the Arch Wiki. In this case the sample config Here.

As for the important part, you stick it in side the http block. It's something like this:

http {
server {
listen 80;
listen [::]:80;
location / {
proxy_pass http://192.0.0.1:5000/;
}
server_name yourdomain.com www.yourdomain.com;
}
}

What we're saying here, is that when we get requests through to port 80, to the domain "yourdomain.com" or "www.yourdomain.com" we immediately forward those requests on to another service which is being hosted on port 5000 on the same linode.

Now don't get too attached, because we're about to clobber that with automated tools.

Why Let's Encrypt

All of the cool kids these days are using https/ssl, and the search engines will give your site worse coverage if you don't support it.

Let's Encrypt is a free, and wonderful service for providing signed certificates, which are used to encrypt and decrypt traffic. You can generate your own self-signed certificate if you want, but the advantage of using a third party service is that browsers tend to freak out when they come across self-signed certificates because there is no way to guarantee that the certificate isn't somebody impersonating you.

The main reason you want encryption is because it means people can't man-in-the-middle attack users of your site. For example if you have accounts with password protection, this stops the owner of a router from being able to steal the passwords of everyone using your site.

Nginx has a good guide on how to set up SSL with Let's Encrypt, solely through automated tools.

You can install all of the tools you need to follow the nginx guide on Arch with pacman -S certbot certbot-nginx.

And here is the guide..

Roswell

So Roswell is a lisp managing system. You'll want this for a couple of reasons if you're hosting a site via lisp, on of which It's available on the AUR.

So yay -S roswell is the way.

And then we'll want to clackup and sbcl, via ros install clackup and ros install sblc.

Finally, you want to use the sbcl installed in roswell to download all of the dependencies that you're going to need for your website, and whack the code for your site somewhere in the quicklisp local-projects directory.

Using nohup to launch your site for real.

Now after all of this pre-work you can launch your site. We need to use a tool called "nohup" here, so when we launch it via ssh it isn't immediately closed when we end the ssh session.

We should be able to launch the site with a command like:

nohup ~/.roswell/bin/clackup ~/.roswell/local-projects/<myproject>/start.lisp --port 5000 &

Have a look at the nohup.out file that gets generated to see logs for anything that went wrong! Good luck.