From be6dde6f0a5bc785c935c2c6f46877799ae167b0 Mon Sep 17 00:00:00 2001 From: DannyDannyDanny Date: Mon, 6 Apr 2026 21:19:38 +0200 Subject: [PATCH] =?UTF-8?q?feat(sunken-ship):=20add=20cloudflare=20tunnel?= =?UTF-8?q?=20for=20external=20access=20=F0=9F=8C=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Exposes navidrome via music.dannydannydanny.me. Bypasses CGNAT — no port forwarding needed. Token stored outside repo at ~/.secrets/cloudflare-tunnel-token. --- nixos/hosts/sunken-ship.nix | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/nixos/hosts/sunken-ship.nix b/nixos/hosts/sunken-ship.nix index 5b18a80..a98a9e0 100644 --- a/nixos/hosts/sunken-ship.nix +++ b/nixos/hosts/sunken-ship.nix @@ -64,6 +64,7 @@ in brightnessctl # manual backlight; replaces removed `light` from nixpkgs uxplay # AirPlay mirroring receiver alsa-utils # aplay, amixer, arecord for audio debugging + cloudflared # Cloudflare Tunnel for external access ]; # Avahi (mDNS) — required for AirPlay discovery. @@ -97,6 +98,23 @@ in 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. # Runs as a system service (no PipeWire needed on a headless server). systemd.services.uxplay = {