Skip to content

Prepare multi-node cluster with Tailscale and Consul integration#81

Merged
ExtraToast merged 18 commits intomainfrom
add-home-node
Apr 10, 2026
Merged

Prepare multi-node cluster with Tailscale and Consul integration#81
ExtraToast merged 18 commits intomainfrom
add-home-node

Conversation

@ExtraToast
Copy link
Copy Markdown
Owner

This pull request introduces a comprehensive setup for a "home node" that acts as a Nomad and Consul client, and runs AdGuard Home for network-wide DNS-based ad blocking. It also improves the infrastructure's configuration management and validation, and introduces node-type-based scheduling constraints in Nomad jobs to better separate workloads between cloud and home nodes.

The most important changes are:

Home Node Bootstrap and Configuration:

  • Added a new setup.sh script to automate installation and configuration of Docker, Consul client, Nomad client, Tailscale, AdGuard Home, and CNI plugins, including templating configs and managing systemd services and firewall rules. This script supports idempotent operation and environment variable templating.
  • Added configuration files for Consul client (consul-client.hcl), Nomad client (nomad-client.hcl), and AdGuard Home (AdGuardHome.yaml) tailored for the home node, using Tailscale for networking and supporting Vault integration. [1] [2] [3]
  • Added systemd unit files for AdGuard Home and a scheduled update mechanism (home-node-update.service and home-node-update.timer), plus an update.sh script for daily auto-updates and reconfiguration. [1] [2] [3] [4]

Nomad & Consul Infrastructure Enhancements:

  • Updated Nomad and Consul cluster configs to support node metadata (node_type), encrypted gossip, and new host volumes (e.g., for Headscale), and improved address binding for Consul server. [1] [2] [3]

Workload Scheduling and Separation:

  • Updated all Nomad job specs for core apps and data services to include a constraint that ensures they only run on nodes with meta.node_type = "cloud". This prevents jobs from being scheduled on the home node unless explicitly allowed. [1] [2] [3] [4] [5] [6] [7] [8]

CI/CD Improvements:

  • Improved validation steps in GitHub Actions workflows (deploy.yml and full.yml) to better handle Nomad job validation errors, especially when Vault is not enabled in CI, and to fail the workflow only if there are actual errors. [1] [2]

These changes provide a robust, reproducible way to bootstrap and maintain a home node for hybrid cloud/home lab setups, while improving infrastructure validation and workload separation.

…ncryption

Add node_type=cloud meta to Nomad client config. Update Consul config
to bind 0.0.0.0 with advertise_addr and gossip encrypt placeholders.
Add Tailscale install and mesh setup to VPS setup.sh, along with UFW
rules for the tailscale0 interface.
Replace hardcoded 127.0.0.1 addresses for Loki and Tempo in the Alloy
config template with Consul service lookups. Register a tempo-otlp-http
service so Alloy can discover the OTLP ingest port via Consul catalog.
Pin apps, data, edge, mail, observability, and platform jobs to nodes
with meta.node_type=cloud so they remain on the VPS when additional
client nodes join the cluster.
Create setup.sh (install/configure/full) to bootstrap a laptop as a
Nomad+Consul client node joined to the VPS cluster over Tailscale.
Add update.sh for daily automated git pull and re-configure via systemd
timer. Include Consul client and Nomad client HCL configs with
template placeholders for Tailscale IPs and gossip key.
Pre-seed AdGuard Home with DNS-over-HTTPS upstreams, ad/tracker filter
lists, .consul domain forwarding, and DNSSEC. Add systemd units for
AdGuard Home, the home-node auto-update oneshot, and a daily timer.
Self-hosted Tailscale control server running as a Nomad service on the
VPS behind Traefik at headscale.jorisjonkers.dev. Uses SQLite for
persistence, Tailscale public DERP relays, and auto-discovered Vault
role/policy for pattern consistency.
Add headscale_data host volume to Nomad client config, create the data
directory in setup.sh, and add Headscale as first job in the infra
deploy phase with wait-for-ready in both infra and all phases.
Make --login-server conditional via HEADSCALE_URL env var in both VPS
and home-node setup scripts. When set, Tailscale clients connect to
the self-hosted Headscale instance instead of Tailscale SaaS.
Jobs that use Vault blocks fail nomad job validate in CI where no Vault
server is running. Skip these expected errors while still catching real
validation failures. Also switch from pipe-to-while to process
substitution so failures propagate correctly under set -eo pipefail.
@ExtraToast ExtraToast self-assigned this Apr 10, 2026
@ExtraToast ExtraToast added the enhancement New feature or request label Apr 10, 2026
Remove the encrypt line from Consul config when CONSUL_ENCRYPT_KEY is
not set instead of leaving an invalid placeholder. Fixes Consul startup
failure in CI where no encryption key is provided. Also fix Prettier
formatting in AdGuardHome.yaml.
Vault policy grants read access to secret/platform/media for PIA VPN
credentials. JWT role binds to the downloads Nomad job. Gluetun env
template renders PIA WireGuard credentials from Vault. All three files
are auto-discovered by setup.sh prepare-vault.
Downloads group: gluetun VPN sidecar + qBittorrent + Prowlarr in bridge
mode so all torrent/indexer traffic routes through PIA WireGuard. Sonarr,
Radarr, and Jellyfin run with host networking for direct LAN access. All
jobs constrained to node_type=home and register with Traefik tags for
external access behind forward-auth.
Samba config exposes a read-only media share for LAN devices and a 300GB
Time Machine share with Apple fruit VFS. Systemd mount unit auto-mounts
the 6TB HDD by UUID on boot. AdGuard DNS rewrites resolve media service
subdomains to the home node LAN IP so LAN clients bypass Cloudflare.
Add 6 host volumes to Nomad client config for media services and enable
NET_ADMIN/NET_RAW capabilities for gluetun VPN container. Setup script
now installs Samba, creates media directories, mounts HDD via systemd,
configures Samba users, templates AdGuard DNS rewrites, loads tun kernel
module, and adds UFW rules for Samba and Jellyfin on LAN. README covers
full VPS prep, home node bootstrap, media deployment, config migration
from existing Sonarr/Radarr/Jackett, and access patterns.
Update Samba share, setup.sh, Nomad job docs, and README to use the
existing directory layout (Completed, Downloading, Films, Series, Anime,
TimeMachine) instead of creating new directories. Rename Samba share
from [media] to [databeast] to match the existing share name.
Films, Series, and Anime shares are read-only and guest-accessible for
LAN devices. The full databeast share and TimeMachine require the media
user to authenticate.
@ExtraToast ExtraToast merged commit 1df773d into main Apr 10, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant