All chapters

Chapter 7: The Unexpected Benefits of Self-Hosting

Something amazing happens when you start running your apps in Docker and Docker Compose. You begin to see it everywhere. I guess that's not a big surprise. Same things happens when you buy a yellow car. The world is full of yellow cars, right?

But in this case, there are some really awesome benefits, and they're usually free and super low-risk to try. Here is what our server with an abstract docker visualization might look like. Our apps are isolated into a Docker Compose cluster, and they share resources such as a completely private network and private data volumes that we've created for persistence of our database data.

Abstract visualization of our Docker infrastructure.

If your server has lots of extra capacity in terms of memory, CPU, and disk space, you already have everything set up to run other services alongside this safely. In this chapter, I will show you two other self-hosted, Docker Compose-based services that are incredibly useful for most web applications. But the important takeaway is not the two useful applications we'll discuss. No. The takeaway is there are so many additional applications that you already know how to run if you can run this Docker Compose configuration for your own apps.

Umami: self-hosted analytics

Do you have web analytics on your website? Typically, people run Google Analytics because Google, I guess? But that has a lot of drawbacks. First, anyone running an ad blocker will block Google Analytics traffic, and you'll get a partial representation of who is visiting your site. On our site, we saw about a 50% drop in actual data collection for visitors when we were running Google Analytics.

Moreover, services such as Google Analytics are a privacy violation for your users. They require you to have those terrible cookie banners, and they're even potentially violating the GDPR according to some European countries, such as Austria.

What's a well-intentioned web app developer to do? Look around for other options, I would say. There are a few. Two good ones are Plausable.io and Umami.is. A big improvement for sure, but you're still sending your data to someone else and sharing your visitors' data with others, right? Plus, at least for Plausible, the pricing is kind of steep. A medium-level trafficked website would be at least $50 to $100 a month.

Umami is open source: github.com/umami-software/umami. And that project has over 23,000 GitHub stars, making it quite a solid option if it wasn't a hassle to install and run it. If you look closely, right there in the GitHub repository is a docker-compose.yml file!

To start using this app and running its hosted version, there are just a few crazy simple steps.

First, download that docker-compose file.

Second, change a couple of the values there so that they are unique to you, such as the database password.

Third, create a persistent volume for storing the data and put it in the Docker Compose file:

# Create a persistent volume outside lifetime of containers.
docker volume create umami-volume

In the file:

# Modified compose.yaml file to use external data volume.

umami_db:
    # ...
    volumes:
      - umami-volume:/var/lib/postgresql/data
      
volumes:
  umami-volume:
    name: umami-volume
    external: true

Finally, run it on your cluster, which includes downloading the latest versions of the database and app server containers like this:

# In the Umami folder with the docker-compose.yml file:
docker compose up

And BINGO!

Event graph in Umami.

Visit the website you just launched to create an account and add it to your production app for real-time analytics without the GDPR worries or selling out your visitors.

This may seem daunting the very first time you try it. But once you get a little experience with operating your own apps this way, it's a walk in the park to add others. And it leads you down a much better path than some service offerings like Google Analytics and others.

I even created an open-source Python package to integrate Umami into your Python backend. Check it out pypi.org/project/umami-analytics if you're working with Python web apps.

Let's try another self-hosted app!

Uptime Kuma: self-hosted status pages

Once you get traction for your web app, you'd want to know when things are working well or if you're having a problem. That is where a status page comes into play. There are paid services out there that you can buy. Alternatively, there are some self-hosted versions as well. One of them is called Uptime Kuma.

Uptime Kuma home page.

Their landing page even just shows you a Docker command for how to get started. Though I wouldn't use Docker, I would use Docker Compose because that's way more repeatable.

If you click the GitHub link, you'll be taken to the repo, as you would imagine. And right there we see a beautiful compose.yaml file. It's so ridiculously simple, I'll put the whole thing here for you to have a look at.

# Compose file defining Uptime Kuma config.

services:
  uptime-kuma:
    image: louislam/uptime-kuma:1
    volumes:
      - ./data:/app/data
    ports:
      - 3001:3001
    restart: unless-stopped

Though in this case, I would actually create an external volume for persistent data just the same:

# Recommended external data for Uptime Kuma.
docker volume create kuma-volume

And change the compose.yaml to:

# Uptime Kuma Docker Compose config with external volume.

services:
  uptime-kuma:
    image: louislam/uptime-kuma:1
    # Add this to make your life easier too
    container_name: uptime-kuma 
    volumes:
      - kuma-volume:/app/data
    ports:
      - 3001:3001
    restart: unless-stopped
    
volumes:
  kuma-volume:
    external: true

In fact, we use Uptime Kuma over at Talk Python. If you visit any of our web apps, at the bottom in the footer there's a link that says "Server Status" and it takes you to this URL:

uptimekuma.talkpython.fm/status/talk-python

Uptime Kuma status page for Talk Python.

From the page, you can see we're using Uptime Kuma to track more than just whether the site is responding to requests. We're tracking the web app, the RSS feed, the API, the CDN, and even the MongoDB database itself directly.

All of this is possible because we now have experience with Docker Compose. We have a large server in the cloud that is cheap to run, has extra capacity, and is already set up for Docker Compose, and these excellent tools come basically pre-configured to run this way.

A whole new world of self-hosting

Once you start down this path and have a few of these self-hosted support applications for your web app, then the world really opens up. Here are just a couple of other things that you could pursue if you're interested.

  1. ArchiveBox - Self-hosted wayback machine that creates HTML & screenshot archives of sites from your bookmarks, browsing history, RSS feeds, or other sources.
  2. Hoarder.app - Quickly save links, notes, and images and hoarder will automatically tag them for you using AI for faster retrieval. Built for the data hoarders out there!
  3. Cal.com - A fully customizable scheduling experience for individuals, businesses taking calls and developers building scheduling platforms where users meet users (like Calendly).
  4. Rocket.chat - Like self-hosted Slack: A secure and sovereign communications platform for governments, defense, and critical infrastructure enterprises.

Awesome right!? Well, here's a list of literally 1,000s of such free, open-source, and self-hostable apps like the two we covered in detail:

awesome-selfhosted.net

I told you it was amazing! The more and more you get into this, the real hard part is not picking out these apps and running them but deciding which ones you should not run because you don't need more apps to take care of. But it's really awesome to pick from these great self-hosted options to run alongside your app to support you better without depending on third-party servers, third-party data exchange, and usually paying for them on top of that.

Next up: Chapter 8: Visualizing Servers and Other Tools
Talk Python's Mastodon Michael Kennedy's Mastodon