Change:
Add clientless remote desktop gateway: Create nix expression. I will look into packaging this. It may be more fruitful than gateone or cloud9.
I actually have a local setup of this, but it is done in a very hacky way, so probably better off if you work on a service expression yourself. Probably need some improvements to the existing Tomcat module first though, from what I remember.
Please post any expressions you may have build. For the client, i just grab the binary (do you build it?): I've not made a service yet. You've hit on the issue, the tomcat setup is more convoluted, especially with DB authentication and the properties/user-mappings. this works for the server (depends on ) (note removing a warning due to a deprecated function in ).
Yeah, I just grab the WAR as well, arguably it is more the Nix way to build it from source but I was just looking to get something working rather than something clean :). My expression for the server is pretty similar, but instead of wrapping I used to avoid removing the RPATHs for the dynamically linked libraries. Also I didn't bother to support as many protocols (e.g. RDP) as I didn't need them for that environment. 's my service expression, but I doubt it will be very helpful. It's kind of a mess, fairly specific to my own setup (which e.g. has a reverse-proxy in front of guacamole, not covered therein), and I haven't altered the tomcat service expression to be any better.
Not strictly on-topic, but since it sounds like you both have or did have this running, can you comment on the performance of remote access via guac relative to other options? I've found everything but teamviewer to be frustratingly slow. Is this tree worth barking up? :)
I am no longer pursuing this. Reopen if needed.
well... it's possible i got this working again... still needs some cleanup, but i combined 's work and it's up and running.
I'd also be interested in native nix expression. Currently I just run it in docker.
Thank you for your contributions. This has been automatically marked as stale because it has had no activity for 180 days. If this is still important to you, we ask that you leave a comment below. Your comment can be as simple as "still important to me". This lets people see that at least one person still cares about this. Someone will have to do this at most twice a year if there is no other activity. Here are suggestions that might help resolve this more quickly: for maintainers and people that previously touched the related code and @ mention them in a comment. on the . 3. Ask on the on .
I'm interested in this (please un-stale it).
I marked this as stale due to inactivity. &rarr;
I'm interested in this (please un-stale it).
I too am interested in it
I'm interested as well.
This is a must-have. Thank you for opening this, we can thumbs up this comment for anyone else who's interested in making this a native nix expression.
For anyone interested - I created a working flake (based on the linked PRs): Configuration is not yet done in a nice way, but if you need to get guacamole running, this could help.
Cool news, I will most probably try it out soon. By the way, how about submitting the PR in directly so we could have a NixOS module?
great work are you planning to make a PR?
Hi all, I just created a draft PR to add Guacamole server and client. I basically copy pasted it from the flake at . This PR does not include the NixOS module since has plan to update it. In the meantime, could you review that new draft PR: ?
Just as side note, I landed here from - where it mentions guacamole not yet being available.
Thanks for noticing it! Any user having a GitHub account is free to edit the wiki. Are you willing to do it?
Can you provide a sample configuration? I'm also unclear of the difference between and
Here's my own server configuration: Are you willing to edit the Wiki page: ?
Thanks for the configuration. However I still can't get it to run. Am I right to assume, that once it's setup, you should get a tomcat webview in which you can select what connection you want to open (defined for your user in the user-). That's how it works on an ubuntu install in a vm that I did. I surf to it, login and then I have a bunch of connections (or can setup a new one). nginx as reverse proxy just prints 502 bad gateway error. I have this in my I also tried with but no luck either. After adding recommended proxy settings to nginx, I get now this error:
It seems to me that the discussion is shifting more towards the configuration of the proxy rather than focusing on Guacamole itself. I must confess, I'm unfamiliar with nginx, as my experience is primarily with — which I highly recommend you give a try, by the way! To approach this issue more systematically, I suggest first setting up Guacamole without the proxy. This should be a fairly straightforward process. Once you've successfully configured Guacamole, you can then layer the proxy on top. Breaking it down into these two separate steps may simplify the process and help identify any underlying issues more clearly.
How to use it without proxy? I tried to access it directly by ip address and port - no luck. And I also tried with caddy but no luck also. In your caddy setup I don't understand this: . Don't you have guac running on port 4822. Then why proxy to 8080?
The webserver is by default on port 8080, that's the reason why I used caddy in my config, see line 27: I guess you just have to access http://127.0.0.1:8080/
Ok, now that makes sense... I always tried port 4822 :)
Glad you found out. 4822 is the port of the service (guacamole-server).
Ok, figured it out: Caddy or nginx And exmpale of user- For generating the sha256 hash you can easily use: or
Excellent, I might reuse what you did in the documentation :) Caddy is amazing, glad you're using it :)
Sure, go ahead. Well, just for testing on that machine. The actual machine where I run guacamole (up to know in an ubuntu vm - so I can scratch that now) is already using nginx as reverse proxy for several things (plex, roundcube, wetty, photoprims, home assistant).
Do you maybe have a user- entry on how to connect to Win10 or Win11? I tried rdp with and without NLA but can't get achieve any connection. I keep getting immediately disconnected: I found a solution here for Win10 (didn't test Win11 yet): And my user- looks now like this: And in the Windows 10 Remote Host settings, make sure that NLA () is not checked. Will test Windows 11 later. Thanks for all the hard work on packaging that.
I'm not using Windows machine, sorry...
Figured now out to use it with NLA also:

