using proprietary apps on NixOS
or, "a tale of my love/hate relationship with buildFHSEnv"
I am one of those people who will only-semi-ironically say “20XX is the year of the Linux desktop!” on a regular basis. I use NixOS on most of my computers, including my company-issued ones - I’m very thankful that my boss has just as much disdain for Windows as I do.
at work, we use Devolutions Remote Desktop Manager quite heavily for accessing both internal, and customer, servers. it’s generally pretty decent - it doesn’t get in the way (much), and it does what we need it to do. it even has a native Linux version!
unfortunately, given it’s proprietary software, that Linux version is binary-only, published as a Debian package. which makes using it on NixOS a bit of a pain in the ass. let’s make it work.
If you just want to use Devolutions Remote Desktop Manager on NixOS, and don’t really care about reading how I made it work, feel free to skip to the end.
buildFHSEnv
nixpkgs has a wonderful thing by the name of buildFHSEnv, which constructs a fake environment resembling a “typical” Linux distro’s filesystem (which is standardised as the Filesystem Hierarchy Standard, or FHS. kinda. but that’s not a topic for this blog post…). we should be able to use that to construct an environment for RDM to run in, with all the necessary dependencies, and then extract the provided Debian package into it.
remote-desktop-manager.nix
{ lib
, fetchurl
, buildFHSEnv
, libarchive
, binutils
}:
let
version = "2025.3.0.8";
src = fetchurl {
url = "https://cdn.devolutions.net/download/Linux/RDM/${version}/RemoteDesktopManager_${version}_amd64.deb";
hash = "sha256-b7shj6HqnGe/whTm44FlrCp7e9g5T1CG+50biGiBmpg=";
};
in buildFHSEnv {
pname = "remotedesktopmanager";
inherit version;
targetPkgs = (pkgs: with pkgs; [
# TODO
]);
extraBuildCommands = ''
"${binutils}/bin/ar" p "${src}" data.tar.xz | "${libarchive}/bin/bsdtar" -C "$out" -xp usr/
'';
runScript = "/usr/lib/devolutions/RemoteDesktopManager/RemoteDesktopManager";
}
in theory, all I’d need to do is fill in the dependencies in targetPkgs above. things are never that simple.
actually populating the dependency list
this ended up being a massive trial-and-error experience - partly because I didn’t really have a good list of dependencies to work from; and partly because Debian ships things that are… “stable” (read: much older than what’s in nixpkgs).
with the benefit of hindsight, i’d have set up a tiny Debian VM, taken a snapshot of the installed apt packages, installed RDM, got it to work, then taken another snapshot of the installed packages and ‘diff’ed them. i didn’t do that.
I say “with the benefit of hindsight” because I’m writing this post several months after actually getting this working. mostly because I needed to update to a newer RDM version, which needed a few extra dependencies, and that shocked me into both (a) realising I didn’t need to struggle as much as I did; and (b) realising I should probably write a blog post about this. c’est la vie.
anyway. turns out RDM needs both openssl and gnutls; two different libsoup versions; two different webkitgtk ABIs (!?); and a bunch of other stuff i’d not have guessed. like udev. why does it need libudev? who fuckin’ knows.
what’s an OpenGL?
after some amount of time, I got RDM to open. except all I got was a bunch of corrupted graphics, and a console filled with libEGL warning: egl: failed to create dri2 screen. cool!
i ended up having to add the below to the RDM derivation so it could find the Mesa stuff:
profile = ''
export LIBGL_DRIVERS_PATH=/run/opengl-driver/lib/dri
export __EGL_VENDOR_LIBRARY_DIRS=/run/opengl-driver/share/glvnd/egl_vendor.d
export LIBVA_DRIVERS_PATH=/run/opengl-driver/lib/dri
export VDPAU_DRIVER_PATH=/run/opengl-driver/lib/vdpau
'';
i’d like a desktop launcher, please
I did try to write some arcane incantations in the extraBuildCommands to move the icon & the .desktop file into the right place for my DE to be able to actually launch RDM, but eventually I gave up and just put copies of them next to the derivation…
extraInstallCommands = ''
install -Dm755 "${./remotedesktopmanager.desktop}" "$out/share/applications/remotedesktopmanager.desktop"
install -Dm644 "${./remotedesktopmanager.svg}" "$out/share/icons/hicolor/scalable/apps/remotedesktopmanager.svg"
'';
and, it works!
the working derivation (for RDM v2025.3.0.8) is available here, on my forgejo instance. if you use flakes, you can probably just pull in my nixconf repo as a flake input to grab it.
alternatively, if anyone else feels like working this into a shape where it could be upstreamed to nixpkgs, be my guest - that’s far too much effort for me. (but if you do, please send me an email!)