Writing intros to posts is such a hard thing. I’ve spent more time on what to write in this paragraph than the rest of this article. You’re supposed to start with a background and a motivation, and conclude with a sentence that you finally did it, and here is how.
I have not done it yet. This thing keeps evolving. As to why I started doing this: it’s fun. It’s fun and powerful to be in control of where your information resides. It’s fun to build a system to manage this efficiently. There are also some benefits too: much more control over my data and the services. These are also all open-source so I can add missing features which I really really want, and I don’t have to abide by the restrictive terms and limits of other platforms. And I don’t lose everything if a platform wants to shut itself down or delete my account for using their product wrong.
As for the disadvantages: Only a few services look as polished as their commercial counterparts. It costs money to host them yourself. Mobile apps are rare. You have to think about security yourself. And if things go wrong, you only have yourself to blame.
Most of my services reside across two servers, which are named HAL-9000 and SAL-9000.
HAL is a Raspberry Pi 4 connected to a single HDD, and acts as a tiny media server for personal use. It runs:
A samba server (allows the HDD to be available as a Windows share)
A DLNA server (most good media players can use this to get a media index off a server)
A Calibre web server (for serving eBooks indexed by Calibre)
Jellyfin (open source alternative to Plex, to organize media)
A suite of services for downloading media (Radarr, Sonarr, Jackett, Transmission)
Syncthing (a P2P file synchronization service)
Tinc VPN (to make this server reachable over the internet)
Some monitoring services (explained later).
HAL resides in a makeshift housing, connected to a cool status screen
SAL runs a lot more services, which I’ll refrain from listing here, as I keep adding and removing them over time. The most used ones are:
Mailman (for hosting a couple of private mailing lists)
Lounge + ZNC (A web IRC client for non-primary machines, and a bouncer for everywhere else)
Firefly III (Favorite expense manager)
Dokuwiki (As a personal knowledge base, also used as an idea-book and journal)
Wallabag (A self-hosted alternative to Pocket, the read-it-later thing)
FreshRSS (RSS reader with a decent frontend and Fever API support)
Radicale (A tiny cardDAV and calDAV server for syncing my contacts and calendars)
Kanboard (Kanban boards)
Tmate (an amazing tool which lets you share your current shell session with anyone else, over ssh)
The complete list of services can be found in the terraform files here.
All of these services run in their own docker containers. This is a primary requirement for me, and I went to great lengths to make sure that nothing runs out of containers. Reasons are:
Easier management: I can store every configuration as static files, which can spin up and configure containers that are ready to go. I use terraform for this. Observing the state of my server becomes a breeze too.
Easier backups: I have to backup only the mounted volumes, which greatly reduce the backup sizes, and can be backed up predictably too.
Easier Upgrades: Upgrading services is as easy as updating the docker image tag. I don’t have to worry of how things might break. And if they do, I can just go back to the earlier version without a hiccup.
Security: Due to the isolated nature of containers, I feel much more safer running everything in containers, knowing that they don’t speak to each other unless I want them to.
Reproducibility: To set it up anew again, all I have to do is install and configure docker, make sure the OS itself is secure, and then my terraform files can take it from there. I rarely have to ever SSH into my host to make infrastructure changes.
Monitoring: A linux system in use has tons of processes running, and to monitor your services, you have to filter through everything, identify which processes are used by which service/user, and so much more. Using containers, I can just look at the resources the container uses.
Monitoring page of SAL-9000
How things actually connect
My home network sits behind my ISP’s NAT, so HAL cannot be reached directly from the Internet. To make it accessible, I use a VPN connection (tinc) between HAL and SAL to bridge the two servers, making HAL locally accessible from SAL. In this network, HAL gets the IP 10.0.0.2 while SAL is 10.0.0.1. This allows me to directly tunnel traffic from SAL to HAL, making it available over the internet.
Tunneling all traffic, though, would mean that services on SAL would be inaccessible. As it’s not guaranteed that all traffic can be identified, I cannot do this selectively for services too. The solution was to get a Floating IP on DigitalOcean and attach it to SAL. Floating IPs are reassignable IP addresses, which can be attached to running instances.
SAL, now has two public IP addresses, the floating IP and the instance’s own public IP. The floating IP connects to SAL through what DigitalOcean calls an Anchor IP, which is added as an alias to the default interface. Now, I can use two different IP addresses to reach my SAL. One by using the SAL’s public IP, and the other via the floating IP (anchor IP on the instance).
| SAL-9000 |
| +---------------+ |
| | eth0 | |
| | | |
Internet ------------>| 184.108.40.206 | |
| | | public IP | |
| | | | |
V | | | |
220.127.116.11 ------->| 10.47.0.5 | |
Floating IP | | anchor IP | |
| +---------------+ |
My DNS configuration says that *.hal-9000 should point to the floating IP, while *.sal-9000 should point to the SAL’s public IP.
I use HAProxy to redirect traffic received on the anchor IP to HAL at 10.0.0.2 over the VPN, and keep the rest on the instance itself. This could be easily done with iptables too, but I wanted all configurations to live in Terraform, hence HAProxy. I’ll be switching to iptables as soon as I add support for them in the Linux Provider.
Once this step is cleared on both servers, all the traffic is forwarded to their respective docker containers. HTTP and TLS traffic, though, all goes to traefik, a reverse proxy with amazing support for Docker (with discovery), ACME, and some capable middlewares. Any contanier which needs to listen to HTTP or decrypted TCP traffic, registers itself with traefik and is ready to go. My traefik config is using Let’s Encrypt to get signed TLS certificates.
The following five services make up the monitoring stack of these servers:
prometheus as the time-series database for storing all metrics
node-exporter to export system metrics to prometheus
cadvisor exports metrics of docker containers to prometheus
loki for storing logs of services
promtail to put docker logs from the filesystem into loki
Data from both the servers’ prometheus and loki is displayed on a Grafana instance running on SAL, which is also used for some rudimentary alerting.
A friend once asked why I was using separate loki and prometheus to store data for different servers, when one could suffice. It’s so that HAL can continue to write metrics to its own databases even in case of internet disruption at my home.
I use restic to backup all my docker volumes to Backblaze. Restic is able to deduplicate blobs too, so the total capacity used for backups is less than the sum of all the backups.
Things I don’t host myself
I am using Migadu as my email provider for now, but plan to try hosting it myself on a separate server later this year. I also use PIA as my VPN provider instead of hosting my own VPN server, mostly because I switch between regions often, and it was cheaper to use PIA than run VPN instances in different regions.
How much does it cost me?
Depending on the TLD, it can be $0 to $$$
I have a DigitalOcean instance with 4GB memory. A 512MB one costs $60/year
I use migadu for my emails. It’s a Swiss provider which allow you to have multiple custom domains as long as you don’t send tons of emails everyday. I’d strongly recommend that you use your own domain for emails, to keep them migratory. But, if you don’t wanna shell out, you can go with free email providers too (Fastmail is pretty good), or maybe what Danny recommends if you really want that domain
The 10GB free tier of Backblaze is able to store all my backups for now. It’s still pretty cheap at 0.5c/GB when it exceeds that limit though
Raspberry Pi running at 135kWh/year at 10c/hr
I use PIA as my VPN provider. Alternatively, you can setup a VPN server on your machine too, if it fits your threat model and you don’t require all the different regions supported by PIA
If you just go with a small cloud server, and a cheap domain, you can probably bring this down to $61/year. If your home IP is not behind a NAT (static IP, or dynamic DNS), you can host this at your home too, bringing it down to just the hardware and electricity costs.
I’ve been using the excellent Firefly III to manage my expenses for a while. As a result, I have developed a habit to actively monitor every transaction I do, which, in my opinion is a much better way than using other automated expense managers which can only track your non-cash expenses, without a lot of context.
Android had an unofficial app which made it easier to interact with Firefly, but iOS doesn’t seem to have one, and the web-ui is not a very mobile friendly one.
While searching for solutions, I came across this blog post by Jesse Dyck where they utilised iOS Shortcuts to create transactions in Firefly. Honestly, I was pretty surprised that Shortcuts is powerful enough to do this, given Apple’s approach to customization.
The shortcuts provided by Jesse didn’t work for me (they were written for iOS 12, before Shortcuts were revamped for iOS 13), so I decided to build one for myself, with a UX more suited for my needs.
Here it is in action:
To use these for yourself, you have to download the following three shortcuts from your iOS device. The first two are function-like dependencies of the third one, which is used to add a transaction.
If you’re not into categories, you’d probably have to edit the Add Transaction shortcut and remove the steps where it deals with them. A fair bit of trial and error should probably give you what you want.
Note that, to be able to import shortcuts from outside the app gallery, you have to go to Settings > Shortcuts and enable Allow Untrusted Shortcuts.
While adding these shortcuts, you’d be prompted to enter your firefly URL and Personal Access Token for each of the shortcut. The URL is where you’ve hosted the app, complete with the protocol and without a trailing slash (like https://demo.firefly-iii.org). You can generate the token from Firefly by going to Options > Profile > scroll down to Personal Access Tokens and click on Create New Token.
After spending 3 hours creating these 150-step shortcuts on a very tiny screen, I was wondering if it’d have been easier to create a basic iPhone app itself. Not really, I don’t know Swift yet.
I spent the last two days trying to switch from my three year old Oneplus 3, to a brand new iPhone 11. I thought I was probably done with expensive phones (I count Oneplus as an expensive purchase), but resigned to giving iOS a chance this time around.
The Oneplus has served as my phone for 33 months now, and has had its fair share of rough usage. The screen broke twice (and got replaced once). Its battery had degraded so much that I didn’t dare go out without carrying a small sling bag with a charger and a power bank in it. Screen-on time would have been somewhere between 50-90 mins. At least it charged fast.
It wasn’t a fast phone by any means anymore too, and I’d gotten used to waiting a few seconds for apps to launch.
The iPhone, is a stark contrast to that. It’s a recent phone with the latest and greatest Apple processor, and things are super fucking fast on it. I am almost in disbelief of how much the battery lasts on this thing. That carry bag isn’t a necessity anymore (though I have gotten used to it - it came in handy a lot more times than it became a hindrance).
Shiny vs battered.
I much prefer the back of the Oneplus. It looks interesting. That sticker is a washed out logo of the 34C3 F.U.C.K. assembly
Actually moving to iOS.
The first thing was setting up contacts and calendar on the iPhone. I use radicale as the CardDAV and CalDAV server to store my contacts and calendar. On Android, I had to use an app called DavX to synchronize the files, which didn’t work perfectly. Rarely ever synced in the background for me. I had to frequently open the app and manually refresh it. I was very pleased to know that iOS supported these standards natively (much like MacOS). Syncing works quite smoothly now.
Setting up Email was pretty easy too in the stock app. UI is really slick, and it sends plain-text emails by default. It’s infuriating how many clients send HTML mails by default, even when not doing any sort of formatting.
The next step would be reinstalling the iOS counterparts to all the apps I had on Android. Most of the popular apps had an iOS version themselves, which didn’t really create many issues. I had to replace few apps with different ones when they weren’t available in the App Store, but the real problem was with apps which had no replacement. This was my first frustration with the walled garden.
Moon+ Reader → Marvin 3 - This was basically a drop-in replacement. I needed an app which could access my OPDS server, and Marvin seems to handle that really well.
Readable → Reeder 3 - This was my replacement for an RSS reader. I use a FreshRSS server as an aggregator and Reeder (I am using the older, free version which seems sufficient for my needs right now) has good support for Fever APIs.
Slide → Apollo - Slide was probably my favorite Reddit client on Android. The gestures were smooth, and it looked pretty nice. Slide for iOS had much more whitespace and had a different design which I wasn’t a big fan of. Apollo, on the other hand seemed like a much better alternative, and had a closer UX to Android’s Slide than iOS’ Slide itself.
Hyperlapse → Microsoft Pix - Microsoft Hyperlapse, while not a very well-designed app, was a good enough one to convert standard videos into Hyperlapse one. There’s a Hyperlapse app from Instagram on iOS, but it doesn’t let you import videos from outside, and stabilization didn’t seem to work in iPhone 11. Microsoft Pix is a complete camera app, but one of its features is converting videos to hyperlapse. That’s probably the only use I’m gonna get out of this app.
Juice SSH → Blink - This was also basically a drop-in (and probably better) replacement for a mosh-enabled shell. The App Store version is pretty expensive, but given that it’s an open source app, one can build it from the source and install the app.
Solid Explorer → Files/Airdrop - Solid explorer used to solve two problems for me. One was being a pretty solid file manager, and the other was the built-in FTP server. It was my preferred way of transferring files between my computer and phone wirelessly, without using the internet. I’m currently using the stock Files app for file management (There might be better apps out there - but this one works well for me right now), and Airdop for exchanging files with my computer. Airdrop is just so nice, man.
Sky map → SkyView Lite - There doesn’t seem to be a good free astronomy app for iOS, so this would have to make do for now. Stellarium is available for iPhone, but I’m putting off buying paid apps for now.
Revolution IRC → Lounge - I was unable to find a free and good IRC client for iOS — so, for now, I’m using a web-based Lounge instance to connect to IRC. It works pretty well, except for the fact that iOS browsers don’t support notifications yet. I’m not really bothered by that though, as I don’t like to be perma-connected to channels on my phone anyway.
Jellyfin → Jellyfin (web) - Jellyfin also didn’t have an iOS app, but the web interface is so good that it almost makes up for it.
These were the apps that were easy to replace. Now there were some which didn’t seem to have any sort of replacement (at least not without jailbreaking the phone – which I’m not very keen on doing right now).
Flud - Flud is a torrent client I used to run on my phone. It was pretty convenient to be able to download torrents on the phone without any hiccup or afterthought. Apple doesn’t seem to allow anything torrent related on their store. I, now have to use the web-ui of a torrent client hosted at my home.
Transdroid - Speaking of managing a hosted torrent client - Transdroid is an app which can remotely control hosted torrent clients really easily. I now have to use a web-browser for that, and most torrent clients don’t really have a mobile-friendly UI.
NewPipe - NewPipe is a Youtube client on steroids. It doesn’t have ads, can download videos as MP4s, can play in the background, and has an overall better interface than the official youtube app. No such replacement on iOS sadly.
Firefly III - I use a self-hosted version of Firefly III for managing my expenses. The web interface is not a mobile friendly one, but there were some Android apps which could connect to the API and make changes. No such things on iOS. But I did find this blog by Jesse Dyck where they utilized iOS shortcuts to interact with the server. That’s something I wanna give a try later on.
SMS Organizer - I am so bummed that this app is not available on iOS. SMS seems like a medium for spam these days, and SMS Organizer did a very good job silencing those messages. I am now back to blocking senders as they come to reduce spam. I’d happily block all SMS messages (I don’t really use SMS for personal communication anyway) but that doesn’t seem to be an option on iOS.
Google Play Services - Okay, not really sad about this. I wrote this because I’m glad to not be dependent on Google APIs anymore. There’re literally zero google apps on my phone right now, and it’s really nice.
Some things about the iPhone are really amazing. And other things, quite awful.
Right off the bat - I love the seamless clipboard syncing with macOS. Honestly, exchanging strings between the phone and computer was such a pain. My method was to use Signal’s “Note to Self” feature for this. I’ve seen others using note-app synchronizations, self-emails, etc. This seamless copy-paste is basically my favorite thing about iOS right now.
There’re also other nice integrations with macOS - Airdrop is super-nice. You can use your phone as a Wifi-hotspot without touching the phone itself. Can even accept calls right from the computer.
iOS Shortcuts seem to be pretty nice and well-integrated with Siri. Though not as powerful as Android’s Tasker - they seem to be good enough for my needs as of now.
Permissions also seem to be better managed. The ability to disallow location access in the background is something which Android should have implemented long back. I like that iOS also asks for notification permissions explicitly. Though I do miss the granular notifications permissions from Android. There, I could disable all promotional notifications, and only keep the important variety. iOS does all-or-none. And this has led to me disallowing notifications from a lot of apps. I refuse to ever receive any promotional anything ever – SMSs, emails, notifications - everything must go.
And I really really miss the customizability of Android. There just seems to be no personality on iOS home screens. Even the widgets on iOS are vastly inferior to the android ones. Also, the status bar is worthless on iOS. On Android, I can see all the apps with notifications, current network speed, ringer status, VPN status, and so many other things. iOS has just the time, network, wifi and battery.
I find the latter layout much better. Everything is reachable on the bottom. The icons are nice, and there's a play button for music right there.
The “True Tone display” is quite nice. It matches the ambient light and temperature much better than any other phone I’ve seen. The speakers are actually great for a mobile phone. What sucks is that there is no headphone jack in this phone. This phone is thicker and heavier than my previous phone. It could have had a fucking headphone jack in it. I do use wireless headphones with my phone, but ever so often, they run out of battery, and then it’s very convenient to attach a wire and use it with that instead. I’ll probably have to buy the lightning-to-AUX dongle now - which I hear, at least has a pretty good DAC in it. Which reminds me - it sucks to move away from USB-C to the lightning port. I’d been getting closer to everything USB-C with every new hardware purchase since the past few years, and now I just took a step back due to this iPhone.
And finally, it’s laughable that Apple includes a 5W charger in the box. I hadn’t seen a 5W charger in years lol. And this, when the phone actually supports 18W fast charging. I don’t understand why they had to cheap out on this.
What the fuck, Apple?
I hope the good outweighs the bad in this move. It took way too much time to shift ecosystems, and I don’t want to repeat that anytime soon.