Discussion:
- [sitespeed-io](https://sitespeed.io), a tool that can generate metrics (timings, diagnostics) for websites. Available as [services.sitespeed-io](#opt-services.sitespeed-io.enable). <ins> - [Apache Guacamole](https://guacamole.apache.org/), a cross-platform, clientless remote desktop gateway. Available as [services.guacamole-server](#opt-services.guacamole-server.enable) and [services.guacamole-client](#opt-services.guacamole-client.enable) services. </ins> ## Backward Incompatibilities {#sec-release-23.11-incompatibilities} - `writeTextFile` now requires `executable` to be boolean, values like `null` or `""` will now fail to evaluate.

./services/web-apps/gotosocial.nix ./services/web-apps/grocy.nix ./services/web-apps/pixelfed.nix <ins> ./services/web-apps/guacamole-client.nix ./services/web-apps/guacamole-server.nix </ins> ./services/web-apps/healthchecks.nix ./services/web-apps/hedgedoc.nix ./services/web-apps/hledger-web.nix

<ins> { config , lib , pkgs , ... }: let cfg = config.services.guacamole-client; settingsFormat = pkgs.formats.javaProperties { }; in { options = { services.guacamole-client = { enable = lib.mkEnableOption (lib.mdDoc "Apache Guacamole Client (Tomcat)"); package = lib.mkPackageOptionMD pkgs "guacamole-client" { }; settings = lib.mkOption { type = lib.types.submodule { freeformType = settingsFormat.type; }; default = { guacd-hostname = "localhost"; guacd-port = 4822; }; description = lib.mdDoc '' Configuration written to `guacamole.properties`. ::: {.note} The Guacamole web application uses one main configuration file called `guacamole.properties`. This file is the common location for all configuration properties read by Guacamole or any extension of Guacamole, including authentication providers. ::: ''; }; enableWebserver = lib.mkOption { type = lib.types.bool; default = true; description = lib.mdDoc '' Enable the Guacamole web application in a Tomcat webserver. ''; }; }; }; config = lib.mkIf cfg.enable { environment.etc."guacamole/guacamole.properties" = lib.mkIf (cfg.settings != {}) { source = (settingsFormat.generate "guacamole.properties" cfg.settings); }; services = lib.mkIf cfg.enableWebserver { tomcat = { enable = true; webapps = [ cfg.package ]; }; }; }; } </ins>

<ins> { config , lib , pkgs , ... }: let cfg = config.services.guacamole-server; in { options = { services.guacamole-server = { enable = lib.mkEnableOption (lib.mdDoc "Apache Guacamole Server (guacd)"); package = lib.mkPackageOptionMD pkgs "guacamole-server" { }; extraEnvironment = lib.mkOption { type = lib.types.attrsOf lib.types.str; default = { }; example = lib.literalExpression '' { ENVIRONMENT = "production"; } ''; description = lib.mdDoc "Environment variables to pass to guacd."; }; host = lib.mkOption { default = "127.0.0.1"; description = lib.mdDoc '' The host name or IP address the server should listen to. ''; type = lib.types.str; }; port = lib.mkOption { default = 4822; description = lib.mdDoc '' The port the guacd server should listen to. ''; type = lib.types.port; }; logbackXml = lib.mkOption { type = lib.types.nullOr lib.types.path; default = null; example = "/path/to/logback.xml"; description = lib.mdDoc '' Configuration file that correspond to `logback.xml`. ''; }; userMappingXml = lib.mkOption { type = lib.types.nullOr lib.types.path; default = null; example = "/path/to/user-mapping.xml"; description = lib.mdDoc '' Configuration file that correspond to `user-mapping.xml`. ''; }; }; }; config = lib.mkIf cfg.enable { # Setup configuration files. environment.etc."guacamole/logback.xml" = lib.mkIf (cfg.logbackXml != null) { source = cfg.logbackXml; }; environment.etc."guacamole/user-mapping.xml" = lib.mkIf (cfg.userMappingXml != null) { source = cfg.userMappingXml; }; systemd.services.guacamole-server = { description = "Apache Guacamole server (guacd)"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; environment = { HOME = "/run/guacamole-server"; } // cfg.extraEnvironment; serviceConfig = { ExecStart = "${lib.getExe cfg.package} -f -b ${cfg.host} -l ${toString cfg.port}"; RuntimeDirectory = "guacamole-server"; DynamicUser = true; PrivateTmp = "yes"; Restart = "on-failure"; }; }; }; } </ins>

graylog = handleTest ./graylog.nix {}; grocy = handleTest ./grocy.nix {}; grub = handleTest ./grub.nix {}; <ins> guacamole-client = handleTest ./guacamole-client.nix {}; guacamole-server = handleTest ./guacamole-server.nix {}; </ins> gvisor = handleTest ./gvisor.nix {}; hadoop = import ./hadoop { inherit handleTestOn; package=pkgs.hadoop; }; hadoop_3_2 = import ./hadoop { inherit handleTestOn; package=pkgs.hadoop_3_2; };

<ins> import ./make-test-python.nix ({pkgs, lib, ...}: { name = "guacamole-server"; nodes = { machine = {pkgs, ...}: { services.guacamole-server = { enable = true; host = "0.0.0.0"; }; }; }; testScript = '' start_all() machine.wait_for_unit("guacamole-server.service") machine.wait_for_open_port(4822) ''; meta.maintainers = [ lib.maintainers.drupol ]; }) </ins>

<ins> { lib , stdenvNoCC , fetchurl , nixosTests }: stdenvNoCC.mkDerivation (finalAttrs: { pname = "guacamole-client"; version = "1.5.2"; src = fetchurl { url = "https://archive.apache.org/dist/guacamole/${finalAttrs.version}/binary/guacamole-${finalAttrs.version}.war"; hash = "sha256-hu/DABbkA4lI2MGlw3oLBeONrdMQTbbsA3VbxuMRHEA="; }; dontUnpack = true; dontBuild = true; installPhase = '' runHook preInstall mkdir -p $out/webapps cp $src $out/webapps/guacamole.war runHook postInstall ''; passthru.tests = { inherit (nixosTests) guacamole-client; }; meta = { description = "Clientless remote desktop gateway"; homepage = "https://guacamole.apache.org/"; license = lib.licenses.asl20; maintainers = [ lib.maintainers.drupol ]; platforms = [ "x86_64-linux" "i686-linux" ]; sourceProvenance = [ lib.sourceTypes.binaryBytecode ]; }; }) </ins>

<ins> { lib , stdenv , fetchFromGitHub , pkg-config , autoPatchelfHook , autoreconfHook , cairo , ffmpeg_4-headless , freerdp , libjpeg_turbo , libpng , libossp_uuid , libpulseaudio , libssh2 , libtelnet , libvncserver , libvorbis , libwebp , libwebsockets , makeBinaryWrapper , openssl , pango , perl , nixosTests }: stdenv.mkDerivation (finalAttrs: { pname = "guacamole-server"; version = "1.5.2"; src = fetchFromGitHub { owner = "apache"; repo = "guacamole-server"; rev = finalAttrs.version; hash = "sha256-L1hFZ24kwTSHwqCUslnt5cBKkNh1cpVxu1ntTN1gFr0="; }; NIX_CFLAGS_COMPILE = [ "-Wno-error=format-truncation" "-Wno-error=format-overflow" ]; strictDeps = true; nativeBuildInputs = [ autoPatchelfHook autoreconfHook makeBinaryWrapper perl pkg-config ]; buildInputs = [ cairo ffmpeg_4-headless freerdp libjpeg_turbo libossp_uuid libpng libpulseaudio libssh2 libtelnet libvncserver libvorbis libwebp libwebsockets openssl pango ]; configureFlags = [ "--with-freerdp-plugin-dir=${placeholder "out"}/lib" ]; postPatch = '' patchShebangs ./src/protocols/rdp/**/*.pl ''; postInstall = '' ln -s ${freerdp}/lib/* $out/lib/ wrapProgram $out/sbin/guacd --prefix LD_LIBRARY_PATH ":" $out/lib ''; passthru.tests = { inherit (nixosTests) guacamole-server; }; meta = { description = "Clientless remote desktop gateway"; homepage = "https://guacamole.apache.org/"; license = lib.licenses.asl20; maintainers = [ lib.maintainers.drupol ]; platforms = [ "x86_64-linux" "i686-linux" ]; mainProgram = "guacd"; }; }) </ins>

gtkpod = callPackage ../applications/audio/gtkpod { }; <ins> guacamole-client = callPackage ../servers/guacamole-client { }; guacamole-server = callPackage ../servers/guacamole-server { }; </ins> q4wine = libsForQt5.callPackage ../applications/misc/q4wine { }; qrcodegen = callPackage ../development/libraries/qrcodegen { };