Docs, config, scripts and whatnots for everything being set up and experimented with at my home lab.
- Hardware, Network & Services — Hardware inventory, network architecture, service guides
- Overview — Host inventory and setup
- Pi-hole — Pi-hole + Unbound setup, Tailscale DNS
- k3s Cluster — k3s install, Tailscale, monitoring stack
- MCP Server — Claude Code MCP integration for Pi-hole and UniFi
All homelab related host configuration and SSH keys can be found in ./config/ssh.config. They can be simply symlinked into ~/.ssh/config:
# Write the public key from 1Passowrd to a file
op read "op://Private/GitHub 1P SSH/public key" > ~/.ssh/gh1p.pub
# Symlink the ssh config
ln -sf ~/src/homelab/.config/ssh.config ~/.ssh/configAll of them are NFS entries in .config/etc.fstab — the UNAS
shares, plus k3s-node-02's DAS array at /mnt/n02r0. The workstation has its own
local /mnt/r0, so the node's array cannot use that path.
sudo mkdir -p /mnt/nas/{backups,media} /mnt/n02r0
# copy the entries into /etc/fstab, then
sudo systemctl daemon-reloadThe DAS export is created by ansible/das-raid.yaml
(--tags nfs) and carries the mp option, so it exists only while the array is
actually mounted on the node.
Some tools need to be installed locally to be able to manage the homelab setup, namely:
- Ansible
- sshpass
- Docker + compose plugin
- k9s
- age
- sops
Run the install script to set everything up in one shot:
./scripts/install.shOr install manually:
# Ansible + sshpass
sudo dnf install -y ansible sshpass
# Docker + compose plugin
sudo dnf config-manager addrepo --from-repofile https://download.docker.com/linux/fedora/docker-ce.repo
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
sudo usermod -aG docker $USER # log out and back in after this
# k9s
sudo dnf install -y k9s
# age (encryption tool used by SOPS)
sudo dnf install -y age
# sops (secret file encryption)
SOPS_VERSION=$(curl -s https://api.github.com/repos/getsops/sops/releases/latest | grep tag_name | cut -d '"' -f 4)
curl -LO "https://github.com/getsops/sops/releases/download/${SOPS_VERSION}/sops-${SOPS_VERSION}.linux.amd64"
sudo install -m 755 "sops-${SOPS_VERSION}.linux.amd64" /usr/local/bin/sops
rm "sops-${SOPS_VERSION}.linux.amd64"
# Ansible community SOPS collection
ansible-galaxy collection install community.sopsSecrets (API tokens, passwords, credentials) are encrypted with SOPS + AGE. Encrypted files follow the naming convention *.sops.yaml (or .sops.json, .sops.env).
See .sops.yaml for instructions on how to manage AGE keys in this repository.
Export SOPS_AGE_KEY to the environment:
# Loads the AGE private key from 1Password so SOPS can decrypt secrets
# without ever writing the key to disk.
#
# Update the op:// path to match your vault and item name.
# To find the correct path: op item get "<item-name>" --format json
export SOPS_AGE_KEY=$(op read "op://<vault>/<item>/AGE/secret key")