- Ubuntu 24.04 LTS
- Homebrew
Cloudflare DNS allows you to easily access your self-hosted services via a public IP as well as protect your domain from external attacks. To setup Cloudflare:
- Buy a domain name
- Onboard your domain to Cloudflare: https://developers.cloudflare.com/fundamentals/manage-domains/add-site/
- Set SSL/TLS mode to
Full (strict)mode - Add @
Arecord that points to your public IP - Add *
CNAMErecord that points to @. - (optional) Enable the proxy status for your records to protect your domain.
- Create an API token:
- Go to
User Profile > API Tokens > API Tokens - For Permissions, select:
Zone - DNS - EditZone - Zone - Read
- For Zone Resources, select:
Include - All Zones
- Save the token to the Cloudflare Kubernetes Secret.
AWS SES SMTP enables reliable email delivery for your self-hosted services. To setup SES:
- Create an AWS account and verify your domain in SES:
- Go to
AWS SES Console > Verified identities - Click "Create identity" and select "Domain"
- Add the required DNS records to your domain
- Go to
- Request production access (move out of sandbox mode):
- Go to
AWS SES Console > Account dashboard - Click "Request production access" and submit the form
- Go to
- Create SMTP credentials:
- Go to
AWS SES Console > SMTP settings - Click "Create SMTP credentials"
- Save the SMTP credentials to SMTP Kubernetes Secret
- Go to
- Configure your applications to use SES SMTP:
- SMTP endpoint:
email-smtp.<region>.amazonaws.com - Port: 587 (STARTTLS) or 465 (TLS)
- Use the SMTP credentials from step 3
- SMTP endpoint:
ZFS allows you to increase the reliability and performance of existing drives. To setup ZFS:
- SSH into each host that supports ZFS.
- Install ZFS
sudo apt install zfsutils-linux - List the drives using stable identifiers
ls -lld /dev/disk/by-id/* - Create and configure a ZFS pool
sudo zpool create -m /zfs-pool-dummy-mountpoint-do-not-use storage mirror SOME_DEVICE_1 SOME_DEVICE_2 sudo zfs set compression=lz4 storage sudo zfs set atime=off storage - Generate an encryption key:
sudo openssl rand -out /root/keyfile-zfs 32 - (important) Backup the generated key
- Create an encrypted dataset:
sudo zfs create -o encryption=on -o keylocation=file:///root/keyfile-zfs -o keyformat=raw -o mountpoint=/storage storage/encrypted
Tailscale allows you to access your hosts from anywhere without exposing static ports. To setup Tailscale:
- Create an account at https://login.tailscale.com.
- Add the following ACL rule at https://login.tailscale.com/admin/acls/file:
"tagOwners": { "tag:ansible": ["autogroup:admin", "autogroup:owner"], }, - Create an OAuth client at https://login.tailscale.com/admin/settings/oauth:
- Enable the Write permission for Device/Core, and add the "tag:ansible" tag.
- Enable the Write permission for Keys/Auth Keys, and add the "tag:ansible" tag.
- Save and write down the OAuth client secret.
all:
vars:
k3s_control_node: false
skip_system_setup: false
skip_firewall_setup: false
skip_vpn_setup: false
skip_k8s_setup: false
skip_binary_update: false
manifest_only_setup: false
display_k8s_dashboard_password: false
timezone: America/Vancouver
tailscale_oauth_secret: "some_secret"
chartValuesOverrides:
fqdn: "example.com"
storageLocation: /storage
# Optional: disable unwanted applications
applications:
crowdsec:
enabled: false
# There must be a minimum of 3 controllers and the number must be odd for etcd to work
k3s_cluster:
hosts:
raspi:
k3s_control_node: true
labels:
- local=true
big_manager:
k3s_control_node: true
labels:
- nas=true
- local=true
small_manager:
k3s_control_node: true
labels:
- public=true
- local=true
big_server:
labels:
- local=true
# Optional
headscale:
hosts:
headscale_control_server: {}public: Add to nodes that will receive external traffic directly.nas: Add to nodes that should store heavy files.local: Add to nodes that are local to the site; useful when having a hybrid cloud.
plugin: aws_ec2
regions:
- us-east-1
- us-east-2
filters:
instance-state-name: running
tag:Category:
- home-cloudMake sure to follow the application specific setup guide below before performing the initial deployment.
Run ansible-playbook setup_cluster.yml -i inventory_static.yml -i inventory_ec2.yml
To ensure no down time, make sure all the machines have key expiry disabled: https://tailscale.com/kb/1028/key-expiry#disabling-key-expiry.
After deployment, services are accessible at: https://dash.<your-domain>.
Provided an S3-compatible bucket, the cluster and select volumes will be backed up by Velero and Kopia.
One can use the Kopia or Kopia UI to access the backed up files manually. Simply provide Kopia with the bucket, the keyID and keySecret to access the bucket, the respository encryption key and kopia/default/ as the prefix.
Read https://velero.io/docs/v1.16/restore-reference/.
In a typical home network setup, when HTTP(S) ports are forwarded to a specific machine, the entire service becomes unavailable if that machine goes offline. However, if your router supports OpenWRT (such as the GL-MT6000), you can install HAProxy to address this issue. For optimal security and high availability, configure the proxy as follows:
/etc/haproxy.cfg:
global
log /dev/log local0
log-tag HAProxy
maxconn 32000
ulimit-n 65535
uid 0
gid 0
nosplice
daemon
defaults
log global
mode tcp
timeout connect 5s
timeout client 24h
timeout server 24h
option redispatch
retries 3
option log-health-checks
option dontlognull
option dontlog-normal
frontend http-in
bind :9080
mode tcp
default_backend http-servers
frontend https-in
bind :9443
mode tcp
default_backend https-servers
frontend mx-in
bind :2465
mode tcp
default_backend mx-servers
frontend smtp-in
bind :9465
mode tcp
default_backend smtp-servers
frontend imap-in
bind :9993
mode tcp
default_backend imap-servers
backend http-servers
mode tcp
balance roundrobin
option httpchk
http-check connect port 8080
http-check send meth GET uri /ping
default-server inter 3s fall 3 rise 2
server s1 192.168.1.11:80 send-proxy-v2 check
server s2 192.168.1.12:80 send-proxy-v2 check
server s3 192.168.1.13:80 send-proxy-v2 check
backend https-servers
mode tcp
balance roundrobin
option httpchk
http-check connect port 8080
http-check send meth GET uri /ping
default-server inter 3s fall 3 rise 2
server s1 192.168.1.11:443 send-proxy-v2 check
server s2 192.168.1.12:443 send-proxy-v2 check
server s3 192.168.1.13:443 send-proxy-v2 check
backend mx-servers
mode tcp
balance roundrobin
option tcp-check
tcp-check connect port 2465
default-server inter 3s fall 3 rise 2
server s1 192.168.1.11:2465 send-proxy-v2 check
server s2 192.168.1.12:2465 send-proxy-v2 check
server s3 192.168.1.13:2465 send-proxy-v2 check
backend smtp-servers
mode tcp
balance roundrobin
option tcp-check
tcp-check connect port 465
default-server inter 3s fall 3 rise 2
server s1 192.168.1.11:465 send-proxy-v2 check
server s2 192.168.1.12:465 send-proxy-v2 check
server s3 192.168.1.13:465 send-proxy-v2 check
backend imap-servers
mode tcp
balance roundrobin
option tcp-check
tcp-check connect port 993
default-server inter 3s fall 3 rise 2
server s1 192.168.1.11:993 send-proxy-v2 check
server s2 192.168.1.12:993 send-proxy-v2 check
server s3 192.168.1.13:993 send-proxy-v2 check
With this configuration, all incoming HTTP(S) traffic must now flow through the gateway ports 9080/9443 where HAProxy is installed. This is because the router forwards traffic to the HAProxy instance, which then distributes it to the backend servers. This setup ensures that even if one server goes down, the service remains available, as HAProxy will route traffic to the remaining operational servers.
To opt-out of this feature, set behindTcpProxy to false.
When using a TCP router, make sure to set the proxy protocol version to 2:
proxyProtocol:
version: 2
By default, all applications are enabled. To selectively disable applications, edit the values file accordingly. Some applications are mandatory for the cluster to function and cannot be disabled.
These applications provide essential cluster functionality.
Reverse proxy and load balancer.
Setup Traefik admin secret for dashboard access.
Access at https://traefik.<your-domain>.
Automatic TLS certificate management.
Setup Cloudflare secret with API token for DNS-01 challenge.
Kubernetes descheduler for rebalancing pods.
Automatically evicts pods to optimize cluster resource usage.
Dynamic DNS client for Cloudflare.
Automatically updates DNS records with your public IP. Uses the Cloudflare secret configured in cert-manager setup.
Kubernetes operator for managing secrets from external sources.
Automatically generates passwords and secrets for applications.
Kubernetes operator for mirroring secrets and configmaps across namespaces.
Kubernetes operator for automatically reloading pods when secrets or configmaps change.
Detects hardware features and labels nodes accordingly.
Dynamic local storage provisioner for Kubernetes.
Provides storage classes: local-path-ephemeral, local-path-persistent, local-path-persistent-namespaced.
SSO and identity provider with LDAP support.
Open https://auth.<your-domain>/if/flow/initial-setup/ to perform the initial setup. Note: the trailing / is important.
Crowdsourced intrusion prevention system.
- Sign-in to Crowdsec dashboard: https://app.crowdsec.net/sign-in
- Write down the enroll key from https://app.crowdsec.net/security-engines
- Setup Crowdsec secret with
enroll_keyand a randomly generatedbouncer_key.
GitOps continuous delivery tool for Kubernetes.
Open https://argo.<your-domain> to perform the initial setup.
Media server for streaming movies, TV shows, and music.
Access at https://jellyfin.<your-domain> to perform the initial setup.
Media request management for Jellyfin.
Access at https://jellyseerr.<your-domain> to perform the initial setup.
Sonarr: TV show monitoring and management.
Radarr: Movie monitoring and management.
Bazarr: Subtitle management for your media library.
Prowlarr: Centralized indexer management for Sonarr and Radarr.
Tdarr: Automated media transcoding and optimization.
Setup Arr secret with API keys for each service.
Subtitle management for movies and TV shows.
Access at https://bazarr.<your-domain>.
Indexer manager for Sonarr and Radarr.
Access at https://prowlarr.<your-domain>.
Movie collection manager.
Access at https://radarr.<your-domain>.
TV show collection manager.
Access at https://sonarr.<your-domain>.
Automated media transcoding.
Access at https://tdarr.<your-domain>. Setup Arr secret with Tdarr API key.
Book and audiobook management.
Access at https://lib.<your-domain> to perform the initial setup.
BitTorrent client.
Setup Transmission secret with credentials.
Access at https://transmission.<your-domain>.
Torrent ratio management.
Setup JOAL secret with access token.
Access at https://joal.<your-domain>.
Proxy server to bypass Cloudflare protection.
Used by Prowlarr for indexers behind Cloudflare.
VPN client container for routing traffic through VPN.
- Create an account at a supported VPN provider: https://github.com/qdm12/gluetun-wiki/tree/main/setup/providers
- Setup Gluetun secret.
Self-hosted photo and video backup solution.
Login to https://immich.<your-domain> to perform the initial setup.
Self-hosted file sync and collaboration platform.
Login to https://nextcloud.<your-domain> to perform the initial setup.
Web-based file manager.
Login to https://filebrowser.<your-domain> with default credentials (admin/admin), then change password.
S3-compatible object storage.
Setup MinIO secret with access credentials.
Access at https://minio.<your-domain>.
Home automation platform.
Login to https://ha.<your-domain> to perform the initial setup.
Workflow automation tool.
Access at https://n8n.<your-domain>. Create an account on first visit.
Self-hosted notification server.
Login to https://gotify.<your-domain> with default credentials (admin/admin), then change password.
Minimalist RSS feed reader.
Setup Miniflux secret with admin credentials.
Access at https://miniflux.<your-domain>.
Internet speed monitoring. To setup:
- Run
echo -n 'base64:'; openssl rand -base64 32;to generate an app key. - Setup Speedtest Tracker secret with app key.
Access at https://speedtest.<your-domain>.
Get notified when free games from Epic Games Store are available.
- Setup an application on Gotify for Epic Games Free Games.
- Setup Epic Games secret.
Access at https://epicgames-freegames.<your-domain>.
Coding activity tracker.
Setup Wakapi secret with password salt.
Access at https://wakapi.<your-domain>.
Infrastructure resource modeling and IPAM.
Access at https://netbox.<your-domain>. Default credentials: admin/admin.
Inventory management system.
Setup InvenTree secret with admin credentials.
Access at https://inventree.<your-domain>.
Open-source ERP and CRM.
Access at https://odoo.<your-domain>. Default credentials: admin/admin.
PDF manipulation tools.
Access at https://pdf.<your-domain>.
PostgreSQL database management and backup operator.
- Create an account with S3 or an S3 compatible storage such as Backblaze B2.
- Create a bucket where your data will be backed up.
- Create an access key for the bucket.
- Setup PostgreSQL secrets with S3 credentials and encryption key.
PostgreSQL administration tool.
Setup pgAdmin4 secret with admin password.
Access at https://pgadmin4.<your-domain>.
In-memory data store.
Management UI for Redis.
Access Redis Insight at https://redis.<your-domain>.
3D printer web interface.
Access at https://octoprint.<your-domain>. Create an account on first visit.
3D printer monitoring with AI failure detection.
Setup Obico secret with Django secret key.
Access at https://obico.<your-domain>.
Multi-purpose Discord bot. To setup:
- Create a bot account by following https://docs.discord.red/en/stable/bot_application_guide.html.
- Setup RED secret with Discord bot token.
Minecraft Bedrock Edition server.
Access via port 30778 (UDP).
Web-based Kubernetes management interface.
To get the dashboard password, run the playbook with display_k8s_dashboard_password: true.
Access at https://kubernetes.<your-domain>.
Automatically generates a dashboard from Ingress annotations.
Access at https://dash.<your-domain>.
Kubernetes backup and disaster recovery.
- Create an account with S3 or an S3 compatible storage such as Backblaze B2.
- Create a bucket where your data will be backed up.
- Create an access key for the bucket.
- Setup Velero secrets with S3 credentials and encryption key.
Monitoring and observability stack.
Setup Prometheus secret with Grafana admin credentials.
Access Grafana at https://grafana.<your-domain>.
Log aggregation system.
Setup Loki secret with MinIO credentials.
Integrated with Grafana for log visualization.
Distributed tracing backend.
Setup Tempo secret with MinIO credentials.
Integrated with Grafana for trace visualization.
Kubernetes node problem detector.
Detects and reports node-level issues to the cluster.
Prometheus exporter for Dell iDRAC metrics.
Setup iDRAC Exporter secret with iDRAC credentials.
Prometheus exporter for IPMI metrics.
Setup IPMI Exporter secret with IPMI credentials and target hosts.
Kubernetes device plugin for discovering and using edge hardware.
Automatically discovers USB devices like webcams and serial devices.
Intel GPU device plugin for Kubernetes.
Enables GPU acceleration for applications like Jellyfin, Immich, and Tdarr.
NVIDIA GPU device plugin for Kubernetes.
Enables GPU acceleration for applications like Jellyfin, Immich, and Tdarr.
AMD GPU device plugin for Kubernetes.
Enables GPU acceleration for applications like Jellyfin, Immich, and Tdarr.
All-in-one email server with SMTP, IMAP, and JMAP support.
Setup Stalwart secret with S3 credentials and admin password.
Access at https://mail.<your-domain>.
Install aws-smtp-relay on your AWS account to relay emails from and to your Stalwart instance.
When using Cloudflare proxy, ensure CNAME mail.example.org record is not proxied through Cloudflare, otherwise the proxy will block the mail traffic ref.
Open https://mail.<your-domain>/manage/dns/<your-domain>/view to download the zone file to import to the DNS provider.
For this setup, replace:
- Replace
MXrecord withinbound-smtp.<aws-region>.amazonaws.com - Replace
TXTrecords that containv=spf1withv=spf1 include:amazonses.com ~all - Skip
TLSArecords
References: