Mount config.hardware.nvidia.package.lib32 into the container (CDI only carries 64-bit driver libs) and add a `gw` launcher that runs Guild Wars through VirtualGL on the M2000. Drops GW from ~18 software-rendered CPU cores to <1. Also bump stream to 60fps. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
99 lines
4.4 KiB
Nix
99 lines
4.4 KiB
Nix
# services/selkies.nix — Guild Wars in a browser via Selkies
|
|
#
|
|
# Replaces the Neko attempt (services/neko.nix, now unimported): Neko's
|
|
# absolute-pointer input model can't handle Guild Wars' exclusive mouse grab.
|
|
# Selkies captures the mouse client-side with the browser Pointer Lock API and
|
|
# sends *relative* movement, so the grab is a non-issue — and it uses the GPU
|
|
# (NVENC + EGL) instead of software rendering.
|
|
#
|
|
# Reach it at selkies.nordhammer.it (Authelia-gated). The Wine prefix with
|
|
# Guild Wars already installed is reused from the old Neko home, seeded into
|
|
# /var/lib/selkies/home/.wine (see the deploy note in the repo).
|
|
{ config, pkgs, lib, ... }:
|
|
let
|
|
# Selkies' NVIDIA EGL desktop (Ubuntu 24.04) plus Wine for the 32-bit GW
|
|
# client. Built from stdin (no build context); see neko.nix for the why.
|
|
dockerfile = pkgs.writeText "selkies-gw.Dockerfile" ''
|
|
FROM ghcr.io/selkies-project/nvidia-egl-desktop:24.04
|
|
USER root
|
|
RUN add-apt-repository -y multiverse \
|
|
&& dpkg --add-architecture i386 \
|
|
&& apt-get update \
|
|
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
|
wine wine32 wine64 winbind cabextract ca-certificates wget \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
# `gw` launcher: GW is 32-bit, so it needs the 32-bit NVIDIA GL libs (mounted
|
|
# at /usr/lib/i386-linux-gnu/nvidia by the service) on the loader path, and
|
|
# VirtualGL (EGL backend) to render on the M2000. Without this GW falls back
|
|
# to llvmpipe (software) and pegs ~18 CPU cores at <20 fps.
|
|
RUN printf '#!/bin/bash\nexport LD_LIBRARY_PATH=/usr/lib/i386-linux-gnu/nvidia\nexport VGL_DISPLAY=egl VGL_FPS=60\ncd "$HOME/.wine/drive_c/Program Files (x86)/Guild Wars/"\nexec vglrun wine Gw.exe "$@"\n' > /usr/local/bin/gw \
|
|
&& chmod +x /usr/local/bin/gw
|
|
USER 1000
|
|
'';
|
|
in
|
|
{
|
|
config = lib.mkIf (config.networking.hostName == "FredOS-Mediaserver") {
|
|
|
|
virtualisation.docker.enable = true;
|
|
# GPU into the container via CDI (nvidia.com/gpu=all). The CDI spec only
|
|
# carries the 64-bit driver libs, so the 32-bit set (for 32-bit Wine/GW) is
|
|
# bind-mounted separately below; enable32Bit makes them exist on the host.
|
|
hardware.nvidia-container-toolkit.enable = true;
|
|
hardware.graphics.enable32Bit = true;
|
|
|
|
systemd.tmpfiles.rules = [
|
|
"d /var/lib/selkies 0755 root root -"
|
|
# Container user is uid/gid 1000 and must own its home.
|
|
"d /var/lib/selkies/home 0755 1000 1000 -"
|
|
];
|
|
|
|
systemd.services.selkies = {
|
|
description = "Selkies — Guild Wars in a browser (EGL desktop + Wine + NVENC)";
|
|
after = [ "docker.service" "network-online.target" ];
|
|
requires = [ "docker.service" ];
|
|
wants = [ "network-online.target" ];
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
startLimitIntervalSec = 600;
|
|
startLimitBurst = 3;
|
|
|
|
serviceConfig = {
|
|
Restart = "on-failure";
|
|
RestartSec = "30s";
|
|
TimeoutStartSec = "3600";
|
|
ExecStartPre = [
|
|
"-${pkgs.docker}/bin/docker rm -f selkies"
|
|
"${pkgs.writeShellScript "selkies-build" ''
|
|
exec ${pkgs.docker}/bin/docker build -t selkies-gw:local - < ${dockerfile}
|
|
''}"
|
|
];
|
|
ExecStart = pkgs.writeShellScript "selkies-run" ''
|
|
exec ${pkgs.docker}/bin/docker run --rm --name selkies \
|
|
--device=nvidia.com/gpu=all \
|
|
-e NVIDIA_VISIBLE_DEVICES=all \
|
|
-e NVIDIA_DRIVER_CAPABILITIES=all \
|
|
--shm-size=2g \
|
|
-p 127.0.0.1:8093:8080 \
|
|
-p 3478:3478 -p 3478:3478/udp \
|
|
-p 65532-65535:65532-65535/udp \
|
|
-e TZ=Europe/Stockholm \
|
|
-e DISPLAY_SIZEW=1280 -e DISPLAY_SIZEH=720 \
|
|
-e DISPLAY_REFRESH=60 -e DISPLAY_DPI=96 -e DISPLAY_CDEPTH=24 \
|
|
-e PASSWD=selkies \
|
|
-e SELKIES_ENCODER=nvh264enc \
|
|
-e SELKIES_VIDEO_BITRATE=8000 \
|
|
-e SELKIES_FRAMERATE=60 \
|
|
-e SELKIES_ENABLE_BASIC_AUTH=false \
|
|
-e SELKIES_TURN_HOST=10.0.0.1 \
|
|
-e SELKIES_TURN_PROTOCOL=udp \
|
|
-e SELKIES_TURN_PORT=3478 \
|
|
-e TURN_MIN_PORT=65532 -e TURN_MAX_PORT=65535 \
|
|
-v ${config.hardware.nvidia.package.lib32}/lib:/usr/lib/i386-linux-gnu/nvidia:ro \
|
|
-v /var/lib/selkies/home:/home/ubuntu \
|
|
selkies-gw:local
|
|
'';
|
|
ExecStop = "${pkgs.docker}/bin/docker stop selkies";
|
|
};
|
|
};
|
|
};
|
|
}
|