2f0d0b5e4c
Replaces the Helm/k3s setup with a declarative NixOS configuration targeting
a Raspberry Pi 4. Services run as podman containers under systemd, with data
on an external HD at /mnt/data. Key components:
- flake.nix: multi-host flake with pi-main (aarch64) and a placeholder for a
second machine
- modules/common.nix: shared system config (nix, podman, sops, SSH)
- modules/storage.nix: external HD mount with per-service subdirs
- modules/caddy.nix: Caddy with cloudflare DNS-01 ACME + authelia forward_auth
- modules/cloudflared.nix: Cloudflare tunnel for remote access
- modules/backup.nix: restic daily backups with NC maintenance mode pre-hook
- modules/services/{openldap,authelia,gitea,nextcloud,phpldapadmin}.nix: core services
- modules/services/{jellyfin,transmission}.nix: media services (disabled by default)
- secrets/: sops-nix scaffold with .sops.yaml age key config
- hosts/pi-main/: hardware config + service selection for the Pi
- PORTING.md: step-by-step migration guide (SD card → data restore → verify)
78 lines
3.0 KiB
Nix
78 lines
3.0 KiB
Nix
{ config, lib, pkgs, homeyConfig, ... }:
|
|
|
|
# Cloudflare Tunnel (cloudflared) — remote access without open inbound ports.
|
|
#
|
|
# Architecture:
|
|
# Internet → Cloudflare edge → cloudflared tunnel (outbound from Pi)
|
|
# → Caddy on localhost → service containers
|
|
#
|
|
# The tunnel is configured to route each hostname to Caddy's HTTPS listener.
|
|
# Caddy handles TLS and forward_auth; cloudflared just carries the traffic.
|
|
#
|
|
# Setup steps (one-time, done from the Cloudflare dashboard):
|
|
# 1. Go to Zero Trust → Networks → Tunnels → Create a tunnel
|
|
# 2. Name it (e.g. "pi-main")
|
|
# 3. Copy the tunnel token — add it to secrets.yaml as cloudflare/tunnel_token
|
|
# 4. In the tunnel's "Public Hostnames" config, add routes:
|
|
# auth.home.zakobar.com → http://localhost:80 (or https://localhost:443)
|
|
# git.home.zakobar.com → https://localhost:443
|
|
# nextcloud.home.zakobar.com → https://localhost:443
|
|
# ldapadmin.home.zakobar.com → https://localhost:443
|
|
# jellyfin.home.zakobar.com → https://localhost:443
|
|
# torrent.home.zakobar.com → https://localhost:443
|
|
# Set "No TLS Verify" = true (Caddy's cert is from Let's Encrypt but
|
|
# the hostname seen by cloudflared is localhost, so hostname verification
|
|
# would fail without this flag).
|
|
#
|
|
# The tunnel_token approach (--token) is the simplest: one secret, no config
|
|
# file needed on the Pi.
|
|
#
|
|
# Secrets consumed from sops:
|
|
# cloudflare/tunnel_token
|
|
|
|
let
|
|
cfg = config.homey.cloudflared;
|
|
in
|
|
{
|
|
options.homey.cloudflared = {
|
|
enable = lib.mkEnableOption "Cloudflare Tunnel for remote access";
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
# -----------------------------------------------------------------------
|
|
# Secrets
|
|
# -----------------------------------------------------------------------
|
|
sops.secrets."cloudflare/tunnel_token" = { owner = "cloudflared"; };
|
|
|
|
# -----------------------------------------------------------------------
|
|
# cloudflared service
|
|
# NixOS 24.11 ships services.cloudflared natively.
|
|
# -----------------------------------------------------------------------
|
|
services.cloudflared = {
|
|
enable = true;
|
|
tunnels = {
|
|
"pi-main" = {
|
|
# credentialsFile is not used with token-based auth;
|
|
# the token is passed via environment variable instead.
|
|
# We override the systemd unit below to inject it.
|
|
default = "http_status:404";
|
|
};
|
|
};
|
|
};
|
|
|
|
# Inject the tunnel token from the sops secret file
|
|
systemd.services."cloudflared-tunnel-pi-main" = {
|
|
serviceConfig = {
|
|
ExecStart = lib.mkForce (pkgs.writeShellScript "cloudflared-start" ''
|
|
exec ${pkgs.cloudflared}/bin/cloudflared tunnel \
|
|
--no-autoupdate \
|
|
run \
|
|
--token "$(cat ${config.sops.secrets."cloudflare/tunnel_token".path})"
|
|
'');
|
|
};
|
|
after = lib.mkAfter [ "caddy.service" ];
|
|
wants = lib.mkAfter [ "caddy.service" ];
|
|
};
|
|
};
|
|
}
|