Having never set up a VPS before, it took a while before I was able to get everything working correctly. Eventually, I got this to a state where I can write posts, and things seem secure (though we’ll see about that).

I’m writing this post mainly to keep a good set of notes in case I need to do this again at some point down the road.

I grabbed a plan from one of the cheapest VPS plans I could find from a provider that received decent reviews. I then read several tutorials about setting up a static site on a VPS, and I settled on the following which has been working for me so far.

LetsEncrpyt Docker container#

This lets me use an SSL certificate on the site. While not necessary for a personal blog that I may not actually update all that often, it was a good learning experience.

I use this docker container for a reverse proxy at home, and I found it to be pretty simple to set up. As someone new to Docker, I appreciate that it comes with both LetsEncrpyt and nginx in one package.

I also use docker-compose as I find it a little easier to maintain with a set file in place that I can edit if needed.

This is what my docker-compose.yml file looks like

version: "3"
services:
  letsencrypt:
    image: linuxserver/letsencrypt
    container_name: letsencrypt
    cap_add:
      - NET_ADMIN
    environment:
      - PUID=1000
      - PGID=1000
      - EMAIL=[email protected]
      - TZ=America/Los_Angeles
      - URL=yourdomain.com
      - SUBDOMAINS=blog
      - VALIDATION=dns
      - DNSPLUGIN=digitalocean
      - ONLY_SUBDOMAINS=true
    volumes:
      - /home/ubuntu/docker/letsencrypt:/config
    ports:
      - 80:80
      - 443:443
    restart: unless-stopped

I use the ONLY_SUBDOMAINS=true variable because I use this same URL for other things that reside behind the firewall at home. They have their own certificates there.

That’s the bulk of the changes needed, but there are a couple other files that need to up updated.

Update the pertinent config/dns-conf file with your API key for whichever service you are using. In the config file above you can see I am using Digital Ocean for DNS, so mine looks like this:

# Instructions: https://github.com/certbot/certbot/blob/master/certbot-dns-digitalocean/certbot_dns_digitalocean/__init__.py#L21
# Replace with your value
dns_digitalocean_token = 1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqr

SSH requiring key for login#

There are plenty of tutorials online about setting this up, but I used a combination of the OVH tutorial, and the text-based tutorial from Wolfgang’s Youtube video for setting up a personal VPN.

Creating your key is simple with this command. I decided to add a password to the ssh key

ssh-keygen -t rsa -b 4096

The next step is to actually copy the SSH key to the VPS so it can be used to verify your machine.

ssh-copy-id username@ip_address

I also took the advice of both tutorials and changed the SSH port, disabled password authentication, and disabled root login. All seemed like logical changes to make.

Do this by editing the following entries in /etc/ssh/sshd_config

Port ##

PasswordAuthentication no

PermitRootLogin no

Then, restart ssh with systemctl restart sshd it’s all set.

The SSH key makes logging into the VPS much easier to log into, but an addition setup that I did not know about until watching Wolfgang’s video was making a server alias for the VPS.

Create (or edit) a file at ~/.ssh/config, and add the following configuration for the VPS.

Host domain
    User username
    Port ##
    IdentityFile ~/.ssh/id_rsa
    HostName ip_address

From now on, you can just log into your VPS using your key with the command `ssh domain`. This is much more convenient, and I don’t need to try and remember the IP address for the VPS.

Updated ufw rules to enabled SSH on the new port#

I also had to update the rules for the ufw firewall.

sudo ufw allow 69 allows traffic on the new SSH port.