When people talk about self-hosting, it's usually around media servers, photo backups, and cloud storage replacements. And I agree, those are important, and that’s why I built my own home server in the first place.

But a home server can run dozens of containers and still feel surprisingly amateur. Not because the applications themselves are bad, but because managing them often requires a lot of guesswork.

Over time, I have experimented with several tiny utility containers that made my server feel more mature, and I eventually settled on four. They’re small, easy to deploy, and arguably some of the most useful services in my stack that actually help me understand and manage everything else.

Vaultwarden

The password manager you keep putting off

I have been using Bitwarden Premium for many years as my default password manager. The world has recently been moving from passwords and 2FAs to a single passwordless login. And frankly, it has been convenient, too. But it also came with a dependency on a particular device. For example, if I created a passkey on my iPhone, I would need my iPhone each time to log in to that account.

That’s when I decided to centralize the process. Bitwarden also supports passkeys, but lately, I have been trying to move my daily-used services to my homelab server. Bitwarden did come with a self-host option, but the server is heavy (needs over 1GB to run comfortably), and that’s not worth it for my old Debian server. Then I came across Vaultwarden, an unofficial Bitwarden-compatible server written in Rust that takes less than 50MB of memory while running. And since it’s Bitwarden-compatible, I could use the same Bitwarden apps and browser extension to use it.

All my credentials now live on my hardware, not someone else's server. Hard to argue with hosting your own passwords and passkeys on your own hardware. I have been using it for several months, and now I think I should have done this earlier.

services:
 vaultwarden:
 image: vaultwarden/server:latest
 container_name: vaultwarden
 ports:
 - "8090:8080"
 volumes:
 - /opt/vaultwarden/data:/data
 environment:
 - DOMAIN=https://your-domain.com
 - ROCKET_PORT=8080
 - ADMIN_TOKEN=your_secure_admin_token
 - WEBSOCKET_ENABLED=true
 - PASSWORD_MIN_LENGTH=8
 restart: unless-stopped
Vaultwarden
Key highlights
Self-hosted Bitwarden alternative

Beszel

Lighter than what it replaced

These days, monitoring a server feels like flying an Airbus just to check the weather. It is far more complicated and takes more resources than the actual service it’s monitoring. Why would I want a monitoring tool that either showed me nothing useful or had full-blown enterprise-grade stats that I didn’t need? I have been searching for a monitoring tool that could answer my one question: is my server healthy? Beszel answered that exactly, without overwhelming the whole process.

Beszel depends on two components — a lightweight agent running on the server being monitored and a simple GUI dashboard that displays the metrics. Combined, they don’t take more than 40MB of memory. And the UI is simple enough to glance at the numbers and immediately know what needs my attention. The hub focuses on four core metrics: CPU, RAM, disk, and network usage, which is exactly what I need to know if my server is healthy. I have already used enterprise-level monitoring services like Datadog and Zabbix for large-scale infrastructure, but for a small homelab, they are overkill.

services:
 beszel-agent:
 image: henrygd/beszel-agent:latest
 container_name: beszel-agent
 network_mode: host
 volumes:
 - /var/run/docker.sock:/var/run/docker.sock:ro
 - beszel_agent_data:/var/lib/beszel-agent
 environment:
 - HUB_URL=https://your-beszel-hub-url
 - LISTEN=45876
 - KEY=your_ssh_ed25519_public_key
 - TZ=Asia/Kolkata
 restart: unless-stopped

volumes:
 beszel_agent_data:
Beszel

Beszel is a lightweight server and container monitoring utility that can be used to track multiple servers via a single dashboard. 

Watchtower

Updates itself. Updates everything.

I always say in my articles that deploying a service and making it feel like a cloud service is one thing, and keeping it running is a different story. New homelabbers follow a pattern: deploy and forget. Manually updating containers is something most homelab owners either forget or defer. Even I am one of them. I have more than 15 active services in my stack, but I barely check for any updates. The only time I update something is when a pop-up appears on my screen asking me to.

That’s where Watchtower came in. It monitors Docker images and updates the containers automatically. The first time I ran it, it scanned 21 images and updated 15 of them. So, even I — someone who always talks about security and privacy constantly — am lazy enough not to update the services I use regularly. The interesting fact is that it takes less than 20MB of runtime memory. So, it barely dents your memory; you just need to deploy it once and forget about it. And you don’t need to worry about it forcing updates at inconvenient times, Windows-style. I scheduled it to run at a specific time, and it sticks to that.

services:
 watchtower:
 image: containrrr/watchtower
 container_name: watchtower
 volumes:
 - /var/run/docker.sock:/var/run/docker.sock
 environment:
 - WATCHTOWER_SCHEDULE=0 30 10 * * *
 - WATCHTOWER_CLEANUP=true
 - DOCKER_API_VERSION=1.44
 restart: unless-stopped
Watchtower

Watchtower automatically updates your Docker containers on a schedule, cleans up old images, and keeps self-hosted stacks current without manual intervention.

Speedtest Tracker

Your ISP doesn't get to lie anymore

Ever encountered inconsistent download or upload issues from your ISP, and when you complain, the ISP asks for a speed test report, declares everything fine, and closes the ticket? Happens to me all the time. And I never have any proof to show them. That’s when I came across Speedtest Tracker.

Deals

Save on Storage & Networking deals for your homelab

Find discounts and offers on routers, NAS, switches, and cables to stabilize and speed up your home server. Shop storage & networking deals to cut costs on backups, faster LAN, and reliable infrastructure - compare savings and accessories now.

It’s a simple tracker that runs on a fixed schedule, logs every result, and builds a history. Not just download and upload speeds, but also latency, jitter, and packet loss. And it is accessible through a clean web dashboard. Yes, it is a little heavier than the other three on this list, taking around 120MB of memory, but that's because it's the only one with a database backing the historical logs.

When something feels wrong, I can check historical data before changing settings or restarting containers. It shifts troubleshooting from guesswork to evidence. Speedtest Tracker won't make your internet faster, but it tells you exactly when, where, and how your performance changes over time.

services:
 speedtest-tracker:
 image: lscr.io/linuxserver/speedtest-tracker:latest
 container_name: speedtest-tracker
 ports:
 - "8765:80"
 volumes:
 - speedtest-config:/config
 environment:
 - PUID=1000
 - PGID=1000
 - APP_KEY=base64:your_generated_app_key
 - APP_URL=http://your-server-ip:8765
 - DB_CONNECTION=sqlite
 - SPEEDTEST_SCHEDULE=0 */6 * * *
 restart: unless-stopped

volumes:
 speedtest-config:
Speedtest Tracker

Speedtest Tracker is a self-hosted application that monitors the performance and uptime of your internet connection.

The boring containers that keep everything else running

I didn’t add all these services at once. They get added to my stack gradually whenever I feel like I need them. Individually, none of them are particularly exciting. But together, they improve visibility, maintenance, and troubleshooting, with no guesswork required. The interesting part is that none of these Docker containers are resource-intensive. Some of them consume less memory than a browser window, and none of them are why anyone starts self-hosting, but they solve operational problems that appear every day that can pile up over time.