kolu
Docs

the headline setup

Your Mac is the window.

Your Mac is slow for agents, especially the filesystem. A headless box isn’t, and it stays up. Keep the Mac as the window. Kolu runs on the box, and you open it from the Mac as a real app.

This is not remoting into a Linux desktop. There is no Linux GUI. Kolu is a website the box serves; the Mac is a browser that you pin as an app.

Your Mac opens Kolu as an app over a private HTTPS URL. Kolu itself runs on a Linux box, and the agents run there.your Macbrowser, then a pinned appthe windowTailscale HTTPSLinux boxkolu runs herethe computer · the agents

You need a headless Linux machine with Nix — NixOS or Ubuntu, or any other Linux with Nix — a Mac, and a Tailscale account on both.

  1. Run kolu as a user service on the Linux box.

    Same home-manager module on both. Then linger, so the user systemd starts at boot on a box nobody is logged into. The full module, logs, and address options are on Deployment.

    NixOS. Import the module in that user’s home-manager config:

    { pkgs, kolu, ... }:
    {
      imports = [ kolu.homeManagerModules.default ];
    
      services.kolu = {
        enable = true;
        package = kolu.packages.${pkgs.stdenv.hostPlatform.system}.default;
      };
    }

    Rebuild as usual (nixos-rebuild switch). On a headless box also set users.users.<you>.linger = true in the system config so the user systemd starts at boot.

    Ubuntu (and other non-NixOS Linux). Install Nix with flakes if you do not have it — the NixOS Asia guide. Then a standalone home-manager flake; replace you and use aarch64-linux on ARM:

    {
      description = "kolu on this box";
    
      inputs = {
        nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
        home-manager.url = "github:nix-community/home-manager";
        home-manager.inputs.nixpkgs.follows = "nixpkgs";
        kolu.url = "github:juspay/kolu";
      };
    
      outputs = { nixpkgs, home-manager, kolu, ... }:
        let
          system = "x86_64-linux";
        in {
          homeConfigurations.you = home-manager.lib.homeManagerConfiguration {
            pkgs = nixpkgs.legacyPackages.${system};
            modules = [
              kolu.homeManagerModules.default
              ({ pkgs, ... }: {
                home.username = "you";
                home.homeDirectory = "/home/you";
                home.stateVersion = "24.11";
                services.kolu = {
                  enable = true;
                  package = kolu.packages.${pkgs.stdenv.hostPlatform.system}.default;
                };
              })
            ];
          };
        };
    }

    From that directory:

    nix run home-manager -- switch --flake .#you
    sudo loginctl enable-linger you

    Linger is what keeps the service up after SSH disconnects. If the switch starts compiling from source, enable the binary cache first.

    Either way, open http://127.0.0.1:7681 on the box (or via ssh port-forward). You should see an empty canvas. That is kolu running.

  2. Give it a private HTTPS URL with Tailscale Serve.

    Install Tailscale on the Linux box and on the Mac, signed into the same account. In the Tailscale admin console, turn on MagicDNS and HTTPS Certificates. On the box:

    tailscale serve --bg 7681

    Tailscale prints a tailnet URL:

    https://your-box.your-tailnet.ts.net/

    Keep kolu bound to 127.0.0.1. Serve is the only exposed surface. The longer tunnel notes are on From another device.

  3. Allow that origin, then rebuild.

    Tailscale presents a browser origin kolu did not start with. Add the exact URL from the previous step:

    services.kolu.allowedOrigins = [
      "https://your-box.your-tailnet.ts.net"
    ];

    Apply again (nixos-rebuild switch, or home-manager switch --flake .#you on Ubuntu). Without this, the page may load and then fail to talk to the server.

  4. Open the printed URL in a browser on the Mac.

    Use the full https://<machine>.<tailnet>.ts.net address — not the bare machine name, and not the 100.x address. Those stay plain HTTP and do not unlock install prompts, badges, or notifications.

  5. Pin it as an app.

    In Chrome, Edge, Brave, or Arc: Install. In Safari 17+: File → Add to Dock. Browser-by-browser paths are on Install as an App.

    Kolu is now in the macOS Apps launcher, in its own window. The agents still run on the Linux box.

Next