Setting up Hetzner Server for Website Hosting
Some scratch notes on setting up a Hetzner VPS to run docker-based Flask projects, static websites, and more using Caddy as a reverse proxy.
Purchase Cheapest Cloud VPS from Hetzner
Their Falkenstein, Germany location gave me the best ping times, so I chose that one. At €2.49/month for a KVM-based VPS with 2GB RAM, 1 vCPU, and 20GB SSD, this was cheaper than my previous preferred European provide, Time4VPS.
I chose a Debian 10 Buster image. It was deployed within seconds (no account verification needed… and didn’t even have to pay yet). They didn’t provide a root password, but luckily they have a section in their web panel that allows adding an SSH key. Put in my public key and logged in as root via SSH.
Initial Setup…
Let’s setup a sudo user, aliases, and initial installs
1adduser <my_user_name>
2usermod -aG sudo <my_user_name>
3
4sudo apt update
5sudo apt install apt-transport-https ca-certificates curl \
6 software-properties-common mc htop tmux gcc g++ libc6-dev
Update .bashrc to enable my favorite alias with this line: alias ll='ls -alF'
Also, since the Hetzner SSH key web interface puts the authorized key into the root space, I had to copy it to my user space and change owner:
1sudo cp /root/.ssh/authorized_keys /home/<my_user_name>/.ssh/authorized_keys
2cd ~/.ssh
3sudo chown <my_user_name> authorized_keys
4sudo chgrp <my_user_name> authorized_keys
Some SSH Setup
Create a private/public key pair:
1ssh-keygen -t rsa
Update /etc/ssh/sshd_config with the following:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
Install Docker:
Get Docker repositories into apt sources, then install:
1curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
2sudo add-apt-repository \
3 "deb [arch=amd64] https://download.docker.com/linux/debian buster stable"
4sudo apt update
5sudo apt install docker-ce docker-ce-cli containerd.io
Install Gitlab Runner:
Get Gitlab repositories into apt sources, then install. Replace the url with https://packages.gitlab.com/install/repositories/runner/gitlab-runner:
1curl -L \
2 <url>/script.deb.sh \
3 | sudo bash
4sudo apt update
5sudo apt install gitlab-runner
Delete or rename .bash_logout under the gitlab-runner userspace:
1cd /home/gitlab-runner
2mv .bash_logout .bash_logout_rename
Add gitlab-runner to the docker group so it can run build and deploy jobs:
1sudo usermod -aG docker gitlab-runner
If you are ready to register this VPS with a Gitlab project, then do this:
1sudo gitlab-runner register # I chose shell as exectutor
Install Go
Get binary and install:
1wget https://golang.org/dl/go1.15.1.linux-amd64.tar.gz
2sudo tar -C /usr/local -xzf go1.14.3.linux-amd64.tar.gz
Add Go path to path in .profile:
PATH="/usr/local/go/bin:$PATH"
Install Hugo
The best static site generator is Hugo. The best way to install the latest version is from source:
1mkdir $HOME/src
2cd $HOME/src
3git clone https://github.com/gohugoio/hugo.git
4cd hugo
5go install --tags extended
It will put the hugo binary in ~/go/bin, although I like to move it to /usr/local/go/bin. It will also leave a bunch of files in a download cache in ~/go/pkg. Clean it up with:
1go clean -modcache
Install Caddy
Get binary and install:
1echo "deb [trusted=yes] https://apt.fury.io/caddy/ /" \
2 | sudo tee -a /etc/apt/sources.list.d/caddy-fury.list
3sudo apt update
4sudo apt install caddy
I like creating a ~/caddy directory and putting Caddyfile inside. An example of using it for a reverse proxy:
1# Add gzip compression to requests
2(webconf) {
3 encode gzip
4}
5subdomain.example.org {
6 reverse_proxy 127.0.0.1:8000
7 tls [email protected] # For automatic Let's Encrypt SSL certificates
8 import webconf
9}
It’s nice having a hard-linked file in my user space while still having it in Caddy’s system startup space:
1cd /etc/caddy
2sudo mv Caddyfile Caddyfile_bak
3sudo ln ~/caddy/Caddyfile /etc/caddy/Caddyfile
Caddy will automatically start when the system is started and will load the Caddyfile that is hard-linked to my user space Caddyfile.
How is this VPS Used?
Basically, gitlab-runner is registered to a project (i.e. Flask application) that is designed to run out of a Docker. And build and deploy scripts are called in the .gitlab-ci.yml file of the respective repository. This server will take care of the rest.