char/flake

nixos flake

git clone https://git.t4t.associates/char/flake

Charlotte Somvnc only over tailscalee91ab2d

main
2.5 KiB99 linesraw
1{ config, pkgs, ... }:
2let
3  swayConfig = pkgs.writeText "sway-headless.conf" ''
4    output HEADLESS-1 custom_mode 1920x1080@60Hz
5    seat seat0 fallback true
6  '';
7in
8{
9  microvm.graphics = {
10    enable = true;
11    backend = "headless";
12  };
13
14  hardware.graphics.enable = true;
15
16  programs.firefox.enable = true;
17
18  programs.sway = {
19    enable = true;
20    wrapperFeatures.base = false;
21    extraPackages = with pkgs; [
22      chromium
23      grim
24      wl-clipboard
25      wlrctl
26      wtype
27    ];
28  };
29
30  users.users.charlotte = {
31    extraGroups = [
32      "video"
33      "render"
34    ];
35    linger = true;
36  };
37
38  environment.sessionVariables = {
39    NIXOS_OZONE_WL = "1";
40    WAYLAND_DISPLAY = "wayland-1";
41    XDG_RUNTIME_DIR = "/run/user/${toString config.users.users.charlotte.uid}";
42  };
43
44  systemd.services.tailscale-serve-novnc = {
45    description = "Expose noVNC to the tailnet";
46    wantedBy = [ "multi-user.target" ];
47    requires = [ "tailscaled.service" ];
48    after = [ "tailscaled.service" ];
49    serviceConfig = {
50      ExecStart = "${config.services.tailscale.package}/bin/tailscale serve --yes http://127.0.0.1:6080";
51      Restart = "on-failure";
52      RestartSec = 1;
53    };
54  };
55
56  systemd.user.services = {
57    sway-headless = {
58      description = "Headless Sway compositor";
59      wantedBy = [ "default.target" ];
60      environment = {
61        WLR_BACKENDS = "headless";
62        WLR_HEADLESS_OUTPUTS = "1";
63        WLR_LIBINPUT_NO_DEVICES = "1";
64        WLR_RENDERER = "gles2";
65        WLR_RENDER_DRM_DEVICE = "/dev/dri/renderD128";
66        XDG_CURRENT_DESKTOP = "sway";
67      };
68      serviceConfig = {
69        ExecStart = "${config.programs.sway.package}/bin/sway --config ${swayConfig}";
70        Restart = "on-failure";
71        RestartSec = 1;
72      };
73    };
74
75    wayvnc = {
76      description = "VNC server for headless Sway";
77      wantedBy = [ "default.target" ];
78      requires = [ "sway-headless.service" ];
79      after = [ "sway-headless.service" ];
80      serviceConfig = {
81        ExecStart = "${pkgs.wayvnc}/bin/wayvnc 127.0.0.1:5900";
82        Restart = "on-failure";
83        RestartSec = 1;
84      };
85    };
86
87    novnc = {
88      description = "noVNC web client";
89      wantedBy = [ "default.target" ];
90      requires = [ "wayvnc.service" ];
91      after = [ "wayvnc.service" ];
92      serviceConfig = {
93        ExecStart = "${pkgs.python3Packages.websockify}/bin/websockify --web=${pkgs.novnc}/share/webapps/novnc 127.0.0.1:6080 127.0.0.1:5900";
94        Restart = "on-failure";
95        RestartSec = 1;
96      };
97    };
98  };
99}