Year in review: what I self-hosted in 2023
A year ago my homelab was a freshly installed Dell OptiPlex running Nginx and Nextcloud. Today it runs six services across isolated VLANs with automated backups and a proper reverse proxy. That is more growth than I expected, and I want to write down what the year actually looked like before I forget the details.
This is not a "look at my perfect setup" post. Half of what I built this year was a reaction to something breaking. The other half was me solving problems I did not have yet. Both approaches taught me something.
If I had to summarize 2023 in one sentence: I went from "I run some Docker containers" to "I run infrastructure." That distinction matters more than it sounds.
The stack that ran all year
Nextcloud has been the anchor of the whole setup. File sync, calendar, contacts. It replaced Google Drive and has mostly stayed out of the way. I wrote about the setup in my Nextcloud post. The honest truth is that it needs occasional attention. A PHP update breaks something, the sync client throws a cryptic error, or the web interface slows down until I restart the Redis container. But it works. My files are on my hardware, syncing across three devices, and I have not opened Google Drive in months.
The mobile app handles photo backup too. It is not as polished as Google Photos, and search is basic at best. But for getting photos off my phone and onto my own storage, it does the job. I have been thinking about a dedicated photo management tool for 2024.
Caddy replaced Nginx in April and that was one of the best decisions of the year. I covered the switch from Nginx to Caddy already, but the long-term experience has confirmed it. Zero certificate issues since the migration. Adding a new service is two lines in the Caddyfile and a reload. I do not think about TLS anymore, which is exactly the point.
My Caddyfile currently has entries for Nextcloud, Gitea, and a couple of smaller things. The whole file is maybe 20 lines. Compare that to the 200+ lines of Nginx config I was maintaining before. The cognitive load difference is real. When adding a new service takes 30 seconds instead of 10 minutes, you are more likely to actually do it.
AdGuard Home handles DNS for the whole network. Each VLAN gets its own filtering profile. IoT devices get aggressive blocking, personal devices get standard filtering. It runs quietly in the background and I forget it exists until someone visits and asks why YouTube has no ads on my TV. The stats page says it blocks about 15% of all DNS queries on the network. Most of that is telemetry from IoT devices phoning home.
Cloudflare sits in front of everything public. DNS, CDN, DDoS protection. I moved my domains there in 2022 and wrote about why I use Cloudflare. Nothing has changed. The free tier is still absurdly generous for solo developers.
Docker underpins everything. Every service runs as a container. I started using Docker in early 2022 and it is the single decision that made the rest of this homelab possible. Without containers, managing this many services on one machine would be a nightmare of conflicting dependencies and manual configuration. With Docker, adding a service is a YAML file and a docker compose up -d.
What I added this year
2023 was the year I stopped treating the homelab as a toy and started treating it as infrastructure. Early in the year I was focused on the network and security side. Later, the focus shifted to services and data safety.
In March, I set up proper network segmentation. Four VLANs, an OPNsense firewall, managed switch. Personal devices on one network, the homelab on another, IoT devices isolated, and a guest network that can only reach the internet. This felt like overkill at the time for someone running three Docker containers. Then I added more IoT devices and exposed more services to the internet, and I was glad the isolation was already in place.
In September, I deployed Gitea for private repositories. My homelab configuration, secrets templates, and infrastructure notes now live on my own hardware instead of GitHub. Gitea runs on 256MB of RAM and uses SQLite. It is one of those services where the effort-to-benefit ratio is hard to beat. I also set up mirroring for my important GitHub repos, so I have a local copy of everything if GitHub ever goes down or I lose access.
Between Caddy replacing Nginx in April and adding VLANs in March, the first half of 2023 was mostly about improving existing infrastructure rather than adding new services. That turned out to be time well spent. When I started adding Gitea and backups later, the foundation was solid.
In October, I finally set up automated backups with restic and rclone. This should have been the first thing I configured, not the last. I lost files earlier in the year when my SSD developed bad sectors, and that was the wake-up call I needed. Now everything gets backed up daily to an offsite location with encryption and automatic pruning. The peace of mind alone was worth the afternoon it took to set up. I should have done it in January.
What I dropped
I tried running a self-hosted wiki for a few weeks. The idea was to document my homelab setup in a structured format with diagrams, cross-linked pages, the whole thing. I picked it up, spent a weekend configuring it, wrote three pages, and never opened it again. The problem was not the software. It was that I do not need a wiki. Markdown files in a Git repo are simpler and I actually use them. Sometimes the boring solution is the right one.
I also experimented with running a small Node.js side project on the homelab instead of deploying it to the cloud. The uptime was not reliable enough. Every time I rebooted the server for updates, the app went down. I tried setting up health checks and restart policies in Docker, but the real issue was that a single machine with no redundancy is not the right place for a production-facing app.
The lesson here is that not everything belongs on the homelab. Services I use personally, where a few minutes of downtime do not matter, are perfect for self-hosting. Anything that needs to be reliable for other people belongs on proper infrastructure. Drawing that line early saved me from over-engineering things that did not need it.
What surprised me
Maintenance is bursty, not constant. Most weeks, the homelab needs zero attention. I check on things occasionally, but there is nothing to do. Then one weekend everything breaks at once. A Docker image update changes a default, Nextcloud complains about a missing PHP module, and the OPNsense firewall decides it needs a firmware update that requires a reboot. Three problems in one day, then nothing for a month. If you are considering self-hosting, know that the time commitment is not an hour every week. It is zero hours for three weeks and then four hours on a Saturday.
Storage fills up faster than you think. I started with a 256GB SSD. Between Nextcloud files, Gitea repos, Docker images, and backup snapshots, I was at 80% capacity by October. Docker images alone eat more space than you expect. Every service has an image, old images pile up, and docker system prune becomes a regular habit. I added a 1TB drive and that bought me breathing room, but I need a real storage plan for 2024.
The reverse proxy is the most important service. If Caddy goes down, nothing works. Every other service can be down for hours and I barely notice. Caddy being down means no access to anything. I learned this the hard way during an update that broke my Caddyfile syntax. Five minutes of downtime felt like an hour.
Docker makes everything possible and also makes everything fragile. Every service runs in a container, which makes deployment trivial. But it also means that a single docker compose pull can update an image that changes a default config and breaks your service silently. I have learned to pin specific image tags for anything important and test updates on a lazy Sunday afternoon, not a Wednesday night when I need the service.
The hardware
The homelab at the end of 2023 is modest. That Dell OptiPlex is still the primary machine. Intel i5, upgraded to 16GB of RAM (the original 8GB was not enough once I added Nextcloud and Gitea), a 256GB SSD for the OS and Docker, and a 1TB HDD for bulk storage. It sits under my desk next to a small managed switch and the OPNsense firewall appliance.
It is not pretty. There is no rack, no cable management to speak of, and the OptiPlex fan gets loud under load. But it runs everything I need and has been surprisingly reliable for an 80 euro used machine. The only hardware failure was the SSD developing bad sectors around month three, which prompted the backup setup. The replacement SSD was 30 euros and I cloned the existing install in about an hour.
Total cost for the year in hardware: about 180 euros. The OptiPlex was 80, the RAM upgrade was 25, the replacement SSD was 30, and the 1TB drive was 40. Power consumption sits around 30 watts idle, which adds maybe 6 euros per month to the electricity bill in Germany. Over the year that is roughly 70 euros in power, bringing the true total closer to 250 euros.
Self-hosting is not free. But compare that to paying for Google One, a Git hosting plan with unlimited private repos, a backup service, and a DNS filtering subscription. Those would easily run 15 to 20 euros per month, or about 200 euros per year. The homelab pays for itself within a year, and the hardware lasts much longer than that. The real cost is time, not money. And I enjoy the tinkering, so I do not count that as a cost.
Plans for 2024
I want monitoring. Right now I have no idea if a service is down unless I try to use it. I find out when I open Nextcloud and get a connection error, or when I try to push to Gitea and it times out. Something that checks each service every few minutes and sends me a notification when things break would solve this. This is the biggest gap in my setup.
Better hardware is on the list too. The OptiPlex has served me well, but I am starting to feel the limits. More RAM, more storage, maybe a machine that supports ECC memory for data integrity. I have been looking at used enterprise hardware on eBay. A decommissioned Dell PowerEdge or HP ProLiant can be had for a couple hundred euros and would be a significant upgrade. But nothing is decided yet, and I am trying to resist the urge to over-build.
And more services. There are things I still rely on third-party providers for that I would rather host myself. Photo management is the big one. I am also curious about self-hosted password management and media streaming, but those are further out. Each one is a weekend project and a few more gigs of RAM.
I would also like to move from one big Docker Compose file to a more organized structure. Right now everything lives in a single docker-compose.yml and updating one service risks pulling down the whole stack. Splitting services into logical groups would make updates safer and rollbacks simpler.
The goal is not to self-host everything. It is to self-host the things where control and privacy matter more than convenience. 2023 taught me where that line is, and 2024 will be about pushing it a little further.
What I would tell someone starting now
Start with backups and a reverse proxy. Not Nextcloud, not Gitea, not a media server. The unglamorous infrastructure that protects your data and makes services accessible. I did this backwards and paid for it with lost files and wasted time.
Pick boring hardware. A used office desktop for under 100 euros runs everything a beginner needs. You do not need a rack, ECC RAM, or a 10-gigabit switch to get started. You need a machine that is quiet enough to sit under your desk and cheap enough that you do not care if it dies.
Run everything in Docker from day one. It makes experimentation low-risk. If a service does not work out, you delete the container and the volume and move on. No leftover dependencies, no broken system packages.
And write things down. Every time you configure something, document the steps. A Markdown file with the Docker Compose config, the port numbers, and any gotchas you hit during setup. Future you will thank present you when something breaks at 11 PM and you cannot remember which port Gitea runs on or what environment variables Nextcloud needs.
Sources
Related posts
Self-hosting with Coolify: a PaaS on your own server
How Coolify turns your VPS into a Heroku-like platform for deploying apps, databases, and services with a clean web UI.
Backup strategies for self-hosted data
The 3-2-1 backup rule applied to self-hosted services, with practical tools and patterns I use to protect my data.
Self-hosting a media server with Jellyfin
Setting up Jellyfin to stream movies, music, and photos across all my devices without a Plex subscription.
Enjoying the blog? Subscribe via RSS to get new posts in your reader.
Subscribe via RSS