diff --git a/nixos/firewall.nix b/nixos/firewall.nix index aeb679b..1cd237f 100644 --- a/nixos/firewall.nix +++ b/nixos/firewall.nix @@ -20,5 +20,6 @@ networking.firewall.extraCommands = '' iptables -I nixos-fw -s 10.89.0.0/16 -p udp --dport 53 -j nixos-fw-accept iptables -I nixos-fw -s 10.89.0.0/16 -p tcp --dport 53 -j nixos-fw-accept + iptables -I nixos-fw -s 10.89.0.0/16 -p tcp --dport 5901 -j nixos-fw-accept ''; } diff --git a/nixos/linux.nix b/nixos/linux.nix index ed1cef9..b7fdde7 100644 --- a/nixos/linux.nix +++ b/nixos/linux.nix @@ -104,6 +104,61 @@ in { } ]; + # KDE Plasma on the host — the noVNC container (vnc-desktop) is a thin WebSocket + # proxy that connects to the VNC server started here. + services.xserver = { + enable = true; + desktopManager.plasma5.enable = true; + }; + # Don't start X via a display manager; the vnc-kde service owns the session. + services.displayManager.sddm.enable = lib.mkForce false; + + systemd.services.vnc-kde = { + description = "KDE Plasma desktop accessible over VNC"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" "agenix.service" ]; + + path = with pkgs; [ + tigervnc + dbus + xorg.xauth + plasma5Packages.plasma-workspace + coreutils + gnugrep + ]; + + serviceConfig = { + Type = "simple"; + User = "root"; + Restart = "on-failure"; + RestartSec = "5s"; + TasksMax = "infinity"; + + ExecStart = pkgs.writeShellScript "vnc-kde-start" '' + set -e + rm -f /tmp/.X1-lock /tmp/.X11-unix/X1 + + mkdir -p /root/.vnc + VNC_PASSWORD=$(grep '^VNC_PASSWORD=' /run/agenix/vnc-password | cut -d= -f2-) + printf '%s' "$VNC_PASSWORD" | vncpasswd -f > /root/.vnc/passwd + chmod 600 /root/.vnc/passwd + + Xvnc :1 \ + -rfbport 5901 \ + -SecurityTypes VncAuth \ + -PasswordFile /root/.vnc/passwd \ + -geometry 1920x1080 \ + -depth 24 \ + -AlwaysShared & + + export DISPLAY=:1 + sleep 2 + + exec dbus-run-session -- startplasma-x11 + ''; + }; + }; + virtualisation.arion = { backend = "podman-socket"; projects.forgejo.settings = import ./arion/arion-compose.nix; diff --git a/nixos/vnc-desktop/Dockerfile b/nixos/vnc-desktop/Dockerfile index 8889f48..2686190 100644 --- a/nixos/vnc-desktop/Dockerfile +++ b/nixos/vnc-desktop/Dockerfile @@ -2,42 +2,11 @@ FROM ubuntu:24.04 ENV DEBIAN_FRONTEND=noninteractive -# Set up Mozilla apt repo before installing KDE so the priority-1000 pin is -# already in place when kde-plasma-desktop resolves Firefox — otherwise apt -# installs Ubuntu's snap stub first and the real Firefox never displaces it. -RUN apt-get update && apt-get install -y --no-install-recommends wget ca-certificates gnupg \ - && wget -qO- https://packages.mozilla.org/apt/repo-signing-key.gpg \ - | gpg --dearmor > /usr/share/keyrings/packages.mozilla.org.gpg \ - && echo "deb [signed-by=/usr/share/keyrings/packages.mozilla.org.gpg] https://packages.mozilla.org/apt mozilla main" \ - > /etc/apt/sources.list.d/mozilla.list \ - && printf 'Package: *\nPin: origin packages.mozilla.org\nPin-Priority: 1000\n' \ - > /etc/apt/preferences.d/mozilla \ - && rm -rf /var/lib/apt/lists/* - RUN apt-get update && apt-get install -y \ - tigervnc-standalone-server \ - tigervnc-common \ novnc \ python3-websockify \ - kde-plasma-desktop \ - konsole \ - x11-utils \ - xfonts-base \ - dbus-x11 \ - openssh-client \ - curl \ - firefox \ && rm -rf /var/lib/apt/lists/* -# Remove Bluetooth stack — obexd gets activated in a tight loop by kded5 -# inside the container (no BT hardware), which exhausts the process limit. -RUN apt-get purge -y --auto-remove bluez bluez-obexd 2>/dev/null || true; \ - rm -f /usr/share/dbus-1/services/org.bluez.obex.service \ - /usr/share/dbus-1/system-services/org.bluez.service - -COPY discover-logging/ /discover-logging/ -RUN chmod +x /discover-logging/build.sh && /discover-logging/build.sh - COPY start.sh /start.sh RUN chmod +x /start.sh diff --git a/nixos/vnc-desktop/start.sh b/nixos/vnc-desktop/start.sh index ad030cc..9ec4aaf 100644 --- a/nixos/vnc-desktop/start.sh +++ b/nixos/vnc-desktop/start.sh @@ -1,34 +1,5 @@ #!/bin/bash set -e -mkdir -p /root/.vnc /root/.ssh -chmod 700 /root/.ssh - -# Clean up stale X lock files from previous container runs -rm -f /tmp/.X1-lock /tmp/.X11-unix/X1 - -# Set VNC password from environment -echo "${VNC_PASSWORD:?VNC_PASSWORD must be set}" | vncpasswd -f > /root/.vnc/passwd -chmod 600 /root/.vnc/passwd - -# Set root password from environment -echo "root:${ROOT_PASSWORD:?ROOT_PASSWORD must be set}" | chpasswd - -# Start Xvnc (headless X server + VNC server in one) -Xvnc :1 \ - -rfbport 5901 \ - -SecurityTypes VncAuth \ - -PasswordFile /root/.vnc/passwd \ - -geometry 1920x1080 \ - -depth 24 \ - -AlwaysShared \ - & - -export DISPLAY=:1 -sleep 2 - -# Start KDE Plasma session -dbus-run-session -- startplasma-x11 & - -# Serve noVNC web UI + bridge WebSocket -> VNC -exec websockify --web /usr/share/novnc 6080 localhost:5901 +# Proxy WebSocket (6080) → VNC server running on the host (hetzner-host:5901) +exec websockify --web /usr/share/novnc 6080 hetzner-host:5901