🐾 rigby

How I Run My Website

My personal website is a collection of several separate parts. photos, my homepage, and of course, rigby. I’d like to talk about how I set these up, how I write them, and what tools I use in “production”.

VPS Setup

My personal website is running on a DigitalOcean VPS with 1GB RAM and 25GB of storage. This has been sufficient for my needs, there aren’t perceivable slowdowns, even when running multiple projects side-by-side. In the future, I may need more storage, but I have yet to hit the limit.

I have two domain names for my website, krikorian.dev and krikorian.ca. Both of these are just pointed at the IPv4 address of the server, and all separate projects get their own subdomain. This enables me to safely refer to the \“root” URL in each project, I know sending the user to / won’t take them to my homepage, but the project index.

I use nginx as a proxy to all projects, and it works great. It is performant, and extremely flexible. I use it for redirecting subdomains to projects, HTTPS support, and logging. Not dealing with HTTPS support in each separate project reduces the code complexity, although it may be confusing for those forking the project. This is an example nginx config from my server:

server {
	listen 443 ssl;
	listen [::]:443 ssl;
	server_name photos.krikorian.dev;
        access_log /var/log/nginx/photos.krikorian.dev.log;

        ssl_certificate /etc/letsencrypt/live/photos.krikorian.dev/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/photos.krikorian.dev/privkey.pem;

        location / {
                proxy_pass http://127.0.0.1:8080/;
        }
}

The domain krikorian.dev is an HTTPS only domain, so I don’t need to worry about rerouting insecure connections. On krikorian.ca though, insecure connections are rerouted:

server {
	listen 80;
	server_name krikorian.ca;
	return 301 https://$host$request_uri;
}

As you might’ve noticed, I use Let’s Encrypt for my certificates. I have a cron job which automatically checks if a renewal is necessary:

0 */72 * * * ~/renew.sh

For ssh-ing into my server, I use public key authentication, but leave password authentication open in case I need to access the server from a different computer one day. On my MacBook, I have an entry in my ~/.ssh/config :

Host box
Hostname krikorian.dev
User root
PubkeyAuthentication yes
PasswordAuthentication no
IdentityFile ~/.ssh/id_rsa
ForwardX11 yes

This allows me to simply run ssh box in my terminal, several characters shorter than root@krikorian.ca!

Projects

At the moment, my projects are written in go. I dislike a few parts of language (like a lack of generics, which should be coming in the next release), but I’ve found it’s a good choice for these kinds of projects.

  • The standard library is well-equipped for most web-server tasks, in particular the http and html/template packages form the base of these web-app projects, and while both have some rough edges, I’m fairly comfortable with them and am productive.
  • You can ship single binaries for common platforms. I don’t actually do this on my server currently, I just have the go command line tool installed, but in the past I’ve just scped a compiled binary to the server. It’s nice to have.
  • Go is fairly light on resources. Compared to languages like rust or c it falls short, but for the scale I’m currently working at, the performance is more than enough, I feel comfortable running several go projects side-by-side without worry. With something like node.js, I wouldn’t be as confident.
  • Compile times are really fast. This is probably my favourite feature because I don’t need to break my flow when adding a few feature. I really hope generics don’t slow this down too much.

For running my projects, I use systemd service files. This allows me to stop, start, and restart the services easily, starts them on system startup, and restarts them in case of a crash. Go projects rarely crash in case of an error, but its a nice feature to have nonetheless. My photos.service file looks like this:

[Unit]
Description=photos app for my personal website
After=network.target

[Service]
Type=simple
Restart=always
RestartSec=10
User=root
WorkingDirectory=/root/photos
ExecStart=/usr/local/go/bin/go run .

[Install]
WantedBy=multi-user.target

As you can see, I simply move into the working director and run go run .. This \“system\” (wink wink) of handling the long-running projects works a lot better than my previous setup, which was simply running go run . > output.log & to force the process into the background.

Comments

Matthias on 2021-06-06

Interesting! I do something remarkably similar with luther, which hosts ourjseditor.com, thoughts.learnerpages.com, and kasearch.learnerpages.com, among other projects. The most notable differences are that I use Apache instead of nginx. And for the first 2 sites, I use Django, which communicates with Apache through WSGI, a slightly more sophisticated protocol than a reverse HTTP proxy (so it starts and stops with Apache). KA User Search is a node process wrapped in a systemd service, reverse proxied like these sites.

luke on 2021-06-07

huh! this apache protocol thing is new to me, is it a lot of work to set up?

new reply

squishypill on 2022-03-30

I found this randomly while searching for who is the creator of https://kasearch.learnerpages.com/ well, now I know. Btw it'd be really nice if the API on kasearch was public. -Squishy

new reply

new comment