Self-Hosting
A dive into my EU-based self hosting setup for video, music, blogs and other apps. How I manage security, backups, and costs
Background
In the wake of AI mass-scraping, ubiquitous tracking and privacy concerns, I started migrating to more privacy-focused, ideally EU-based solutions for my personal data. Having settled on Proton, I then proceeded to see what I can do about other services I use to serve my videos, photos, host code etc.
I settled on self-hosting and migrating my data over to alternatives to Instagram, Youtube, Netflix or Spotify. I previously ran a few services on an Intel NUC hosted in my own flat and served over a tunnel, however it could not promise availability or throughput I would need.
Cloud
I chose OVHCloud for my setup to keep my data within EU, as well as since their VPS pricing is extremely good for my purpose. I set up two VPSes:
- 12vCores, 48 GB RAM VPS where all services are hosted
- 4vCores, 8 GB RAM VPS to run an Uptime checker, and some backup services
Both VPSes use Yunohost to manage deployment of applications. The main VPS’s applications include:
- Peertube for serving gamedev/gaming videos, as well as for uploading longer, private gameplay videos to share with friends.
- Funkwhale for streaming my own music
- A Dissenting Opinion where I occassionally write
- A private, unfederated Matrix server
- A Git Forge
- A private WebArchive
- A Jellyfin instance
- A WebDAV backup server
- La Suite Meet
And others. The CPU/RAM is more than enough to handle any of the traffic + video encoding, the main issue being storage costs. Whenever possible, applications are set up to use OVHCloud’s S3 backend to store data. Where it’s not possible, I utilise rclone S3 mounts to handle applications with large amount of data.
The only non-EU element is CloudFlare as they are my domain registrar and DNS provider.
Security
The main threat to the VPSes are SSH access, since both ports are exposed on a default port number. SSH keys are enforced and only one user is allowed to log in via SSH, however this can be further hardened by forcing SSH to only be done via a pre-existing Wireguard tunnel. This would take the SSH port off of the public Internet, but it risks issues if the tunnel is misconfigured or fails.
There is also the concern of access to data by the cloud provider. Any sensitive data (Matrix communication, phone backups via WebDAV) is only uploaded in encrypted format. Unencrypted data consists of Funkwhale music, Peertube videos, Jellyfin movies/series, Git Forge source code, and while it should be kept private it is not of any risk if exposed to the cloud provider.
Any Rclone mounts (eg. Jellyfin) are automatically set up with an encryption later. This will not prevent someone with access to the VPS from recovering the encryption key, but seems like a good practice as it costs little to add in an extra encryption layer.
Yunohost handles all LetsEncrypt certificate provisioning for custom domains.
Backups
Backups are done both on the cloud level (a 24hr snapshot), and via Restic. The latter backups are done on an 8 hour schedule, are then encrypted and uploaded over to S3 in encrypted format.
Restic backups, Peertube, Funkwhale audio/video files are replicated to another bucket in a different region, meaning data is stored in at least 2 distant location. I am planning to set up a local RPI with an external HDD to perform a weekly backup sync for an off-site backup. This would mostly protect against losing access to my OVHCloud account, as even though replication avoids a single point of failure, there is the unlikely case of OVHCloud denying me access to my data. Off-site replication de-risks that single point of failure.
Monitoring
Glances and Monitorix are used to keep track of common metrics, since I am mostly dealing with a single VPS this is enough for visibility.
Uptime Kuma on the smaller VPS handles keeping track if all services are up. It is set up to send Matrix notifications via a bot, and, if the Matrix server itself is down, to my email.
Cost Control
The VPSes are the bulk of the cost, coming up to 300 USD a year. I might have overprovisioned a little bit and could have easily gone with a smaller instance, so that is something to explore next year.
Thanks to using S3 the > 1TB of data (including backups and replications) costs me about 120 USD a year to handle. Since I switched to delivering Peertube videos via an Nginx proxy on the VPS I could potentially move all my videos to infrequent access class, as internal VPS-S3 traffic does not incur traffic fees, and cut the bill down down to 90 USD a year.