This is probably the last post on the home infra, at least one that I thought about from the start. I will perhaps write more if I come up with something, but probably the future ones will be less about the overall software stack and more about e.g. Lixie or some other hobby project that is related to the infra, and less about the composition of the infrastructure.

Container types, recap - and their lifetime

Types of containers: As noted in an earlier post about the architecture, the home router is running plain Debian stable, with 3 types of containers, all provisioned using pyinfra so I do not mess with them on the host itself:

  • LXC containers
  • rootful podman containers
  • rootless podman containers

I have considered also introducing Kubernetes to the mix (mostly for the practice of using it), but for now these are plain containers (not even docker-compose ones), with their parameters encoded in Python code in pyinfra configuration files, and updated as I change them. Just like many other cases of pyinfra use, I have also defined two different modes for the script. Plain call will simply ensure configurations exist (and/or are updated) to what I have on my laptop, and then there is upgrade mode in which affected containers (and packages) are upgraded if possible. I have usually manually removed the containers I do not any longer need; for this, Kubernetes with e.g. Helm charts would have been perhaps better.

Without further ado, here’s the kind of containers I use.

LXC container: OpenWrt

OpenWrt was the first container. It is also the last LXC container, as I decommissioned Adguard Home at some point due to it having some issues at restoring its state on reboot (I replaced its functionality with OpenWrt).

OpenWrt handles:

  • DHCP serving
  • firewalling
  • netflow packet capture (and forwarding of the flows to separate container using softflowd package)
  • traffic shaping (luci-app-sqm package)
  • DNS ad blocking (adblock-fast package)

Rootful podman containers

1. Jellyfin (added 202311)

One of the original goals for the home router was to offload things from devices which were not on all the time (or not present all the time at home, like my laptop). Jellyfin needed to be rootful container to have access to hardware acceleration, and it has served quite well ever since.

We do not watch media from it that often (streaming services are more useful for most part), but it is .. around. It partial broke at 10.9.0 upgrade month or two ago when DLNA support was moved to a plugin, and we accessed it mainly from TV via DLNA. Since that, I reconfigured the DLNA support and moved to using Jellyfin app on the TV too.

2. Caddy (added 202312)

Initially I did not have that strong plans about doing much HTTP serving on the router, but gradually plans changed and having certificates which just work is really nice. Due to that, I installed Caddy pretty soon as reverse proxy. It handles access for wide variety of services - some with Authelia authentication, others not, but mostly for things from my home network.

Only downside with Caddy is that it does not have ACME DNS challenge support built-in, and I am not that big fan of building my own container images for it, and due to that I am living with the ACME HTTP challenges to get certificates for the services instead. This requires bit more manual work unfortunately, as I cannot have wild-card certificate in place pointing at the home router but instead need to have per-service actual DNS entries (CNAMEs) which then point at the home router.

Pretty much everything is blocked from outside the home network.

3. Frigate (added 202403)

https://frigate.video/ has been the network video recorder of choice for me ever since I installed it. It has worked quite well, although we have had some home infrastructure issues at times with networking (there only two mesh routers, and too many places which block signal). This motivated me to add uptime monitoring tools - more about that later.

It requires root due to hardware acceleration.

Rootless podman containers

This is the zoo, as I have installed (and subsequently uninstalled) quite many of them.

  1. Home Assistant has been there from the start (202311). It is primarily used as visualization system, although with it I sometimes e.g. turn off the TVs. A lot of the home automation still depends on Hue, as I have been too lazy to migrate to HA’s automations and Hue works well enough. We shall see if this changes as Hue seems to be hell bent on changing their offering to be more cloud-driven.
  2. Grafana Loki container was added in February for log storage, as I was curious about it. .
  3. https://grafana.com/grafana/ was added about same time, for dashboarding and viewing metrics and logs.
  4. VictoriaMetrics was also added at same time. for metrics storage.
  5. At end of February, I wrote custom nfcapd container to store netflow logs in the filesystem which invokes nfcapd in phaag/nfdump: Netflow processing tools
  6. In March, Eclipse Mosquitto (MQTT) container was added for integration of Home Assistant and Frigate
  7. VictoriaLogs container was also added in March, to provide competing log storage solution for testing purposes (they both are fed from same Vector pipeline described in earlier blog post).
  8. Authelia was added in April, to provide authentication and authorization for some services accessed via Caddy. Unfortunately it is somewhat partial solution still, as many of the services I use do not support single sign-on, or external user definitions in general.
  9. Heimdall Application Dashboard was also added in April, to keep track of all services I have at home and to have one-stop place to visit them. It has worked quite well.
  10. VaultWarden for secret storage was added around same time too, as I was moving away from 1Password for various reasons (noted in earlier posts).
  11. Shiori (Go-based bookmark manager with some offline storage options) was added around then too, but I also decommissioned it later. It did not have good way of ingesting bookmarks (I prefer an app),
  12. Ollama was also added in April, as I wanted to experiment with running local models. On this particular hardware they are quite slow, though, and I have not really used it much.
  13. In May, I added Uptime Kuma for uptime monitoring as I was curious about how bad mesh networking was, and how bad the availability of some of the network nodes was due to that. The tool was quite good, but unfortunately only clickops-able, and as my set of containers changes over time quite often, being able to do it programmatically was preferable so it was also decommissioned shortly after.
  14. conduit.rs container was added at end of May, like some of the other Matrix pieces too (that I have written about in an earlier post). This was replaced by conduwuit 🏳️‍⚧️ 💜 🦴
  15. Discord bridge for Matrix
  16. Slack bridge for Matrix
  17. Signal bridge for Matrix
  18. Synapse server for Matrix (an experiment, I chose not to use it for long)
  19. matrix-webhook
  20. linkding was added as replacement for Shiori (bookmark manager). On the plus side, it has API. The iOS app is quite limited unfortunately, so still looking for ‘the perfect solution’ (smirk).
  21. gatus uptime monitor replaced uptime-kuma
  22. In June, conduwuit 🏳️‍⚧️ 💜 🦴~~ replaced Conduit.

Summary

When adding container as code is ~dozen lines of Python, it is quite easy to add bunch of them. Idle containers do not consume much resources though, as the current infrastructure is still not particularly loaded, so there will be most likely more containers in its future:

CPU load is mainly Frigate dealing with video cameras over the network, and the system portion is its hardware accelerated object detection.