Managing containers with Portainer for HomeLab
published: ⏰ 4In continuation of the article CI/CD with Gitea for HomeLab, we’ll look at an example of a method for remotely managing services deployed as Docker containers. It doesn’t always make sense to deploy “heavyweight” container orchestrators like K8S, K3S, Swarm, and the like. One alternative will be discussed.
Introduction
Those who use modern NAS have likely already used Portainer, which comes out of the box. I decided to give it a try for container management.
Portainer is a web interface for managing Docker (and, optionally, Kubernetes). Its main advantages for a home environment are:
| Function | Description |
|---|---|
| 💻 Visual interface | There is no need to keep in mind the commands docker ps, logs, exec, docker-componse up and others. |
| 🛠️ Stack management | It’s quite easy to manage Docker Compose configurations from the web interface. Again, no console required. |
| 🌐 Cluster of nodes | If you have several servers with containers, you can combine them under one control panel via agents. |
| 🧩 Templates | There are templates, a kind of Helm analog, OpenShift templates that allow you to quickly deploy popular services. You can create your own. |
| 🆓 Community Edition | Completely free for personal use, but there is an option to get a BE license for 3 nodes. |
CE’s functionality is sufficient for home use, but if you want more, you can request a 3-node license – Get 3 Nodes Free.
Example of service organization
Currently, everything is deployed on a single server without additional nodes.
[Docker Host (HomeLab Server)]
├── Portainer Server (main container)
├── DevOps Utility Services (Gitea, Nexus, SonarQube, Structurizr, ...)
├── Infrastructure Services (Traefik, Pi-hole, Poste.io, ...)
├── Security (Vaultwarden, Keycloak, ...)
└── Applications (tB.kbase, ...)I don’t use Portainer Agent, although it’s recommended to deploy them on each node, even if there’s only one.
I have local DNS records (Pi-hole) configured for most services and load balancing via Traefik for convenience. You can do without this, but you’ll have to monitor the assigned ports to avoid conflicts.
Installation and configuration
As I mentioned earlier, I don’t use agents. They’re useful when you have multiple servers that need to be managed from a single location.
Configuration can be done according to the official documentation:
I mount /var/run/docker.sock directly in Portainer Server, so when starting the server, I just need to add the
environment.

Stacks (Docker Compose)
A stack in Portainer is essentially just a Docker-compose file that can be loaded and run. There are two types:
- Manually launched outside of Portainer, with limited management capabilities.
- Created within Portainer, which can be managed entirely through the UI.

In the screenshot, all services except tekblueprint are running outside of Portainer, but Portainer can still see them
and manage them.

When creating a stack within Portainer, you have complete control. Docker Compose and environment variables can be edited and deployed directly from the interface. This is quite convenient if you need to quickly check something.
The only thing required is access to the host filesystem if you need to mount files or folders in a container.

Container management
Managing running containers is also quite convenient, similar to Docker Desktop or Services in IntelliJ IDEA. In principle, Portainer can easily be used as a replacement for Docker Desktop, Rancher Desktop, Podman Desktop, etc.
You can view a full list of containers and their status.

And inside each of them there is more detailed information, where you can manage running containers, view logs, etc.

Third-party repositories
You can add third-party repositories to Portainer to use as an image source. This is especially convenient for local development if you have your own images that are built using CI/CD.

Auto-updating images
I haven’t configured this yet, but you can use the auto-update feature via Watchtower to automatically update images. This means Watchtower will automatically update images if they’ve been updated in the registry (public or private).
You can control auto-updates using labels in Docker Compose:
version: '3.8'
services:
watchtower:
image: someimage
restart: always
labels:
- "com.centurylinklabs.watchtower.enable=true"Conclusion
Overall, it’s a pretty handy tool for home use, especially if you’re not entirely comfortable managing everything from a console. But it’s certainly no replacement for K8s, K3s, and the like.