Want to build a website like this? It’s really simple and fast once you set up the infrastructure. A lot of this guide will be a repeat of how Luke Smith hosts his servers so you can read landchad for the source material. Inspired heavily from sethforprivacy. The whole website source is on github for a point of reference.
Tooling
- Hugo:
- A fast static-website generator that turns easily written markdown to html in miliseconds
- This website is all generated by hugo, using the papermod theme
- Learn basic markdown
rsyncis the tool I use to sync up files locally to my remote webserver- Git:
- A definite must for this
- Git is a version control program that uses a central repository share, edit, and do more with your code (most common implementations of this is github, gitlab, or a selfhosted gitea instance)
- I use my desktop and laptop to update the website so I need to be able to have a remote repository so that I can update the website from both devices
- Learn
git
- Any VPS or spare computer:
- This is for the actual webserver, choose one close to you or your audience
- You can host the website on any VPS like Vultr or Linode
- Or, host it straight from a spare computer and open port 443 on your router (less secure)
- A less private but easy solution can be using Cloudflare Tunnels, which is more secure than opening up a port, but less private
- A domain name:
- You should have your own domain name bought from one of the registrars like namecheap or Epik
- Makes your website more “professional” and you can feel superior to github pages
Get Started with Hugo
Hugo is very easy to get start with. I will assume you are on linux.
Installation; hugo docs
# Arch-based distros
sudo pacman -S hugo
# Debian/Ubuntu-based distros
sudo apt update ; sudo apt install hugo
# Fedora/RedHat-based
sudo dnf install hugo
Quick Start hugo docs
Change your directory into where you want the new site to be created, for me I prefer ~/Public. To create a skeleton of a new website with a config file in yaml type, use hugo new site name_of_website -f yml. The default config file is in toml but I think it’s ugly and I’m used to docker-compose.yml files. Be careful of spacing mistakes with yml.
Anyways, let’s go into the website: cd name_of_website. If we do an ls here, or use a file manager, you’ll see the default hugo directory structure.
name_of_website/
├── archetypes/
│ └── default.md
├── assets/
├── content/
├── data/
├── layouts/
├── public/
├── static/
├── themes/
└── config.yml
This is displayed with the tree command
Let’s turn this into a git repository: git init. Now that this is a git repo, we can add in a submodule for a theme, I really like papermod, but you can choose any you want.
Note that without a theme, hugo will not work
# Installing papermod
git submodule add --depth=1 https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod
git submodule update --init --recursive # needed when you reclone your repo (submodules may not get cloned automatically)
# Updating papermod
git submodule update --remote --merge
Now, add papermod into your configuration file to activate the theme. Inside config.yml, add in this line (make sure the spaces are correctly placed and not tabs):
baseURL: "https://yourdomain.com/" # You will buy a domain later on
title: Super cool blog # Name it something cool
paginate: 5
theme: PaperMod # Activating papermod as your theme, if you have more themes in the themes directory, papermod will be the one activated
While we’re in the config file, let’s change some stuff for papermod. You can go and check the settings for papermod in their example config file or my config file. Most of the settings are self explanatory, but if you are confused they have documentation as well here.
Now let’s open a new terminal and cd back into the website directory: cd ~/Public/name_of_website. In here, we can start a simple webserver that should not be used for production, just for testing: hugo serve --noHTTPCache -D.
--noHTTPCache just means your browser doesn’t cache the website, which would bloat up your RAM and storage.
-D means that you will load drafts, which will be the default setting on your articles. Drafts will not load in your actual webserver.
We can start writing content for the website now, back on your first terminal: hugo new posts/first-post.md. Note that we don’t specify the whole path (content/posts/first-post.md), just path we want inside the content directory. Also note that first-post.md ends with a .md extension, which is required most content you write.
Once you are done writing, go to your browser and this address: http://localhost:1313. If it doesn’t work, try http://127.0.0.1:1313. Your content should be loaded on to the front page of your website. Go ahead and edit the first-post.md file, type in whatever you want. Once the file is saved, the content you be automatically updated on your browser. This is the best feature in hugo, autoloading. It makes troubleshooting extremely easy to do, and when it errors, the error is even shown in the browser so you don’t have to read terminal if you’re scared of it.
Nice, you’ve set up a local website ready to deploy
Setting Up Your Webserver: landchad Tutorial
Get a Domain Name
Domain names normally go for $10-11USD, but some websites will offer discounts such as Epik or any one of these. Pick a cool name for your website like hyperboly.net and purchase it. I normally pick the cheapest one that looks legit to the average person. *.net is pretty recognized and doesn’t look suspicious.
Get a Server
So now you need a server to link your domain to. I will show you how to do this using a VPS
Vultr and Linode both offer $100 credits to people who use youtuber links like Luke Smith’s or LearnLinuxTV. I don’t have the links on hand so go search for them. Purchase the cheapest subscription plan they have (often times just $5USD/month, roughly 600nt) with IPv4 addresses. Select whatever location you want and choose Debian as the distribution.
Linking Your Domain with Your Server.
Now that you have everything purchased, it’s time to make the internet recognize that your domain name belongs to the IP of your server. This section is better explained by landchad, which includes a lot of visuals. Please read it.
You will set up an A and a AAAA record. This basically means you will link your IPv4 and IPv6 record to your server. To do this, go to your registrar and their DNS settings. Different registrars will have different buttons, please refer to their documentation.
The IPs of the servers should be listed on your VPS provider, check landchad for more inforamtion
Setting Up The Actual Webserver: landchad Tutorial
I will be using nginx here because I have never used apache. The nginx settings are taken from landchad and sethforprivacy.
First, log into your VPS server with ssh. You want to update your server so that your servers aren’t vulnerable from old vulnerabilities: apt update ; apt upgrade ; apt install nginx python3-certbot-nginx rsync. I installed all necessary packages in the code too just to save some time.
Editing nginx Settings
Create a new file and edit it in /etc/nginx/sites-available/name_of_website. In the file you should include:
server {
listen 80 ;
listen [::]:80 ;
server_name name_of_website.com ;
root /var/www/name_of_website ;
index index.html index.htm index.nginx-debian.html ;
location / {
try_files $uri $uri/ =404 ;
}
}
Here, you’ll have to change name_of_website.com and /var/www/name_of_website to your own domain name and website. Keep everything else the same and paste it into /etc/nginx/sites-available/name_of_website. Now you can create the directory for the website at /var/www/name_of_website, we’ll populate the directory later with rsync: mkdir /var/www/name_of_website. To enable the site so people can actually access it, do ln -s /etc/nginx/sites-available/name_of_website /etc/nginx/sites-enabled. Reload nginx, and the website should be online. Wait a few minutes (sometimes hours) for the domain to update: systemctl reload nginx.
EDIT: Since 2024, I’ve switched to HAProxy
Poking Holes in The VPS Firewall
You’ll have to open some ports on the host in order for people to access those ports, this is done with ufw.
ufw allow 80
ufw allow 443
Getting a SSL For Your Website
SSL certificates makes your website less scary for average people. Websites without an SSL certificate will display as “unsecure” in most modern browsers. To prevent this is easy. Remember when we installed nginx we also installed certbot? All we have to do is execute certbot with certbot --nginx. Go through the process, provide your email (you will be notified to renew the cert), allow your domain to have an SSL cert, and wait for certbot to finish. Now we will import the hugo site contents over to the server.
Rsync
Now back on your local machine (the one with the hugo website), you should still be in the ~/Public/name_of_website directory. We will create a script that automates the process of having to rsync your files manually everytime. I like to put my scripts in ~/.local/bin, but you can put it whereever you want. I will assume the script is in ~/.local/bin/deploy-hugo. Once you’ve created your file, paste this bash script in:
#!/bin/bash
USER=root
HOST=IP_of_your_server
DIR=/var/www/name_of_website # the directory where your web site files should go
cd ~/Public/name_of_website
git pull
hugo && rsync -avz --delete public/ ${USER}@${HOST}:${DIR} # this will delete everything on the server that's not in the local public folder
exit 0
Edit the pasted code accordingly. Make it executable: chmod +x ~/.local/bin/deploy-hugo and try executing it: bash ~/.local/bin/deploy-hugo.
Note that your local machine must have rsync installed as well.
Once execution worked, go back to your remote machine and make sure that /var/www/name_of_website contains all the files such as index.html, 404.html, sitemap.xml..: ls /var/www/name_of_website. You should see your changes applied to your domain name if you navigate to https://yourdomain.com.
Cronjob For Rsync
Having to execute ~/.local/bin/deploy-hugo all the time isn’t fun, which is why I set up a cronjob to execute the script every night at 20:00. All you need to do is crontab -u $USER -e and at the bottom of the file add in this line: 0 20 * * * /home/$USER/.local/bin/deploy-hugo.
End
You now have a fully functioning website that is encrypted and an automated website updating system. Thanks for reading.
>> Home