This guide covers how to set up a new cargo pgrx PostgreSQL extension in this project.
Create your extension directory:
nix/ext/my_extension/
├── default.nix # Nix build configuration
└── Cargo.lock.patch # (optional) if upstream lacks Cargo.lock
Create nix/ext/my_extension/default.nix:
{
lib,
stdenv,
callPackages,
fetchFromGitHub,
postgresql,
buildEnv,
rust-bin,
pkg-config,
openssl,
}:
let
pname = "my_extension";
build =
version: hash: rustVersion: pgrxVersion:
let
cargo = rust-bin.stable.${rustVersion}.default;
mkPgrxExtension = callPackages ../../cargo-pgrx/mkPgrxExtension.nix {
inherit rustVersion pgrxVersion;
};
in
mkPgrxExtension rec {
inherit pname version postgresql;
src = fetchFromGitHub {
owner = "your-org";
repo = pname;
rev = "v${version}";
inherit hash;
};
nativeBuildInputs = [ pkg-config cargo ];
buildInputs = [ openssl postgresql ];
CARGO = "${cargo}/bin/cargo";
cargoLock = {
lockFile = "${src}/Cargo.lock";
# Add outputHashes if you have git dependencies:
# outputHashes = {
# "some-crate-0.1.0" = "sha256-...";
# };
};
# Optional: if extension's Cargo.toml needs modification
# preConfigure = ''
# sed -i 's/pgrx = "0.12"/pgrx = "0.12.6"/' Cargo.toml
# '';
meta = with lib; {
description = "Description of your extension";
homepage = "https://github.com/your-org/${pname}";
license = licenses.mit; # adjust as needed
};
};
allVersions = (builtins.fromJSON (builtins.readFile ../versions.json)).${pname};
supportedVersions = lib.filterAttrs (
_: value: builtins.elem (lib.versions.major postgresql.version) value.postgresql
) allVersions;
versions = lib.naturalSort (lib.attrNames supportedVersions);
latestVersion = lib.last versions;
packages = map (
version:
let
v = supportedVersions.${version};
in
build version v.hash v.rust v.pgrx
) versions;
in
buildEnv {
name = pname;
paths = packages;
pathsToLink = [
"/lib"
"/share/postgresql/extension"
];
postBuild = ''
# Create version-specific SQL symlinks for migrations
${lib.concatMapStringsSep "\n" (version: ''
if [ -f $out/share/postgresql/extension/${pname}--${version}.sql ]; then
ln -sf ${pname}--${version}.sql $out/share/postgresql/extension/${pname}--${latestVersion}--${version}.sql 2>/dev/null || true
fi
'') versions}
'';
}Edit nix/ext/versions.json and add your extension:
{
"my_extension": {
"0.1.0": {
"postgresql": ["15", "17"],
"hash": "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
"pgrx": "0.12.6",
"rust": "1.80.0"
}
}
}To calculate the hash: Use a dummy hash first, then run:
nix build .#psql_15.exts.my_extension -LThe error message will show the correct hash.
Edit nix/packages/postgres.nix and add to the ourExtensions list:
ourExtensions = [
# ... existing extensions ...
../ext/my_extension/default.nix
];| File | Change |
|---|---|
nix/ext/my_extension/default.nix |
Create new file |
nix/ext/versions.json |
Add version entry |
nix/packages/postgres.nix |
Add to ourExtensions list |
nix/tests/sql/my_extension.sql |
(optional) Add test SQL |
nix/tests/expected/my_extension.out |
(optional) Expected test output |
# List all available dev shells
nix flake show | grep devShells
# Enter pgrx 0.12.6 development environment (Rust 1.80.0)
nix develop .#cargo-pgrx_0_12_6
# Enter pgrx 0.14.3 development environment (Rust 1.87.0)
nix develop .#cargo-pgrx_0_14_3
# Default shell (general tooling, not pgrx-specific)
nix developOnce inside nix develop .#cargo-pgrx_0_12_6:
# Initialize pgrx (first time only)
cargo pgrx init --pg15 $(which pg_config)
# Create a new extension from scratch
cargo pgrx new my_extension
cd my_extension
# Build and test your extension
cargo pgrx run pg15
# Package for release
cargo pgrx packageThe pgrx dev shells provide:
- Correct Rust toolchain version
cargo-pgrxCLI matching the pgrx version- PostgreSQL headers and pg_config
- Required build tools (pkg-config, openssl, etc.)
# Build extension for PostgreSQL 15
nix build .#psql_15.exts.my_extension -L
# Build extension for PostgreSQL 17
nix build .#psql_17.exts.my_extension -L
# Build all extensions (full PostgreSQL package)
nix build .#psql_15.bin -L
# Run tests
nix flake check -LFrom nix/cargo-pgrx/versions.json:
| pgrx Version | Rust Version |
|---|---|
| 0.12.6 | 1.80.0, 1.81.0 |
| 0.14.3 | 1.87.0 |
Match your extension's pgrx dependency to a supported combination.
| Extension | Path | Notes |
|---|---|---|
| pg_graphql | nix/ext/pg_graphql/default.nix |
Clean pgrx example |
| pg_jsonschema | nix/ext/pg_jsonschema/default.nix |
Simple single-crate |
| wrappers | nix/ext/wrappers/default.nix |
Complex with git deps |