Graham's Personal Site

DIY Technical Blog

I recently decided to put together a personal website. I've previously used github pages for any blogging or writing I felt like doing and that worked well enough but I've been on a self-hosting kick so I figured I would try setting up my own. I've done plenty of web development work how hard could it be right? Since I'm making this for myself and my own needs I get to set it up exactly how I want.

Requirements #

Tech Stack #

Handling Static Content

A Website or if we want to get specific this is a set of static html pages served by an nginx webserver on a cheap vps running debian. I handwrote some css markup stolen loosely inspired by a hugo theme. I've included some javascript but it's only necessary for code formatting. The blog will display fine without it. I'm also serving the js libs from the site itself so there are zero external dependencies. If an external cdn goes down for some reason we don't care. Server includes on nginx add some templating and reusable components to our plain html files which makes it a little easier for me to work on.

This runs very very fast by modern web standards. We're using a big chunk of js to help with code formatting and this takes a bit to load the first time but will be cached for any subsequent requests. I also do not include the js library or it's associated css file when I'm not using it. Same for any images. So our pages get initial load times of 20-30 ms best case and maybe 100ms or so on the first load with any images or scripts.

With caching on our big assets a page reload is a consistent 20ms. Nginx can handle very large numbers of requests and is very well optimized for serving static content like this. Even on a little potato vps like this we can comfortably handle a metric shitton of simultaneous connections. We also crank through those requests very quickly because each user only needs max 100ms to finish the whole exchange and does not need to keep any open tcp connections. Have I mentioned websites are great? It's also trivial to handle more traffic, just slap a cdn in front of this bad boy and we can entirely offload the traffic to the cdn. The whole site is a static file that can be cached, no complicated state management.

Server Side Includes are Cool

NGINX SSI Boilerplate with straight html can get kind of crazy and there's not any built in method to handle code reuse or make it more modular. This in my opinion is one of the few good reasons to reach for a static site generator or js framework instead of slogging through html. But check this out.

<!--# include file="/si/header.html" -->
<div class="content">
    <h2>Posts</h2>
    <!--# include file="/si/blogsummaries.html" -->
</div>
</body>
That's the blog index page for this site. Where's all the boilerplate for the header and stuff? Nice and modular in a separate file so we don't have to repeat the code and it's easy to update.
server {
    server_name bunnylab.net www.bunnylab.net
    access_log /var/log/nginx/tracking.access.log;
    root /var/www/tp;    

    location / {
	ssi on;
  }
}
All we have to do is set ssi on in the nginx location block for our site to on and this works. As far as I can tell there's no real noticeable performance cost for using server side includes for simple static html pages. I'm going to use these everywhere now, wish I'd known about them earlier.

Pretty Code Blocks #

Need javascript for this. You can do some basic styling but as far as I know there's no way to get syntax highlighting without doing a real parse of the code. So I'm using a nice js library Prism JS for syntax highlighting and code formatting. Works well and has support for most languages. This also degrades nicely if js is disabled or unusable you still get the formatted code blocks it just loses the nice syntax highlights.

Basic Analytics #

Most people I've talked to reach for google analytics for this but its complete overkill in my opinion. For this blog I'm running a small script on a cron job that parses the nginx access logs and outputs the view counts to a file. I'll write up how I did this elsewhere in case anyone is interested. I'm really only interested in a simple view count on different pages and there's zero need for it to be live updated. A view count that updates every few minutes on a cron job is more than sufficient for me.

Keeping it sekrit

I originally just ssh'd into the server or grabbed the views file via scp, but this was kind of a pain in the ass. So I made the file available on the web with nginx and protected it with NGINX Basic Authentication.
location /admin {
	auth_basic	"Admin Area";
	auth_basic_user_file /etc/apache2/.htpasswd;
}
This is pretty easy to set up. Just set the file for basic user auth which contains user/password hash pairs. I'll also set a rate limit on it to prevent any brute forcing of the passwords.

Basic Auth Security

You might be wondering hey basic auth is pretty ancient is that really secure?

Basic Auth Problems

So there's a few problems with basic authentication but for something like this where we just want a quick and dirty way to require authorization on some static content? I think it's great.

Quality of Life #

There's a few things here that are not too hard to do and I think make the website a lot more usable.

Color Code Elements with Different Purposes

I don't know why this makes such a big difference but slightly lighter color for headings and a noticeably different color for links really helps my brain parse things quickly.

Relative Units for Different Screen Sizes

Using REM instead of px goes a long way to making the layout work on phone/desktop etc.

Image Zoom

img {
    transition: -webkit-transform 0.25s ease;
    transition: transform 0.25s ease;
}

img:active {
    -webkit-transform: scale(1.5);
    transform: scale(1.5);
}
Neat css trick. Makes all images scale on hold. Useful for zooming in on image details when you want without having them take up too much space in the normal layout.

Section Links

<h2 id="sitestyle">Don't Hurt My Eyes  <href="#sitestyle">#</a></h2>
Adds a link for each main heading section. Nice quality of life thing where you can click on the heading and the page will scroll to the right spot.

Always Open External Links in New Tabs

<a href="external link" target="_blank" rel="noopener noreferrer">link</a>
I personally like external links to open in new tabs so I don't have to lose my place in whatever I'm reading. The html for having links do this isn't really obvious in my opnion but here it is.

Version Control #

I put all the site files into a git repository locally. Done.

Deployment

SSH into the server and pull or copy over the latest version of the site. I also just edit in prod half the time. Since this is just my personal site I don't care if anyone can see my half finished thoughts.

After Action Report #

Took me a bit to tweak my css for spacing, font sizes and coloring the way I wanted but as someone fairly experienced working with web stuff the basic site setup and NGINX config was not difficult. I also didn't find writing straight html substantially harder than writing markup. I discovered nginx basic auth and server side includes while writing this up both of which were a big help. Highly reccomend server side includes if you're developing a larger static html site. I did find writing some sets of html tags by hand got repetitive.

<pre><code class="language-markup">html stuff</code></pre>

Doing this over and over for every code block is annoying. I know writing in markdown could solve this but that seems like overkill. I wonder if there's a way to configure my editor to write the whole block for me via some sort of shortcut or tag?

Good Enough

I might tweak or do some more fixes in the future but this handles what I want fairly cleanly. Since we're using very standard html/css/js there shouldn't be any issues to worry about with switching hosting or browser updates in the future. I can leave the site and focus on writing and other projects. In general I think programmers and web developers in particular are too used to working with extremely complex web application frameworks and really underestimate how far you can get with a static site plus a little js. Please join me and write websites like its 1999, it's fun I promise!

Top        Home