Building a Modern Home Lab with Containers, Kubernetes, and GitOps
Building a Modern Home Lab with Containers, Kubernetes, and GitOps
What You Will Learn
Why Containers Matter in a Home Lab
Containers have become the standard unit of deployment in modern infrastructure. They are lightweight, reproducible, and isolate applications from the host system. Even in a small lab, containers provide:
Consistent environments across systems
Rapid deployment and teardown
Easier upgrades and rollbacks
A direct path to cloud-native skills
Starting with containers sets the foundation for Kubernetes, GitOps, and CI/CD workflows later.
Setting Up Docker from Scratch
Prerequisites
A Linux VM or bare-metal system (Ubuntu Server 22.04 recommended)
At least 2 CPU cores and 4 GB RAM
SSH access
Install Docker Engine
sudo apt update
sudo apt install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io
Post-Install Configuration
sudo usermod -aG docker $USER
newgrp docker
Verify installation:
docker run hello-world
Managing Containers with Portainer
Portainer provides a web-based UI for managing Docker containers, images, volumes, and networks.
Deploy Portainer
docker volume create portainer_data
docker run -d \
--name portainer \
--restart always \
-p 8000:8000 -p 9443:9443 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:latest
Access Portainer:
https://:9443
From here you can visually manage containers and stacks using Docker Compose.
Deploying a Self-Hosted Password Manager
A password manager is one of the most valuable self-hosted services in a lab.
Example: Vaultwarden (Lightweight Bitwarden-Compatible)
mkdir -p ~/vaultwarden && cd ~/vaultwarden
Create docker-compose.yml:
version: '3'
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: always
ports:
- "8080:80"
volumes:
- ./data:/data
Start the service:
docker compose up -d
Access it at:
http://:8080
Add HTTPS later using a reverse proxy like Nginx Proxy Manager or Traefik.
Hosting a Small Web Service in Containers
Running a simple web service teaches containerization fundamentals.
Example: Python Flask App
app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello from your containerized lab!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY app.py .
RUN pip install flask
CMD ["python", "app.py"]
Build and run:
docker build -t lab-web .
docker run -d -p 5000:5000 lab-web
Designing a 3-Node Kubernetes Cluster
A minimal Kubernetes lab consists of:
1 control plane node
2 worker nodes
Recommended Specs (Per Node)
2 CPU cores
4–8 GB RAM
40 GB disk
You can deploy these as VMs using VMware, Proxmox, or VirtualBox.
Installing Kubernetes (kubeadm-based)
Common Setup (All Nodes)
sudo swapoff -a
sudo apt install -y containerd
Install Kubernetes tools:
sudo apt install -y apt-transport-https ca-certificates curl
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update
sudo apt install -y kubelet kubeadm kubectl
Initialize Control Plane
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
Configure kubectl:
mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Install a CNI (Flannel):
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
Join worker nodes using the kubeadm join command provided.
Introducing GitOps with Argo CD
GitOps treats Git as the single source of truth for cluster state.
Install Argo CD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Expose the UI:
kubectl port-forward svc/argocd-server -n argocd 8080:443
Login and connect a Git repository containing Kubernetes manifests. Any change pushed to Git automatically syncs to the cluster.
Building CI/CD Pipelines with GitHub Actions or GitLab
Typical Pipeline Flow
Developer pushes code
Pipeline runs tests
Docker image is built
Image is pushed to registry
Kubernetes manifests are updated
Argo CD deploys changes
GitHub Actions Example (Docker Build)
name: Build and Push
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/build-push-action@v5
with:
push: true
tags: user/lab-web:latest
This pipeline integrates directly with your GitOps workflow.
Where to Go Next
Once this lab is running, you can expand with:
Ingress controllers (NGINX, Traefik)
Persistent storage (Longhorn, NFS)
Monitoring (Prometheus, Grafana)
Logging (Loki, ELK, Graylog)
Secrets management (External Secrets, SOPS)
Final Thoughts
By starting with Docker and progressing to Kubernetes, GitOps, and CI/CD, you transform a simple home lab into a modern DevOps platform. These skills translate directly to enterprise and cloud environments, making your lab both educational and practical.
Your lab is no longer just infrastructure — it’s a living system.
Comments
Post a Comment
Got something to say? Drop a comment below — let’s chat!