Skip to content

Commit 5dba400

Browse files
committed
feat: extension image contributing guide
Signed-off-by: Gabriele Bartolini <gabriele.bartolini@enterprisedb.com>
1 parent 7a11b8d commit 5dba400

3 files changed

Lines changed: 192 additions & 0 deletions

File tree

301 KB
Loading
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
---
2+
title: "From proposal to PR: how to contribute to the new CloudNativePG extensions project"
3+
date: 2026-03-07T17:36:35+11:00
4+
description: "A step-by-step guide on contributing PostgreSQL extensions to the CloudNativePG ecosystem using modern build tools and the new Image Volume feature."
5+
tags: ["postgresql", "postgres", "kubernetes", "k8s", "cloudnativepg", "cnpg", "postgresql", "postgres", "dok", "data on kubernetes", "extensions", "pg_crash", "chaos engineering"]
6+
cover: cover.jpg
7+
thumb: thumb.jpg
8+
draft: false
9+
---
10+
11+
_In this article I walk you through the journey of adding the `pg_crash`
12+
extension to the new CloudNativePG extensions project. It explores the
13+
transition from legacy standalone repositories to a unified, Dagger-powered
14+
build system designed for PostgreSQL 18 and beyond. By focusing on the *Image
15+
Volume* feature and minimal operand images, the post provides a step-by-step
16+
guide for community members to contribute and maintain their own extensions
17+
within the CloudNativePG ecosystem._
18+
19+
20+
<!--more-->
21+
22+
---
23+
24+
At CloudNativePG, we recently reached a milestone in how we manage PostgreSQL
25+
extensions. With the Kubernetes **Image Volume** feature and the new
26+
`extension_control_path` parameter in PostgreSQL 18, we finally have a scalable
27+
way to provide the community with trusted, immutable extension images.
28+
This critical advancement is the result of amazing work by my colleagues at
29+
EDB, both for CloudNativePG and PostgreSQL. This led to the creation of the
30+
[`postgres-extensions-containers`](https://github.com/cloudnative-pg/postgres-extensions-containers)
31+
project.
32+
33+
But a repository is only as good as its contribution workflow, and only time
34+
will tell.
35+
36+
## The birth of a unified ecosystem
37+
38+
Making this project a reality was a significant undertaking. If you are
39+
interested in the technical roadmap, you can explore the [GitHub Epic (Issue #15)](https://github.com/cloudnative-pg/postgres-extensions-containers/issues/15),
40+
which tracks the features and tasks we implemented to make community
41+
contributions possible.
42+
43+
As maintainers, our first priority was ensuring a seamless upgrade path for our
44+
existing users. Before opening the doors to community contributions, we
45+
migrated and stabilised the key extensions that we already maintain:
46+
47+
- `pgAudit` and `pgvector`: currently part of the `standard` and `system`
48+
images in the [`postgres-containers`](https://github.com/cloudnative-pg/postgres-containers)
49+
project.
50+
- `PostGIS`: currently maintained in the dedicated
51+
[`postgis-containers`](https://github.com/cloudnative-pg/postgis-containers)
52+
project.
53+
54+
It is worth noting that we have omitted `pg_failover_slots` from this new
55+
project. This is because PostgreSQL 18 and CloudNativePG 1.27+ now provide
56+
native support for failover slots, making the external extension redundant for
57+
the future.
58+
59+
We are also shifting our strategy regarding operand containers: the `system`
60+
and `PostGIS` operand images will eventually disappear once PostgreSQL 17 is
61+
phased out in November 2029. For PostgreSQL 18 and beyond, this new unified
62+
repository is the official home.
63+
While the `standard` image will remain to serve users requiring locale support
64+
and specific libraries, the ecosystem is converging towards **minimal images**.
65+
66+
By centralising these extensions, we have decoupled their lifecycle from the
67+
main PostgreSQL engine images. This allows us to update an extension or patch a
68+
vulnerability without forcing a rebuild of the entire PostgreSQL operand
69+
image. It is a massive win for operational stability and security.
70+
71+
## The case study: pg_crash
72+
73+
To "dogfood" our new contribution process, I chose to migrate `pg_crash`. This
74+
extension is a disruptive tool designed for Chaos Engineering; it
75+
randomly or periodically terminates PostgreSQL processes to verify that
76+
CloudNativePG properly detects failures and performs failovers.
77+
78+
I strongly discourage using it in production, unless you are deliberately chaos
79+
engineering your infrastructure (which, in fact, is the proper way to perform
80+
chaos engineering). However, for most users, it serves as the ultimate "fire
81+
drill" for testing resilience in staging environments.
82+
83+
By distributing the `pg_crash` extension image, we can successfully dismiss the
84+
old, standalone [`pgcrash-containers`](https://github.com/cloudnative-pg/pgcrash-containers)
85+
project and, at the same time, provide an example for future contributors to follow.
86+
87+
## The journey: following the guide
88+
89+
I used our new
90+
[`CONTRIBUTING_NEW_EXTENSION.md`](https://github.com/cloudnative-pg/postgres-extensions-containers/blob/main/CONTRIBUTING_NEW_EXTENSION.md)
91+
guide as my map. Here is how the journey looked.
92+
93+
### Package discovery
94+
95+
Before writing code, I had to ensure the package was available in the PGDG
96+
(PostgreSQL Global Development Group) repositories. I ran a "disposable"
97+
container to search for it:
98+
99+
```sh
100+
docker run -u root -ti --rm ghcr.io/cloudnative-pg/postgresql:18-minimal-trixie
101+
# apt update && apt search pg-crash
102+
```
103+
104+
### Scaffolding the extension
105+
106+
We use [Dagger](https://dagger.io) to automate the mundane tasks of
107+
building and testing. One command created the entire directory structure for
108+
me:
109+
110+
```bash
111+
task create-extension NAME=pg-crash
112+
```
113+
114+
This generated the `metadata.hcl`, `Dockerfile`, and a template `README.md`. My
115+
job was to fill in the "TODOs" to ensure the extension correctly copied the
116+
`.so`, `.sql`, and `.control` files into the scratch image.
117+
118+
### The local feedback loop
119+
120+
One of the most satisfying parts of the workflow is the local testing
121+
environment. I could bake the image and see it running in a real Kubernetes
122+
cluster on my laptop:
123+
124+
```bash
125+
task e2e:test:full TARGET="pg-crash"
126+
```
127+
128+
The framework provides basic smoke tests to verify that the extension image can
129+
be deployed in a CNPG cluster and installed both in the system and, if
130+
applicable, in a database via `CREATE EXTENSION`.
131+
If an extension requires more rigorous validation, you can submit additional
132+
specific tests using the Chainsaw framework.
133+
134+
### Manual verification
135+
136+
Once the automated tests passed, I performed a manual "sanity check". I
137+
exported the Kubeconfig, identified the image tag using tools like `skopeo`,
138+
and deployed a 3-instance cluster to watch `pg_crash` trigger a real failover.
139+
Seeing the orchestrator respond exactly as expected is the ultimate validation.
140+
141+
## Navigating licensing
142+
143+
During the PR process
144+
([#126](https://github.com/cloudnative-pg/postgres-extensions-containers/pull/126)),
145+
we refined our licensing policy. Since we redistribute unmodified PGDG
146+
packages, we confirmed that the PostgreSQL License is CNCF-compliant.
147+
For other open-source licenses, such as FSF-approved (GPL), we established a
148+
case-by-case review process to ensure the legal integrity of the project.
149+
150+
## Conclusion: join the movement
151+
152+
With thew conversion of `pg_crash` to an image volume extension, we have turned
153+
a standalone maintenance burden into a community-ready template.
154+
155+
The [`postgres-extensions-containers`](https://github.com/cloudnative-pg/postgres-extensions-containers)
156+
project represents a unique opportunity for everyone to contribute to
157+
CloudNativePG and maintain one or more extensions for the years to come.
158+
By maintaining these images, you are helping build the most robust and flexible
159+
PostgreSQL ecosystem in the cloud-native world.
160+
161+
If you want to dive deeper into the technical mechanics of how these extensions
162+
are used, I encourage you to read my previous blog post:
163+
[CNPG Recipe 23: Managing extensions with ImageVolume in CloudNativePG]({{< relref "../20251201-extensions/index.md" >}}).
164+
165+
Furthermore, the future of extension management is becoming even more
166+
streamlined; CloudNativePG 1.29 introduces [support for extensions in image catalogs](https://github.com/cloudnative-pg/cloudnative-pg/pull/9781),
167+
a feature that makes the distribution,discovery and usage of these
168+
community-maintained images much easier.
169+
170+
Finally, I want to thank EDB and EDB's customers for supporting us in this
171+
endeavour. This project has been nearly two years in the making, and your
172+
support is what allows us to keep making Postgres better for the years to come
173+
in Kubernetes.
174+
175+
_Are you ready to contribute? Check out the
176+
[Contribution Guide](https://github.com/cloudnative-pg/postgres-extensions-containers/blob/main/CONTRIBUTING_NEW_EXTENSION.md)
177+
and let's build the future of cloud-native PostgreSQL together!_
178+
179+
---
180+
181+
Stay tuned for the upcoming recipes! For the latest updates, consider
182+
subscribing to my [LinkedIn](https://www.linkedin.com/in/gbartolini/) and
183+
[Twitter](https://twitter.com/_GBartolini_) channels.
184+
185+
If you found this article informative, feel free to share it within your
186+
network on social media using the provided links below. Your support is
187+
immensely appreciated!
188+
189+
<!--
190+
_Cover Picture: [“TITLE“](URL)._
191+
-->
192+
162 KB
Loading

0 commit comments

Comments
 (0)