This and the second post are about the previous iteration of my website. Additionally, When I originally made this post, my domain was I’ve since changed it to, and have updated all references to reflect this change.


Over the past couple years, my website has accumulated digital dust. Its design was stale, its content reflecting an erstwhile me. I wanted to create something simple that could 1) be a landing page for others to find out more about who I am, and 2) be a place for some written analysis of ideas I’m pondering, projects I’m working on or considering, and other musings.

More specifically, I wanted to do the following:

  • Setup and maintain a virtual private server (VPS) for hosting
  • Use Hugo, the static website generator, to build my site
  • Ensure my website is reasonably safe and secure
  • Configure a native Tor Onion Service, so my site can be easily accessed over Tor

Setting Up a Virtual Private Server (VPS)

I decided on Linode for my VPS host because it is affordable and well-regarded. Since I don’t anticipate much traffic, I opted for the basic shared instance that has 1GB RAM, 1 core, 25GB SSD, and 1TB transfer. After installing Ubuntu Server 20.04, I made sure it was up to date:

sudo apt update
sudo apt upgrade -y


After checking for updates, I checked if the Uncomplicated Firewall (ufw) was enabled. It wasn’t, so I turned it on and allowed ssh:

# enable ufw if not already
sudo ufw status
sudo ufw enable

# allow ssh
sudo ufw allow ssh


I knew I needed to disable password-based ssh authentication and enable ssh key based authentication instead. I followed this guide by Digital Ocean, and copied my ssh key over to the server.

Replace ‘username’ and ‘remote_host’ appropriately:

ssh-copy-id username@remote_host

# Output
Are you sure you want to continue connecting? (yes/no)? yes

After confirming that I wanted to connect, I entered my ssh key passphrase for which I was prompted. I needed to make sure this worked, so I again authenticated using ssh, this time without providing my server account password.

ssh username@remote_host

I again typed “yes” when asked if I wanted to continue, and supplied the passphrase for my private ssh key.

Finally, having logged in via my ssh key, I could disable password authentication. I needed to edit the /etc/ssh/sshd_config file, setting the PasswordAuthentication option to ’no’.

# use whatever editor you're comfortable with
sudo vim /etc/ssh/sshd_config

I made sure to uncomment the line with PasswordAuthentication:

PasswordAuthentication no

After closing and saving the file, I restarted the ssh sever using sudo systemctl restart ssh. I then opened another terminal tab and verified once more that I could login via ssh, as desired.

Configuring Hugo

Now it was time to configure the static site generator Hugo. I needed to install Go.

NOTE: I installed Hugo (and therefore Go) on both my Linode server and my local machine. I use my local machine to write and develop the site, and fetch/pull the changes to my server using git.

Following the documentation:


sudo rm -rf /usr/local/go && tar -C /usr/local -xzf go1.16.3.linux-amd64.tar.gz

export PATH=$PATH:/usr/local/go/bin

go version

Next, I installed hugo from source following their documentation:

mkdir $HOME/src
cd $HOME/src
git clone
cd hugo
go install --tags extended

Creating My New Site

Now I could finally use Hugo to generate a new site from scratch. Initially, I used a theme called PaperMod, but then decided on the theme Terminal by Panr (as mentioned and linked in the acknowledgements section). The Hugo documentation proved invaluable during this step. Also, be sure to reference the documentation created for your particular theme.

First, I generated a new Hugo site (replace ‘mywebsite’ with whatever is appropriate for you):

hugo new site mywebsite

Next, I added my chosen theme by adding it as a submodule, and added all npm dependencies.

cd mywebsite/
git init
git submodule add themes/terminal
cd themes/terminal
npm install

NOTE:At this point, I’m working on my local machine, but I followed the same steps when installing Go/Hugo/Terminal-theme on my server. In short, I want to create posts and edit my site locally, push my changes to GitHub, and pull the changes to the server for deployment.

Now, I can start the hugo server, which will automatically update changes as I work on my site. I generally run the server in one terminal tab, open a second tab, generate a new post template and vim into the root directory of my site. Then I start editing.

hugo server -D

# in a second tab, same directory
hugo new content/posts/

Installing and Configuring Nginx

I installed Nginx from the apt repository following both the Nginx Documentation and a guide from Digital Ocean. The Digital Ocean guide is specific to my server instance, Ubuntu Server 20.04, and I highly recommend it if you’re using the same.

In short, I installed Nginx, configured UFW, and setup server blocks.

sudo apt update
sudo apt install nginx -y

# adjust firewall
sudo ufw allow 'Nginx HTTP'
sudo ufw status

Which gives the following output:


Status: active

To                         Action      From
--                         ------      ----
...                         ...         ...
Nginx HTTP                 ALLOW       Anywhere
Nginx HTTP (v6)            ALLOW       Anywhere (v6)
...                         ...         ...

I then checked my web server was active by running systemctl status nginx.

Setting up my first server block, I closely followed Gideon Wolfe’s guide:

cd /etc/nginx/sites-available/
cp default mywebsite
vim mywebsite

This is how my server block started out:

server {
       listen 80;
       listen [::]:80;


       root /home/username/mywebsite/public/; #Absolute path to where your hugo site is
       index index.html; # Hugo generates HTML

       location / {
               try_files $uri $uri/ =404;
               add_header 'Access-Control-Allow-Origin' '*'; # Allow access to resources (for www and non www)

Next, I created a symlink from /etc/nginx/sites-available/mywebsite into /etc/nginx/sites-enabled. I also removed the default file from sites-enabled. Lastly, I started and enabled nginx:

sudo rm /etc/nginx/sites-enabled/default
sudo ln -s /etc/nginx/sites-available/mywebsite /etc/nginx/sites-enabled/mywebsite

# run and enable Nginx
sudo systemctl start nginx
sudo systemctl enable nginx

Up to this point, I’ve created a simple static site using hugo, and configured it to run on nginx on my server. Additionally, I configured my DNS records for to point to my server. Instructions for this can typically be found on your registrar’s website.

I can now navigate to Success!


Next, in Part II, I enable SSL using CertBot, enable some basic headers in my nginx server blocks, and configure a native Tor onion service.


I followed very helpful guides along the way. This detailed post by Seth Simmons I more or less followed line-by-line. This post by Gideon Wolfe (which is also linked in Seth’s post) was a huge help as well. You’ll notice that I use the same Terminal Hugo theme (made by Panr) as Gideon and Seth. Once my site was finished and deployed, I used the Mozilla Observatory to scan for and fix basic security vulnerabilities.

Thanks for reading, and feel free to contact me via twitter or email if you have any questions, comments, or corrections.