Most people who know me, they know about my libertarian inclinations and how important self-reliance and independence are to me.

With the CoVID-19 crisis, being at home and alone, it gave me time to introspect and evaluate how much of those principles I was applying to myself and whether I could do better. What I've found is that I was relying way too much on 3rd party services for critical parts of my online persona.

As if that wasn't enough motivation, the way governments handled the CoVID situation made me distrust them even more. All these tracking applications and programs they are pushing give me the creeps. And this is all being done with help from the private sector.

I decided to start the journey of taking more control and ownership of the services I rely on the most in the internet.

Goals

From the get-go I decided that what I wanted to achieve is something that it would be as painless to deploy as possible.

The servers where my services run should be considered disposable. I want to run these in cheap servers and will potentially be needing to switch providers. So, everything should be easy to setup from scratch.

Another thing that was a must was to be able to backup the data easily. As these are going to be critical services, the information they hold is really precious to me and backing things up here is not a nice-to-have but a necessity.

The third of my goals was to have each of the services I ran to be composed of Open Source Software. Open Source Software is the way to go for the critical services that you rely on.
Without having access to the source-code there are too many literally hidden risks: third party changing the license, code not doing what it is supposed to, etc.

The Approach

After assessing different possibilities I settled with using all dockerized services and their setup done through Ansible playbooks and roles.

Docker

There are several reasons behind using dockerized services rather than running the services directly on the host.

The first one is the isolation that docker provides. If there's an issue it is less likely that it can propagate to the host and other services.

This isolation is not only helpful on the security front. It also allows you to run versions not available through the package repo in your distro and running a service doesn't pollute your base system with all the required dependencies which can potentially conflict with each other.

On the maintenance/deployment plane, using docker containers has several positive sides on my perspective.
It makes it so much simpler to control the versioning, you use a particular tag and you know what version you are running and updating it is as simple as changing the tag and redeploying the container.

Also, as docker containers are ephemeral in nature, the persistence locations are explicit and can be easily isolated on the host.
This simplifies not only the backup process: knowing what to back up but also how to restore it; but also the setup, in most cases all you need to do is create a folder structure where configuration goes in one place, a folder for the data generated by the service and just mount those into the appropriate places in the container.

Ansible

I don't have a really good reason behind my choice for Ansible. I asked some friends I trust who are DevOps and all of them pointed to it.

At the beginning I found it somewhat confusing, particularly the way of organizing things. But after struggling with it for a while I managed to come up with an easy way of declaring things and set everything up with a single Ansible command.

I am relying on a single site.yml file that contains the description of each host in my infrastructure in a declarative manner.
In it, each host is basically composed of a series of roles: some generic while some specifically created for the host itself. The idea behind this is that I just need to declare what I want to be in a particular host and the roles specifications will take care of setting it up.

This makes the site.yml file really clean and easy to read; by glancing at it I am able to tell where each thing is.

The main hiccup I've faced with Ansible was that it was almost impossible for me to re-use the roles that other people have already developed and published on Galaxy.

None of these leverage docker container for services, they are all meant to setup the service natively on the host. I guess that most people who use Ansible (DevOps) prefer to run the services natively rather than in docker containers.

Migrated Services

The services I decided to migrate first are: mail, calendar, contacts, blog and git hosting.

The reason behind the first three should be obvious: they are the core of my internet persona and contain the most private information. Them being under a third party's control and not my own control seems really risky.

Setting up an email server is not a trivial task, there are many things that can go wrong and multiple parts that need to work together to make it reliable and useful.
Installing and configuring each one of the different components themselves (MTA, MDA, antispam, antivirus, etc) was a no-go for me. I also wanted something that was easy to manage.

I ended up finding a suite called poste.io. The suite is basically the plumbing across all the different components of a mail server plus an administration interface.
And even though the suite itself is not open-source, all the services that are used for the mail server are open source. So, I decided to use it anyways.

For calendar and contacts I've used Radicale. It is a simple-yet-effective CalDAV and CardDAV server written in Python.
For Radicale, not only did I have to write the Ansible role but also the Docker image for it.

Regarding the blog, I thought about using a platform instead of hosting my own. But after seeing what those platforms do regarding censorship and curation of content, I decided to withdraw my support from them. And the best way of doing so is by just not using them.

I've chosen: ghost as my blogging platform. It is an open-source and elegant one; it has a strong community and it keeps getting updated and improved.

Finally, I write code for a living and I want some of it to remain private and have control over it. I don't want one big provider sniffing on everything I do. I still have and use GitHub, but just for my public repos.

For my private ones, I decided to used gitea. It is an open-source clone of GitHub. It has all the functionality I need and even more.

Conclusion

Since I've begun this journey of taking ownership of these relevant things I've learned a lot.
From thinking how to organize the Ansible repo to make it easy, to designing roles for simplifying the setup of services and even having to create some tooling to help with the basic functions I needed to do (see backup-to-dropbox).

I want to encourage more people to follow my steps and become, even if a little bit, more independent and take more control of their online lives.
But I realized that for that to happen, the whole process of setting things up needs to be smoother.

I've set myself a goal to give back to the Open Source community as much of this knowledge as possible.
The way I'm planning to do it is by (1) writing more frequent and in-depth blogposts about each one of the things I've done and learned, (2) by releasing all the roles I've been working on and (3) by contributing to the open-source projects I'm using.
So, expect to see in the upcoming weeks new blogposts related to the those items.

Become independent, own your data and decentralize the internet as much as possible!