Self-host a static site in the cloud
/ 8 min read
This article serves as a practical guide for hosting a static website on a cloud service provider. The description particularly focuses running the site on a virtual private server (vps). The primary objective of this guide is to act as a reminder for my future self, but cheaper or even free alternatives do exist (for example, GitHub Pages).
Overview - the most important steps
- Create ssh keys
- Set up vps instance (using ssh key)
- Create and and configure your server
- Configure DNS record
Prerequisites
In order to follow through with this guide, you need to own a domain.
Before buying a domain consider that some domains (e.g. *.dev
) require the TLS certificates.
Caddy does this out-of-the-box, but it is also possible to use another web server.
More on how to automatically update TLS certificates with Let’s Encrypt.
You need an account at Hetzner or another cloud service provider. Any provider will do, as long as you can buy a server instance, e.g. a vps or dedicated server. I will skip a description on how to buy a domain and how to set up an account at Hetzner.
Create ssh keys
In order to connect with your vps via ssh, we need to create a set of ssh keys.
This can be skipped, if you do not want to use ssh keys for authentication (in that case the password for your root
-login will be sent to your email-address by Hetzner).
Linode’s documentation describes step-by-step what to do. So I am only going to summarise the commands:
Set up vps instance (using ssh key)
Click to expand and read about cloud service providers and registration
Create account for cloud service
Create an account at a service provider that offers cloud service. You can pick any service provider you want, however I will focus on Linux (Ubuntu). There are differences with the CPU performance, amount of storage, maximum traffic, etc.
Hetzner
I am currently using Hetzner (scroll to “Prices”)
Alternatives
These are some options I came in touch with:
- Strato was recommended to me, because they are based in Germany (so is Hetzner), and they seem to be cheaper than Hetzner. For example, they offer three tiers of service named “mini-vserver”, one of which can be tested for free for one month (as of 17.06.2023)
- Linode (check the pricing for “Shared CPU”) is located in the United States. I think they are worthy to be mentioned because I found their documentation well written. It helped me a lot to set up my linux instance.
- Vultr is an American cloud services provider that is famous for their powerful API that lets users automate their cloud server deployment.
- Uberspace is a Germany-based web hosting company that lets the users decide how much they pay for the service, so those who cannot afford the service otherwise can. Others that are more fortunate are kindly asked to pay more to help others out.
Create and configure your server
Create a new project
Set up a new project and a new server using Ubuntu as operating system. You are going to be asked to add a ssh key. It is possible now to configure firewall rules either with the GUI or using cloud init config. I configure ufw directly on the Ubuntu instance (further below), but of course there’s no reason to not configure the server with the help of those two other options.
The GUI will display the ip address of your server, as soon as it is set up.
Update ssh config
The next step is to set up the ssh config on your local machine. Open the file via:
Add the following entry
Recommended: Add a non-sudo user
Add a non-sudo user
Connect via ssh:
This connects you as root
, but I would rather connect as a less privileged user.
The following part illustrates how to add another user.
You can use the same ssh key as root
, but you should create and use another set of ssh keys instead!
To start the dialogue to add another user, e.g. with the name metters
, execute:
You will be prompted to enter a password and additional information for the new user.
Grant administrative privileges to metters
by adding the account to the sudo
group.
After that, whenever there are commands that need to be executed as user with root privileges, you can just put sudo
in front of the command.
Then switch to the new user account (the prompted password is the one you set up for metters
) and create a .ssh
directory for the new user.
Configure the permissions for the new directory and create a file, e.g. named authorized_keys
.
Copy and paste the contents of your ssh public key into this file, then save the file and close the text editor.
After this, update the permissions for authorized_keys
:
Update ssh config
On your local machine update the ssh config file again:
If you still want to connect as root
, simply put the username before the hostname:
Now you can connect via ssh as root
(or user metters
, if you followed the previous optional steps):
The following steps assume you are connected as non-sudo user.
Therefore, the sudo
keyword is required for many commands.
Set up Firewall (UFW)
Execute the following commands, one after another:
To check the firewall configuration execute sudo ufw status
or sudo ufw status verbose
to check the ufw configuration. It should print something like this:
Set up web server: Caddy
Download and install
First, run sudo apt update && sudo apt upgrade
, in order to install available updates.
After this install Caddy. The vps is an Ubuntu instance, there is a section about the installation on Ubuntu.
Click to see the commands to install Caddy (its latest stable version)
Regularly used commands to manage Caddy
Configure Caddyfile
Edit the Caddyfile
in order to configure Caddy. You can find it under /etc/caddy/
:
This is nearly the most basic setup for your site
Do not forget to restart Caddy after editing the Caddyfile
with the reload command!
Add a static site
In order for Caddy to serve your site, you must create a folder which contains the build artefact or contents of the website (which can also be a simple html file):
Configure DNS record
Add an A
record for every domain/subdomain that you need.
With a Caddyfile
as the one shown above that would be three entries: @
, www
, and blog
, with the latter two as subdomains.
NOTE: Saving the file, does not immediately take effect. Propagating edited DNS records to the nameservers may take up to a few hours!
Use the following command to find out what ip address the domain refers to. As soon as the displayed ip address matches the one you configured in your DNS record, open the previously configured domain in your browser.