On Mon Aug 24, 2026 at 11:59 AM CDT, Greg Burd wrote:
> Hackers,
>
> I'd like to propose adding a flake.nix at the repository root. Attached
> is a first cut.

+1

> This is not another build system. It doesn't touch configure, Meson, or the
> Makefiles, it wires up what we already have. A flake is a small, declarative
> manifest that tells Nix how to fetch our build dependencies and drop a
> developer into a shell where ./configure && make or meson setup just
> works, with bison, flex, perl, the optional libraries, and the docs
> toolchain all present and pinned to compatible versions. nix develop gives
> you that shell; nix build produces a server.
>
> The reason to carry it in-tree: Nix users are a growing segment of the
> PostgreSQL developer base across Linux, macOS, and increasingly the BSDs and
> even illumos. Today each of them keeps a private flake to hack on Postgres, I
> have one, and I know I'm not alone. These private copies drift, disagree on
> which features to enable, and have to be re-derived every time someone new
> wants to contribute from a Nix machine. A single blessed flake in the tree
> gives everyone the same reproducible starting point and one place to keep it
> current, the same argument that motivates the .editorconfig and CI files we
> already ship.

I am one of the people that has a private copy. I've also been working
on a NixOS-based buildfarm client that includes a derivation for the
buildfarm-client code.

> The flake exposes a toggle for every optional feature configure and Meson
> support, both build systems, and platform-appropriate defaults (io_uring,
> libnuma, systemd, PAM on Linux; Bonjour on macOS), so it's a starting point,
> not a policy so flip anything with an override.
>
> One deliberate omission: there is no flake.lock. A lock file pins the exact
> nixpkgs revision, which is the right call for an application that wants a
> frozen environment, but wrong for us. We don't want to freeze contributors to
> one snapshot of the dependency universe, and we don't want a lock file to
> become one more thing that goes stale in the tree and needs bumping. Leaving
> it out means the flake tracks whatever nixpkgs the developer already runs,
> which is exactly the behavior a build-from-source developer wants. Anyone who
> needs reproducibility can generate a lock locally; the tree stays clean.

I think the lack of flake.lock makes sense. I would add it to the
.gitignore. Additionally, I would also add `/result` and `/result-*` to
the .gitignore.

> It's meant to sit at the root next to configure, not in a subdirectory, so
> that a fresh checkout is immediately usable with nix develop.
>
> To use it you'll need to be in a Nix environment.  This means a Nix-based OS
> like NixOS or the macOS/Windows layers that bring in the Nix environment.
> Start by reading the https://nixos.org/learn/ information.

Can be Linux as well! For instance, I am using Nix on Fedora, which is
available in the Fedora system repositories.

> With a flake you can start a "developer shell" (a "dev shell") which will have
> all the dependencies required to build and run Postgres, no installing All The
> Things (TM) if you buy into this model you have a predictable environment, a
> shell with developer tools prepared and present always at hand when needed.
>
> So, first start the dev(eloper) shell:
>
> ```
> nix develop
> # then, meson (the default direction):
> meson setup build && ninja -C build
>
> # or classic autoconf:
> ./configure && make -j
> ```
>
> You don't have to enter the dev shell, you could instead build a server:
>
> ```
> nix build                      # default: meson, all features for your 
> platform
> ./result/bin/postgres --version
> ```
>
> The presets:
>
> ```
> nix build .#postgresql-debug      # cassert + debug syms + injection points
> nix build .#postgresql-minimal    # no optional libs — fastest compile
> nix build .#postgresql-autoconf   # configure/make instead of meson
> ```
>
> Flip any single feature (26 toggles) without a preset:
>
> ```
> nix build --expr '(builtins.getFlake (toString 
> ./.)).packages.x86_64-linux.postgresql.override { llvmSupport = true; cassert 
> = true; }'
> ```

I didn't know that this was a thing. What a mouthful!

> Run without installing:
>
> ```
> nix run . -- --version         # runs postgres (mainProgram is psql, so:)
> nix run .#postgresql -- --version
> ```
>
> There are many other things we could add into the flake such as
> cross-compilation, but to start off this should suffice.  I hope this 
> generates
> interest and constructive debate.  I'll say upfront, I'm not a Nix master,
> just a user and I find it invaluable.  I'm sure I'm not alone.
>
> Feedback welcome.

I think this is a great first pass! I am a recent Nix convert myself,
and I have found the development shell to be quite invaluable. I have
added flake.nix's to all of my personal projects. I think lowering the
bar to PostgreSQL development could really make a meaningful difference
in attracting new contributors.

I think this will also have side benefits of making things easier to
test. For instance, we could start inlining buildfarm client members
configurations as derivations in this repository. Then we can have
a library of derivations to test against that are tracked in version
control that are easily visible to everyone. People who find that their
submissions are failing on certain animals could more easily test and
diagnose what is causing the animal to fail. Additionally, I wonder if
NixOS VM tests could expose new ways to do automated testing of
Postgres. That is not something that I have thought about.

Regarding the code, can you explain the reasoning for the packages list
in the development shell? It seems like everything in the list is
already included by the Postgres package.

-- 
Tristan Partin
PostgreSQL Contributors Team
AWS (https://aws.amazon.com)


Reply via email to