Skip to main content

The Hill90 Homelab

Hill90 is homelab infrastructure on a single Hostinger VPS running AlmaLinux 10. It is the automation that takes a bare VPS to a running, TLS-terminated, observable, Tailscale-secured Docker host — and keeps it there. It is not a single-app host. An AI agent application previously ran here. It was shelved in June 2026 and removed from the repository in July 2026. See Decisions for the record, and the AI Application section for what it was. The infrastructure lives in the jonhill90/Hill90 repository. This site is the narrative layer; the operational depth stays in that repo, beside the code it describes.

A personal cloud platform

The organising idea is capability parity with Azure. Jon works with Azure professionally, and each platform service here is the open-source counterpart of a primitive he uses at work — chosen so the concepts, failure modes and operational habits transfer in both directions. That framing is also the honest answer to why a homelab runs an identity provider at all. It is not single sign-on for four dashboards — the infrastructure dashboards deliberately keep local auth behind Tailscale. It is capability parity plus real multi-user support: family accounts, demo accounts and test accounts, a realm per consumer, with the AI application as one tenant among several rather than the reason the platform exists. The reasoning behind the mapping, and the consequences that follow from it, are recorded in the Hill90 repository’s decision records rather than restated here.

What is missing

The parity is partial, and the gaps are real rather than pending:
  • No container registry. Nothing corresponds to Azure Container Registry; images come from public registries and GHCR.
  • No messaging tier. Nothing corresponds to Service Bus or Event Hubs.
  • No object storage. MinIO went with the application teardown and has not returned.
  • Keycloak and Postgres are being restored, not running. They are absent from the current stack. Everything on this page under “What runs” is what exists today.

What runs

Ten containers across three stacks. The edge stack owns all three Docker networks; the other two attach to them as external. On a fresh host, edge deploys first.

Surfaces

Everything with a dashboard is reachable only over Tailscale (100.64.0.0/10), enforced by a Traefik IP-allowlist middleware on top of the host firewall. Only ports 80 and 443 are open publicly.

The stack

  • Host — AlmaLinux 10 on a Hostinger VPS
  • Runtime — Docker Engine and Docker Compose
  • Edge — Traefik v2.11 with Let’s Encrypt, HTTP-01 for public hostnames and DNS-01 for Tailscale-only ones
  • Observability — Prometheus, Grafana, Loki, Tempo, plus Promtail, node-exporter and cAdvisor
  • Secrets — OpenBao as the intended runtime store, SOPS + age for bootstrap and disaster recovery
  • Admin access — Tailscale VPN, SSH by key only
  • Provisioning — Ansible playbooks driven by the Hostinger and Tailscale APIs
  • CI/CD — GitHub Actions
  • DNS — Hostinger DNS API via scripts/hostinger.sh

The one piece of application code

services/dns-manager is the only application code in the infrastructure repository — a small Flask webhook implementing Traefik’s httpreq DNS-01 provider against the Hostinger DNS API. Without it, certificates for Tailscale-only hosts cannot issue, because those hosts have no public A record for HTTP-01 to validate against. See Certificates.

Where to go next

Architecture

Network topology, isolation boundaries, and what each service is responsible for.

Local development

Run the whole stack on a Mac with one command. No secrets, no VPS.

Operations

Deploy, rebuild, back up, recover.

Secrets

The vault model, and an honest account of what the vault holds today.