I wanted to cover my current server setup. It might prove useful for other web developers wanting an easy way to self-host their websites, portfolios and CI/CD pipelines.
Some considerations first. I have a full bare-metal machine I’m renting from OVH as it is the most efficient solution for my use case as I also host some game servers for my group from time to time.
If all you’d need to host are static websites you can do that with GitHub alone. If you only need a WordPress website, again, there are way cheaper better solutions out there than what I am going to cover in this post. That being said, let’s get into it.
At the core of my setup is a bare-metal dedicated server I rent from OVH. It’s a beast for my needs but it doesn’t cost a lot (around £60 / month) and it provides a lot of overhead should I need it. The full specs include an AMD Ryzen 7 5800X, 64GB of RAM and 1 TB of SSD disk storage in RAID 0 configuration.
In the past, I used to run a classic LAMP stack on it and a MySQL server for my database needs. That was very cumbersome to deal with due to needing to SSH into the machine to make changes whenever I wanted to add a new website or configure an application. It meant a lot of overhead whenever I wanted to deploy a new application or version of an existing one.
The natural step at the time, about 8 or so years ago, was cPanel. Which helped and I considered it worthwhile despite its somewhat spendy license. Today however we have access to way better tools for essentially free through “community edition” type licensing.
So what’s my current setup then? Relatively simple. I run a minimal installation of Ubuntu 22.04 on top of which I have Docker running with its docker-compose
utility. This, coupled with a private GitHub repository that holds a Docker compose file with my base “stack” allows me to essentially spin this server up from scratch within minutes after the initial OS setup.
My base docker includes two containers that have become essential to my life over the past few years. The first of them is Portainer and the second is Traefik. You can find a lot more detail about each of them by following the links but I’ll give a quick overview here as well.
Traefik is a proxy. It knows to do way more than what I use it for. I use it to route traffic to specific containers and terminate SSL for my web servers. All of Traefik’s routing configuration can be done through docker container labels which is great because Portainer allows you to easily add and edit those.
Portainer is a web interface for Docker. It allows you to quickly and easily deploy whole stacks or single containers without having to log in through SSH or an overly complicated setup. It also has a lot of features around managing users, teams and multiple servers in case you need that for shared access to resources. I have never used those so I can’t comment on how well they work but the core set of features works great. I can easily deploy my stacks, edit them and spin up a new game server for my group within minutes. The web traffic is routed to my Portainer container through Traefik.
Besides these two, I have configured Docker to save container volumes to a different path than the default one and I have a bash utility that runs every night at midnight, creates archives of all the volumes and pushes them to an AWS S3 Bucket for backup purposes.
I also keep a copy of all of my docker-compose files in a private repository in my GitHub so that I can have a history of versions and also make sure I don’t lose them.
Everything I described above took me about a month to set up the first time, learning Docker and then how to use Portainer and Traefik together. Now I can set everything up in an hour or so from scratch since I have the docker-compose files saved. I am not going to cover how to set them up as that is already widely available on the internet but I wanted to mention them as I find sometimes half the battle is just finding out the name of the right tools rather than how to use them.
So, to recap: Dedicated server -> Ubuntu -> Docker -> [Portainer + Traefik]. That’s everything summed up in a single sentence.