Self-hosting applications and services has never been easier.
Here I want to outline how I deploy and manage my self-hosted services on Linode with nginx, docker-compose and CloudFlare
- create a nginx site configuration under
/etc/nginx/site-enabled/with the correct port mapping and domain
restart: alwaysis set in your
- provision SSL certificate with CloudFlare / alternative with Letsencrypt
Get a cheap VPS
There are many services that offer virtual private servers for quite cheap prices.
Finding self-hostable services
awesome-selfhosted is THE resource to find new projects.
Some are outdated, some are discontinued, many are up to date and also “docker-friendly”.
The general idea is:
- browse through the categories
- find the service you want to self-host
- check whether a
docker-compose.ymlfile is present
If the project you want to self-host doesn’t have a
docker-compose.yml file, you can try to create your own.
Alternatively, if the service doesn’t depend on other containers (e.g. persistence) you can try to spin it up directly with the
docker cli and provide the
Docker / docker-compose
If the project contains a
docker-compose.yml you’re ready to clone it.
git clone the repo and
cd into it.
Understand with the help of the port mapping in the
docker-compose.yml file, on which port the service is exposed, and especially on which network:
If you find a port mapping like this:
you might want to expose it only on the local network (because by default it exposes it on
If there is no explicit port mapping, you might need to understand on which port the service is exposed.
Oftentimes, you can customize the HTTP port through some env var defined in the
To start your service just run
docker-compose up -d (
-d so that the service will run as a daemon, in the background)
Now it’s time to set up a reverse proxy with nginx.
First of all, install nginx on your VPS.
Now take the snippet below and change it accordingly to your needs:
You’ll need to customize
YOUR_PORT: the HTTP port on which the service is exposed through docker, e.g.
YOUR_SUBDOMAIN: define a sub-domain on which the service will be reachable, e.g.
YOUR_TLD: your top-level domain, e.g.
your_service: change this to a meaningful name of your service, e.g.
Put this file under
Then link it with
ln -s /etc/nginx/sites-available/<service> /etc/nginx/sites-enabled/<service>
Also check that everything the nginx configuration is valid with
SSL / CloudFlare
Now I encourage you to put a SSL certificate in front of your service.
The easiest way I found is to use CloudFlare to issue a free SSL certificate for my domains.
To configure Cloudflare you’ll need to log in to your domain registrar and transfer the DNS records to CloudFlare. CloudFlare provides excellent guides to do this.
Now simply get your VPS IP address and create a new DNS record in the CloudFlare dashboard.
A record that points your subdomain to your VPS IP address.
Check that the “Proxy status” is set to “Proxied” so that CloudFlare does the SSL termination.
Recently I wrote about what services I am self-hosting, here you can find practical examples I use daily.