You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/blog/building-images-bake/index.md
+27-28Lines changed: 27 additions & 28 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
---
2
2
title: "Creating a custom container image for CloudNativePG v2.0"
3
-
date: 2025-06-23
3
+
date: 2025-07-22
4
4
draft: false
5
5
image:
6
6
url:
@@ -22,19 +22,21 @@ summary: Using Docker's Bake to create container images for the CloudNativePG Op
22
22
---
23
23
24
24
## Summary
25
-
Almost two years ago, we wrote a [blog post on building custom container images
26
-
for CloudNativePG]({{% ref "/blog/creating-container-images/" %}}). Since then, many things have changed in the world of containers.
27
-
One of those things has been the introduction of [Bake](https://docs.docker.com/build/bake/) in Docker,
28
-
which allows you to build images using a simple configuration file. Bake is now
29
-
our recommended way to build images for CloudNativePG.
25
+
Nearly two years ago, we shared a [blog post on building custom container
26
+
images for CloudNativePG]({{% ref "/blog/creating-container-images/" %}}). Since then, the container ecosystem has evolved
27
+
significantly—one notable development being the introduction of [Docker Bake]((https://docs.docker.com/build/bake/)).
30
28
31
-
We will follow a simple baking recipe to create a custom container image.
32
-
Bake will also allow you to easily build multiple images at the same time.
29
+
Docker Bake simplifies image builds using a straightforward configuration file,
30
+
and it’s now our recommended approach for building CloudNativePG images.
31
+
32
+
In this post, we’ll walk through a simple baking recipe to create a custom
33
+
container image. With Bake, you can also easily build multiple images in
34
+
parallel.
33
35
34
36
## Ingredients
35
37
36
-
- A Bake file. We will use the one provided in the [CloudNativePG repository](https://github.com/cloudnative-pg/postgres-containers/blob/main/docker-bake.hcl)
37
-
-Another (local) Bake file, to overwrite the previous one and have a Bake file with your changes applied and build the container images
38
+
- A Bake file, using the one provided in the [CloudNativePG repository](https://github.com/cloudnative-pg/postgres-containers/blob/main/docker-bake.hcl) as a base.
39
+
-A second, local Bake file to override the base configuration—this lets you apply your custom changes and build the container images accordingly.
38
40
39
41
Baking time: 5 minutes.
40
42
@@ -79,15 +81,16 @@ EOT
79
81
}
80
82
```
81
83
82
-
There are a few things that we should remark here:
84
+
There are a few important points to highlight:
85
+
86
+
- The `extensions` variable is a list of extensions that we want to include in the image. In our recipe we are using `pgvector`, but you can add any others as needed.
87
+
- The `dockerfile-inline` variable contains our Dockerfile definition, which cannot be used remotely. We will explain why later.
88
+
- The `target` and the `tgt` values share the same name, but you can use any name you prefer.
89
+
- The `pgVersion` variable is a list specifying the PostgreSQL version(s) in MAJOR.MINOR format.
90
+
- The `name` field is used to identify individual entries in the matrix we’ve defined.
91
+
- The `args` variable contains the arguments passed to the Dockerfile—more on this later.
92
+
- The `getExtensionsString()` function is inherited from the base Bake file mentioned in the [Ingredients](#ingredients) section
83
93
84
-
- The `extensions` variable is a list of extensions that we want to include in the image. In our recipe we are using `pgvector`. But you can add any other extension you want.
85
-
- The `dockerfile-inline` variable contains our Dockerfile definition, which cannot be used remotely. We will explain more about this later.
86
-
- The `target` and the `tgt` have the same name. You can use whatever you want here as a name.
87
-
- The `pgVersion` variable is a list that contains basically the MAJOR.MINOR version of PostgreSQL.
88
-
- The `name` is the name that we will use later to refer to one element of the matrix that we created.
89
-
- The variable `args` lists all the arguments passed to the Dockerfile. We will talk more about this later.
90
-
- The function `getExtensionsString()` is inherited from the Bake file that we reference in the [Ingredients](#ingredients) section
91
94
92
95
### Step 2: Build the image
93
96
@@ -97,11 +100,10 @@ We can now build the image using the following command:
This will, by default, build the image for the bake matrix we previously created, and will try to push the image to the registry at
103
+
This will build the image for the bake matrix we previously created, and will try to push the image to the registry at
101
104
`localhost:5000`, which is the default registry defined for testing environments in the parent Bake file. Let's explain the full command:
102
105
103
-
As explained in the [Bake documentation about remote definitions](https://docs.docker.com/build/bake/remote-definition/) you can use a remote Bake definition with all the functions and default targets, and attach another local one to override
104
-
all the default values.
106
+
As outlined in the [Bake documentation on remote definitions](https://docs.docker.com/build/bake/remote-definition/), you can use a remote Bake file that includes functions and default targets, then attach a local Bake file to override any default values as needed.
105
107
106
108
In the command above, `-f cwd://bake.hcl` is the local file that we created in Step 1, and
107
109
`-f docker-bake.hcl` is the remote file in the git repo, that we're using to build the image.
@@ -144,14 +146,12 @@ For example, the `pgvector` extension will be translated into
144
146
`postgresql-16-pgvector,` which is the name of the package for pgvector extensions for PostgreSQL 16 in the Debian
145
147
Bookworm distribution.
146
148
147
-
When we add elements to, for example, the `args` variable, those elements are processed by the Bake file, and will be
149
+
When we add elements to, for example, the `args` variable, those elements are processed by the Docker bake command, and will be
148
150
merged, meaning that the new elements will be added, and the existing ones will be overwritten.
149
151
150
152
### Dockerfile file
151
153
152
-
The Dockerfile is simply a heredoc string, because of the limitations of Bake to overwrite the remote Dockerfile with a
153
-
local one, but it allows us to change the FROM in the image, which means we can create an image that it's directly based
154
-
on the CloudNativePG images, and we can add the extensions we want to use in our image, without building all of them.
154
+
The Dockerfile is defined as a heredoc string due to Bake's limitation in overriding a remote Dockerfile with a local one. However, this approach still lets us modify the FROM directive, allowing us to base our image directly on the CloudNativePG images and add only the specific extensions we need—without rebuilding all of them.
155
155
156
156
## There's more!
157
157
@@ -161,7 +161,6 @@ You may want to avoid building arm64 images by adding the following:
161
161
platforms = ["linux/amd64"]
162
162
```
163
163
164
-
This will overwrite the platforms variable and so, will build only for one platform.
164
+
This will override the platforms variable, so the image will be built for a single platform only.
165
165
166
-
Also, if you want to build everything into your own repository and manage the same tags, it's possible. In the future
167
-
we may write another post explaining this.
166
+
If you’d like to build everything into your own repository while managing the same tags, that’s also possible. We may cover that in a future post.
0 commit comments