Postgres and extensions in docker

I have a simple flake that builds a postgres container with dockerTools. When I include the pgvector extension, postgres in the resulting container can’t find the vector.control. It seems like it’s looking in the lib folder in the nix store, and not in the `share/postgresql/extensions/’ folder where it gets installed. Does anyone know how to get it to build with the right pg_config path?

Here is the postgres.nix file:

{ pkgs, lib, stdenv, pkgsMusl, dockerTools, buildEnv, ... }:


  postgres = pkgs.postgresql_16;
  pgvector = pkgs.postgresql16Packages.pgvector;
in dockerTools.buildImage {
  name = "brauer";
  tag = postgres.version;
  created = "now";
  copyToRoot = buildEnv {
    name = "image-root";
    paths = [
      (dockerTools.fakeNss.override {
        extraPasswdLines = [
        extraGroupLines = [

  runAsRoot = ''
    mkdir /data
    chown postgres:postgres /data

  config = {
    Cmd = [ "postgres" ];
    Env = [ "PGDATA=/data" ];
    User = "postgres";
    Group = "postgres";

It looks like postgres is expects extension .control files to be in the NIX_PGLIBDIR which is in the nix store. The extensions install in the PG_DATA directory under share/extension/ folder. I guess I will try some hack overlay to get postgres to build pointing to the right folder for extensions. Maybe a simlink, or possibly by overriding these postinstall instructions:

      mkdir -p $out/bin
      rm $out/bin/{pg_config,postgres,pg_ctl}
      cp --target-directory=$out/bin ${postgresql}/bin/{postgres,pg_config,pg_ctl}
      wrapProgram $out/bin/postgres --set NIX_PGLIBDIR $out/lib
If anyone knows this stuff, please help a brother out.

You could probably take a look at how the NixOS module includes its support for extensions, for inspiration.

I believe it indicates that you can use this to compose a derivation containing Postgres and your desired extensions:

This would be instead of including pgvector as a sibling to Postgres in your list.


Thanks for the suggestion!
So would this be like the inline overlays that people do with python, e.g. something like (postgresql16.withPackages(ps: with ps; [ pgvector ]))
Or would it be an overlay that sets cfg.extraPlugins? Or neither?

Much much closer to the first example if I’ve understood your question accurately.


In case anyone has the same problem, the suggestion in post #3 worked. I just got it running by changing postgres and pgvector in the original file up top, to ( postgres.withPackages(ps: with ps; [ pgvector ])) I also added pathsToLink = [ "/bin" "/etc" "/var" "/share" ] although I don’t know if that was necessary or not.