{ config, pkgs, ... }: let swayConfig = pkgs.writeText "sway-headless.conf" '' output HEADLESS-1 custom_mode 1920x1080@60Hz seat seat0 fallback true ''; in { microvm.graphics = { enable = true; backend = "headless"; }; hardware.graphics.enable = true; programs.firefox.enable = true; programs.sway = { enable = true; wrapperFeatures.base = false; extraPackages = with pkgs; [ chromium grim wl-clipboard wlrctl wtype ]; }; users.users.charlotte = { extraGroups = [ "video" "render" ]; linger = true; }; environment.sessionVariables = { NIXOS_OZONE_WL = "1"; WAYLAND_DISPLAY = "wayland-1"; XDG_RUNTIME_DIR = "/run/user/${toString config.users.users.charlotte.uid}"; }; systemd.services.tailscale-serve-novnc = { description = "Expose noVNC to the tailnet"; wantedBy = [ "multi-user.target" ]; requires = [ "tailscaled.service" ]; after = [ "tailscaled.service" ]; serviceConfig = { ExecStart = "${config.services.tailscale.package}/bin/tailscale serve --yes http://127.0.0.1:6080"; Restart = "on-failure"; RestartSec = 1; }; }; systemd.user.services = { sway-headless = { description = "Headless Sway compositor"; wantedBy = [ "default.target" ]; environment = { WLR_BACKENDS = "headless"; WLR_HEADLESS_OUTPUTS = "1"; WLR_LIBINPUT_NO_DEVICES = "1"; WLR_RENDERER = "gles2"; WLR_RENDER_DRM_DEVICE = "/dev/dri/renderD128"; XDG_CURRENT_DESKTOP = "sway"; }; serviceConfig = { ExecStart = "${config.programs.sway.package}/bin/sway --config ${swayConfig}"; Restart = "on-failure"; RestartSec = 1; }; }; wayvnc = { description = "VNC server for headless Sway"; wantedBy = [ "default.target" ]; requires = [ "sway-headless.service" ]; after = [ "sway-headless.service" ]; serviceConfig = { ExecStart = "${pkgs.wayvnc}/bin/wayvnc 127.0.0.1:5900"; Restart = "on-failure"; RestartSec = 1; }; }; novnc = { description = "noVNC web client"; wantedBy = [ "default.target" ]; requires = [ "wayvnc.service" ]; after = [ "wayvnc.service" ]; serviceConfig = { ExecStart = "${pkgs.python3Packages.websockify}/bin/websockify --web=${pkgs.novnc}/share/webapps/novnc 127.0.0.1:6080 127.0.0.1:5900"; Restart = "on-failure"; RestartSec = 1; }; }; }; }