nix-pocketbase.txt

Tools

PocketBase + Nix

On a recent episode of the Syntax podcast, Wes and Scott discussed PocketBase, a realtime SQLite stack/framework, and how they were using it for various projects. They really sold me on checking PocketBase out, but there was one minor gripe midway about the installation process that stuck with me afterwards:

it’s actually a bit weird because it’s you download, like, an executable. It’s not like a npm install, which I think they should do that.

PocketBase is not yet at version 1, so this current setup of downloading releases directly from GitHub is a sensible distribution solution. But this comment stuck out to me because it aligned perfectly with my current NixOS rabbit hole that I’ve been slowly descending over that past year, and with Nix a minor issue like this is actually very easily and elegantly solved (if you use Nix of course)!

There’s A Nix Package For That

Nix’s package manager is one of the largest on the web, so there’s a good chance it has a binary of most binaries, and this includes young projects like PocketBase. Using flakes, you can get a instance of PB up and running by creating a flake.nix in your working directory and simply add pocketbase to your devShell.buildInputs of any flake.nix.

{
    # Simplified for demonstration, inputs/outputs would be configured
    inputs = {...};
    outputs = {...}:

    devShell = with pkgs; mkShell {
        buildInputs = [
            pocketbase
        ];
    };
}

Fire up a dev shell and run:

$ nix develop
$ pocketbase serve
2024/07/25 14:21:59 Server started at http://127.0.0.1:8090

and that’s it! Open your browser and start adding records to your database, write a web server in whatever language you want and profit.

Bonus Tip: Isolated Dev Shells

Up to this point my I’ve been completely composing my project dependencies under a singular devShell.buildInputs property. This is fine, but when configuring a development environment where there’s a separation of concerns like this, it’s actually simple to break apart your dependencies into their own shell by using outputs.devShells:

{
    inputs = {...};
    outputs = {...}:

    devShells = with pkgs; {
        pb = mkShell {
            buildInputs = [
                pocketbase
            ];
            shellHook = ''
               pocketbase serve
            '';
        };
        code = mkShell {
            buildInputs = [
                nodejs
            ];
        }
    };
}

Now you can use tmux/Zellij pane or terminal window for your database service and another for your client service like so:

# Session 1:
$ nix develop .#pb
2024/07/25 14:21:59 Server started at http://127.0.0.1:8090

# Session 2
$ nix develop .#code
$ nvim .

Wrapping Up

I’m still quite new to Nix and I am sure there are derivation or service configurations that could take this example even further (email if you have any comments or recommendations), but I hope small little configurations like this help demonstrate how useful Nix is for improving us developer’s daily work life.

473 Words

Published