Skip to content

Commit 5fceacf

Browse files
sxdgbartoliniNiccoloFei
authored
chore: improve Dockerfile to build as extension image (#11)
Some improvements were made to the Dockerfile to build using meson and use a scratch image to have an extension image compatible with CloudNativePG Closes #10 Signed-off-by: Jonathan Gonzalez V. <[email protected]> Signed-off-by: Gabriele Bartolini <[email protected]> Signed-off-by: Niccolò Fei <[email protected]> Co-authored-by: Gabriele Bartolini <[email protected]> Co-authored-by: Niccolò Fei <[email protected]>
1 parent dee84a1 commit 5fceacf

File tree

4 files changed

+210
-28
lines changed

4 files changed

+210
-28
lines changed

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,16 @@ kind: Cluster
3535
metadata:
3636
name: pg-oauth
3737
spec:
38-
imageName: pg18-kc-validator:18.0 # Image containing kc_validator.so
38+
imageName: ghcr.io/cloudnative-pg/postgresql:18-minimal-trixie
3939
instances: 1
4040

4141
postgresql:
42+
extensions:
43+
- name: keycloak-oauth-validator
44+
ld_library_path:
45+
- system
46+
image:
47+
reference: ghcr.io/cloudnative-pg/postgres-keycloak-oauth-validator-testing:18-dev-trixie
4248
parameters:
4349
oauth_validator_libraries: "kc_validator"
4450
kc.token_endpoint: "https://<keycloak>/realms/<realm>/protocol/openid-connect/token"
@@ -131,10 +137,20 @@ created during the setup process.
131137

132138
### Docker
133139

140+
A simple possibility is to build the image using a plain docker build
141+
command:
142+
134143
```bash
135144
docker build -t pg-kc-validator -f docker/Dockerfile .
136145
```
137146

147+
To have all the possible labels, annotations, SBOMS, etc. the
148+
image can be built using Docker Bake:
149+
150+
```bash
151+
docker buildx bake
152+
```
153+
138154
---
139155

140156
## Security Notes

docker-bake.hcl

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#
2+
# Copyright © contributors to CloudNativePG, established as
3+
# CloudNativePG a Series of LF Projects, LLC.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
# SPDX-License-Identifier: Apache-2.0
18+
#
19+
20+
variable "environment" {
21+
default = "testing"
22+
validation {
23+
condition = contains(["testing", "production"], environment)
24+
error_message = "environment must be either testing or production"
25+
}
26+
}
27+
28+
variable "registry" {
29+
default = "localhost:5000"
30+
}
31+
32+
variable "insecure" {
33+
default = "false"
34+
}
35+
36+
variable "latest" {
37+
default = "false"
38+
}
39+
40+
variable "buildVersion" {
41+
default = "dev"
42+
}
43+
44+
variable "revision" {
45+
default = ""
46+
}
47+
48+
variable "distributions" {
49+
default = [
50+
"trixie"
51+
]
52+
}
53+
54+
variable "pgVersions" {
55+
default = [
56+
"18"
57+
]
58+
}
59+
60+
fullname = ( environment == "testing") ? "${registry}/postgres-keycloak-oauth-validator-testing" : "${registry}/postgres-keycloak-oauth-validator"
61+
62+
title = "PostgreSQL OAuth validator module for Keycloak"
63+
description = "This module enables PostgreSQL to delegate authorization decisions to Keycloak using OAuth tokens, leveraging Keycloak Authorization Services for fine-grained, token-based access control."
64+
authors = "The CloudNativePG Contributors"
65+
url = "https://github.com/cloudnative-pg/postgres-keycloak-oauth-validator"
66+
documentation = "https://cloudnative-pg.io/"
67+
license = "Apache-2.0"
68+
now = timestamp()
69+
70+
target "default" {
71+
matrix = {
72+
pgVersion = pgVersions
73+
distro = distributions
74+
}
75+
76+
name = "${pgVersion}-${distro}"
77+
platforms = [
78+
"linux/amd64",
79+
"linux/arm64"
80+
]
81+
tags = [
82+
"${fullname}:${pgVersion}-${buildVersion}-${distro}",
83+
"${fullname}:${pgVersion}-${buildVersion}-${formatdate("YYYYMMDDhhmm", now)}-${distro}",
84+
latest("${fullname}", "${latest}"),
85+
]
86+
87+
dockerfile = "docker/Dockerfile"
88+
context = "."
89+
90+
args = {
91+
BASE = "${getBaseImage(distro, pgVersion)}"
92+
PG_MAJOR = pgVersion
93+
}
94+
95+
output = [
96+
"type=image,registry.insecure=${insecure}",
97+
]
98+
99+
attest = [
100+
"type=provenance,mode=max",
101+
"type=sbom"
102+
]
103+
annotations = [
104+
"index,manifest:org.opencontainers.image.created=${now}",
105+
"index,manifest:org.opencontainers.image.url=${url}",
106+
"index,manifest:org.opencontainers.image.source=${url}",
107+
"index,manifest:org.opencontainers.image.version=${buildVersion}",
108+
"index,manifest:org.opencontainers.image.revision=${revision}",
109+
"index,manifest:org.opencontainers.image.vendor=${authors}",
110+
"index,manifest:org.opencontainers.image.title=${title}",
111+
"index,manifest:org.opencontainers.image.description=${description}",
112+
"index,manifest:org.opencontainers.image.documentation=${documentation}",
113+
"index,manifest:org.opencontainers.image.authors=${authors}",
114+
"index,manifest:org.opencontainers.image.licenses=${license}",
115+
"index,manifest:org.opencontainers.image.base.name=${getBaseImage(distro, pgVersion)}",
116+
]
117+
labels = {
118+
"org.opencontainers.image.created" = "${now}",
119+
"org.opencontainers.image.url" = "${url}",
120+
"org.opencontainers.image.source" = "${url}",
121+
"org.opencontainers.image.version" = "${buildVersion}",
122+
"org.opencontainers.image.revision" = "${revision}",
123+
"org.opencontainers.image.vendor" = "${authors}",
124+
"org.opencontainers.image.title" = "${title}",
125+
"org.opencontainers.image.description" = "${description}",
126+
"org.opencontainers.image.documentation" = "${documentation}",
127+
"org.opencontainers.image.authors" = "${authors}",
128+
"org.opencontainers.image.licenses" = "${license}",
129+
"org.opencontainers.image.base.name" = "${getBaseImage(distro, pgVersion)}",
130+
"name" = "${title}",
131+
"maintainer" = "${authors}",
132+
"vendor" = "${authors}",
133+
"version" = "${buildVersion}",
134+
"release" = "1",
135+
"description" = "${description}",
136+
"summary" = "${description}",
137+
}
138+
}
139+
140+
function latest {
141+
params = [ image, latest ]
142+
result = (latest == "true") ? "${image}:latest" : ""
143+
}
144+
145+
function getBaseImage {
146+
params = [ distro, pgVersion ]
147+
result = format("ghcr.io/cloudnative-pg/postgresql:%s-minimal-%s", pgVersion, distro)
148+
}

docker/Dockerfile

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,42 @@
1-
# syntax=docker/dockerfile:1.7
2-
FROM postgres:18 AS builder
3-
ARG DEBIAN_FRONTEND=noninteractive
4-
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
5-
set -eux; \
6-
apt-get update; \
7-
apt-get install -y --no-install-recommends \
8-
build-essential \
9-
meson \
10-
libcurl4-openssl-dev \
11-
postgresql-server-dev-18; \
12-
WORKDIR /work
13-
COPY . .
14-
RUN meson setup build && meson build -C build/
1+
ARG BASE=ghcr.io/cloudnative-pg/postgresql:18-minimal-trixie
152

16-
FROM ghcr.io/cloudnative-pg/postgresql:18-standard-trixie
3+
FROM $BASE AS builder
174
ARG DEBIAN_FRONTEND=noninteractive
5+
ARG PG_MAJOR=18
6+
187
USER root
198
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
20-
set -eux; \
21-
apt-get update; \
22-
apt-get install -y --no-install-recommends libcurl4 ca-certificates; \
23-
apt-get clean; \
24-
rm -rf /var/lib/apt/lists/*
25-
COPY --chmod=0644 docker/certs/server.crt /usr/local/share/ca-certificates/kc-root.crt
26-
RUN update-ca-certificates
27-
ENV CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
28-
USER postgres
29-
COPY --from=builder /work/build/kc_validator.so /usr/lib/postgresql/18/lib/
9+
# Base image system libraries
10+
ldconfig -p | awk '{print $NF}' | grep '^/' | sort | uniq > /tmp/base-image-libs.out && \
11+
# Build Dependencies
12+
apt-get update && \
13+
apt-get install -y --no-install-recommends \
14+
build-essential \
15+
meson \
16+
libcurl4-openssl-dev \
17+
"postgresql-server-dev-${PG_MAJOR}"
18+
19+
WORKDIR /srv
20+
COPY meson.build LICENSE ./
21+
COPY src/ ./src/
22+
RUN meson setup build && meson compile -C build/
23+
24+
# Gather keycloack-oauth-validator system libraries and their licenses
25+
RUN mkdir -p /system /licenses && \
26+
ldd /srv/build/kc_validator.so | awk '{print $3}' | grep '^/' | sort | uniq > /tmp/all-deps.out && \
27+
comm -13 /tmp/base-image-libs.out /tmp/all-deps.out > /tmp/libraries.out && \
28+
for lib in $(cat /tmp/libraries.out); do cp -a "${lib%.so*}.so"* /system; done && \
29+
# Licenses
30+
for lib in $(find /system -maxdepth 1 -type f -name '*.so*'); do \
31+
pkg=$(dpkg -S "$(basename "$lib")" | awk -F: '{print $1}'); \
32+
[ -z "$pkg" ] && continue; \
33+
mkdir -p "/licenses/$pkg" && cp -a /usr/share/doc/"$pkg"/* "/licenses/$pkg/"; \
34+
done
35+
36+
37+
FROM scratch
38+
39+
COPY --from=builder /srv/LICENSE ./
40+
COPY --from=builder /srv/build/kc_validator.so /lib/
41+
COPY --from=builder /system /system/
42+
COPY --from=builder /licenses /licenses/

examples/cnpg/cluster.yaml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ kind: Cluster
33
metadata:
44
name: pg-oauth
55
spec:
6-
imageName: pg18-kc-validator:18.0
6+
imageName: ghcr.io/cloudnative-pg/postgresql:18-minimal-trixie
77
instances: 1
88

99
# Bootstrap from scratch and run our init SQL from a ConfigMap
@@ -19,9 +19,14 @@ spec:
1919
storage:
2020
size: 1Gi
2121
postgresql:
22+
extensions:
23+
- name: keycloak-oauth-validator
24+
ld_library_path:
25+
- system
26+
image:
27+
reference: ghcr.io/cloudnative-pg/postgres-keycloak-oauth-validator-testing:18-dev-trixie
2228
parameters:
2329
oauth_validator_libraries: "kc_validator"
24-
2530
kc.token_endpoint: "https://<keycloak>/realms/<realm>/protocol/openid-connect/token"
2631
kc.audience: "postgres-resource"
2732
kc.resource_name: "appdb"

0 commit comments

Comments
 (0)