Deploying postgres databases using CloudnativePG #
CloudnativePG provides an easy to use API to deploy postgres databases on our cluster drawing from a single image pool with easy backups and configuration.
Deploying the cloudnativePG Helm chart and image catalog #
Before using the cloudnativePG API we must deploy the official helm chart. We must also define a postgres image catalog for database deployments to use:
{
inputs,
...
}:
{
flake.modules.nixos.postgres =
{
config,
lib,
pkgs,
...
}:
let
chart = {
name = "cloudnative-pg";
repo = "https://cloudnative-pg.github.io/charts";
version = "0.28.0";
hash = "sha256-gdN4lPNgbfm9kcVRkFP0GnnoM9KKyiUv+zkpTLnLGa4=";
};
image = pkgs.dockerTools.pullImage {
imageName = "ghcr.io/cloudnative-pg/cloudnative-pg";
imageDigest = "sha256:68074486205a33ed41928761e22ad48278c690feebe8316727a1c6b3380f9e5e";
sha256 = "sha256-UWieKoPlh4RvK73QJcOC9+76kYzKruSsh5+uZZELVnU=";
finalImageTag = "1.29.0";
arch = "amd64";
};
postgresImage = pkgs.dockerTools.pullImage {
imageName = "ghcr.io/cloudnative-pg/postgresql";
imageDigest = "sha256:d879dfab951cb0eef9beac367f259d08ea1c04ae84699526854ff9ae478656be";
sha256 = "sha256-ngZW2rMlOaGm/VbSR2AHGCQis88zt+S2I++Oi6hqcKE=";
finalImageTag = "18.3-standard-trixie";
arch = "amd64";
};
in
{
options = {
postgres.enable = lib.mkEnableOption "Cloudnative-pg helm chart on k3s";
};
config = lib.mkIf config.postgres.enable {
services.k3s = {
images = [
image
postgresImage
];
autoDeployCharts = {
cloudnative-pg = chart // {
targetNamespace = "database";
createNamespace = true;
values = {
image = {
repository = image.imageName;
tag = image.imageTag;
};
resources = {
requests.cpu = "100m";
requests.memory = "128Mi";
limits.cpu = "200m";
limits.memory = "256Mi";
};
};
extraDeploy = [
{
apiVersion = "postgresql.cnpg.io/v1";
kind = "ClusterImageCatalog";
metadata = {
name = "postgresql-global";
};
spec = {
images = [
{
major = 18;
image = "${postgresImage.imageName}:${postgresImage.imageTag}";
}
];
};
}
];
};
};
};
};
};
}Deploying postgres databases #
Once installed, we can use CloudnativePG to define postgres databases for use in complex service deployments:
{
self,
inputs,
...
}:
{
flake.modules.nixos.immich-postgres =
{
config,
lib,
pkgs,
...
}:
{
config = lib.mkIf config.immich.enable {
services.k3s.autoDeployCharts.immich.extraDeploy = [
{
apiVersion = "postgresql.cnpg.io/v1";
kind = "Cluster";
metadata = {
namespace = "immich";
name = "immich-postgres";
};
spec = {
instances = 1;
imageCatalogRef = {
apiGroup = "postgresql.cnpg.io";
kind = "ClusterImageCatalog";
name = "postgresql-global";
major = 18;
};
storage.size = "8Gi";
managed.roles = [
{
name = "immich";
passwordSecret.name = "immich-secrets";
superuser = true;
login = true;
}
];
bootstrap.initdb = {
database = "immich";
owner = "immich";
secret.name = "immich-secrets";
};
resources = {
requests.cpu = "200m";
requests.memory = "256Mi";
limits.cpu = "1000m";
limits.memory = "1Gi";
};
};
}
];
};
};
}