feat(sunken-ship): add cloudflare tunnel for external access 🌐

Exposes navidrome via music.dannydannydanny.me.
Bypasses CGNAT — no port forwarding needed.
Token stored outside repo at ~/.secrets/cloudflare-tunnel-token.
This commit is contained in:
DannyDannyDanny 2026-04-06 21:19:38 +02:00
parent 76f63f0ae3
commit be6dde6f0a

View file

@ -64,6 +64,7 @@ in
brightnessctl # manual backlight; replaces removed `light` from nixpkgs brightnessctl # manual backlight; replaces removed `light` from nixpkgs
uxplay # AirPlay mirroring receiver uxplay # AirPlay mirroring receiver
alsa-utils # aplay, amixer, arecord for audio debugging alsa-utils # aplay, amixer, arecord for audio debugging
cloudflared # Cloudflare Tunnel for external access
]; ];
# Avahi (mDNS) — required for AirPlay discovery. # Avahi (mDNS) — required for AirPlay discovery.
@ -97,6 +98,23 @@ in
options = [ "bind" "ro" ]; options = [ "bind" "ro" ];
}; };
# Cloudflare Tunnel — exposes services to the internet without port forwarding.
# Token (not in repo): ~danny/.secrets/cloudflare-tunnel-token
# Routes configured in Cloudflare Zero Trust dashboard:
# music.dannydannydanny.me → http://localhost:4533
systemd.services.cloudflare-tunnel = {
description = "Cloudflare Tunnel for sunken-ship";
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "/bin/sh -c '${pkgs.cloudflared}/bin/cloudflared tunnel --no-autoupdate run --token $(cat /home/danny/.secrets/cloudflare-tunnel-token)'";
Restart = "on-failure";
RestartSec = 10;
User = "danny";
};
};
# UxPlay AirPlay receiver — audio-only, outputs directly to Scarlett Solo via ALSA. # UxPlay AirPlay receiver — audio-only, outputs directly to Scarlett Solo via ALSA.
# Runs as a system service (no PipeWire needed on a headless server). # Runs as a system service (no PipeWire needed on a headless server).
systemd.services.uxplay = { systemd.services.uxplay = {