From b4f65d1956eddd3b149d54b73a258cd7a1dfae03 Mon Sep 17 00:00:00 2001 From: Saarko Date: Fri, 1 Mar 2024 16:03:59 -0600 Subject: [PATCH 1/2] WIP: add Alpine Dockerfile --- Alpine/16/.versions.json | 6 ++ Alpine/16/Dockerfile | 76 +++++++++++++++ Alpine/Dockerfile-beta.template | 54 ++++++++++ Alpine/Dockerfile.template | 57 +++++++++++ Alpine/requirements.in | 1 + Alpine/update.sh | 168 ++++++++++++++++++++++++++++++++ 6 files changed, 362 insertions(+) create mode 100644 Alpine/16/.versions.json create mode 100644 Alpine/16/Dockerfile create mode 100644 Alpine/Dockerfile-beta.template create mode 100644 Alpine/Dockerfile.template create mode 100644 Alpine/requirements.in create mode 100644 Alpine/update.sh diff --git a/Alpine/16/.versions.json b/Alpine/16/.versions.json new file mode 100644 index 00000000..7afc6166 --- /dev/null +++ b/Alpine/16/.versions.json @@ -0,0 +1,6 @@ +{ + "BARMAN_VERSION": "3.10.0", + "IMAGE_RELEASE_VERSION": "6", + "POSTGRES_IMAGE_LAST_UPDATED": "2024-02-23T03:11:32.950689Z", + "POSTGRES_IMAGE_VERSION": "16.2-alpine3.19" +} diff --git a/Alpine/16/Dockerfile b/Alpine/16/Dockerfile new file mode 100644 index 00000000..43df28f0 --- /dev/null +++ b/Alpine/16/Dockerfile @@ -0,0 +1,76 @@ +FROM postgres:16.2-alpine3.19 AS build + +RUN apk add -U --no-cache -t .build-deps1 \ + $DOCKER_PG_LLVM_DEPS \ + git \ + build-base \ + openssl-dev \ + krb5-dev + +# Build and install pgaudit +WORKDIR /pgaudit +RUN git clone https://github.com/pgaudit/pgaudit --branch REL_16_STABLE . \ + && make install USE_PGXS=1 PG_CONFIG=/usr/local/bin/pg_config + +# Build and install pg_failover_slots +WORKDIR /pg_failover_slots +RUN git clone https://github.com/EnterpriseDB/pg_failover_slots --branch v1.0.1 . \ + && make install + +# Build and install pgvector +WORKDIR /pgvector +RUN git clone https://github.com/pgvector/pgvector --branch v0.6.0 . \ + && make install OPTFLAGS="" + +# Build and install barman +WORKDIR /barman +RUN apk add -U --no-cache -t .run-deps \ + python3 \ + rsync \ + postgresql-client \ + py3-argcomplete \ + py3-dateutil \ + py3-psycopg2 \ + py3-boto3 \ + && apk add -U --no-cache -t .build-deps2 \ + py3-gpep517 \ + py3-setuptools \ + py3-wheel + +RUN addgroup -S barman \ + && adduser -SD -h /var/lib/barman/ -s /sbin/nologin -G barman -g barman barman + +RUN git clone https://github.com/EnterpriseDB/barman --branch release/3.10.0 . \ + && gpep517 build-wheel \ + --wheel-dir .dist \ + --output-fd 3 3>&1 >&2 \ + && python3 -m installer -d "/" .dist/*.whl \ + && cp doc/barman.conf /etc + +WORKDIR / +# Remove source files and build deps +RUN rm -rf /pgaudit /pg_failover_slots /pgvector /barman \ + && apk del .build-deps1 .build-deps2 + +# Change the uid of postgres to 26 +RUN apk add --no-cache shadow \ + && usermod -u 26 postgres \ + && apk del shadow + +# Copy all into scratch image to reduce image size, this will not be necessary +# when removing/squashing some layers in the build stage. +FROM scratch + +# Do not split the description, otherwise we will see a blank space in the labels +LABEL name="PostgreSQL Container Images" \ + vendor="The CloudNativePG Contributors" \ + version="${PG_VERSION}" \ + release="6" \ + summary="PostgreSQL Container images." \ + description="This Docker image contains PostgreSQL and Barman Cloud based on Postgres 16.2-alpine3.19." + +LABEL org.opencontainers.image.description="This Docker image contains PostgreSQL and Barman Cloud based on Postgres 16.2-alpine3.19." + +COPY --from=build / / + +USER 26 diff --git a/Alpine/Dockerfile-beta.template b/Alpine/Dockerfile-beta.template new file mode 100644 index 00000000..ad175b97 --- /dev/null +++ b/Alpine/Dockerfile-beta.template @@ -0,0 +1,54 @@ +# vim:set ft=dockerfile: +# +# Copyright The CloudNativePG Contributors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +#  +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +FROM postgres:%%POSTGRES_IMAGE_VERSION%% + +# Do not split the description, otherwise we will see a blank space in the labels +LABEL name="PostgreSQL Container Images" \ + vendor="The CloudNativePG Contributors" \ + version="${PG_VERSION}" \ + release="%%IMAGE_RELEASE_VERSION%%" \ + summary="PostgreSQL Container images." \ + description="This Docker image contains PostgreSQL and Barman Cloud based on Postgres %%POSTGRES_IMAGE_VERSION%%." + +COPY requirements.txt / + +# Install additional extensions +RUN set -xe; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + "postgresql-${PG_MAJOR}-pgvector" \ + "postgresql-${PG_MAJOR}-pgaudit" \ + ; \ + rm -fr /tmp/* ; \ + rm -rf /var/lib/apt/lists/*; + +# Install barman-cloud +RUN set -xe; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + python3-pip \ + python3-psycopg2 \ + python3-setuptools \ + ; \ + pip3 install --upgrade pip; \ +# TODO: Remove --no-deps once https://github.com/pypa/pip/issues/9644 is solved + pip3 install --no-deps -r requirements.txt; \ + rm -rf /var/lib/apt/lists/*; + +# Change the uid of postgres to 26 +RUN usermod -u 26 postgres +USER 26 diff --git a/Alpine/Dockerfile.template b/Alpine/Dockerfile.template new file mode 100644 index 00000000..24cbb6d3 --- /dev/null +++ b/Alpine/Dockerfile.template @@ -0,0 +1,57 @@ +# vim:set ft=dockerfile: +# +# Copyright The CloudNativePG Contributors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +#  +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +FROM postgres:%%POSTGRES_IMAGE_VERSION%% + +# Do not split the description, otherwise we will see a blank space in the labels +LABEL name="PostgreSQL Container Images" \ + vendor="The CloudNativePG Contributors" \ + version="${PG_VERSION}" \ + release="%%IMAGE_RELEASE_VERSION%%" \ + summary="PostgreSQL Container images." \ + description="This Docker image contains PostgreSQL and Barman Cloud based on Postgres %%POSTGRES_IMAGE_VERSION%%." + +LABEL org.opencontainers.image.description="This Docker image contains PostgreSQL and Barman Cloud based on Postgres %%POSTGRES_IMAGE_VERSION%%." + +COPY requirements.txt / + +# Install additional extensions +RUN set -xe; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + "postgresql-${PG_MAJOR}-pgaudit" \ + "postgresql-${PG_MAJOR}-pgvector" \ + "postgresql-${PG_MAJOR}-pg-failover-slots" \ + ; \ + rm -fr /tmp/* ; \ + rm -rf /var/lib/apt/lists/*; + +# Install barman-cloud +RUN set -xe; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + python3-pip \ + python3-psycopg2 \ + python3-setuptools \ + ; \ + pip3 install --upgrade pip; \ +# TODO: Remove --no-deps once https://github.com/pypa/pip/issues/9644 is solved + pip3 install --no-deps -r requirements.txt; \ + rm -rf /var/lib/apt/lists/*; + +# Change the uid of postgres to 26 +RUN usermod -u 26 postgres +USER 26 diff --git a/Alpine/requirements.in b/Alpine/requirements.in new file mode 100644 index 00000000..c1cc785d --- /dev/null +++ b/Alpine/requirements.in @@ -0,0 +1 @@ +barman[cloud,azure,snappy,google] == 3.10.0 diff --git a/Alpine/update.sh b/Alpine/update.sh new file mode 100644 index 00000000..886128fb --- /dev/null +++ b/Alpine/update.sh @@ -0,0 +1,168 @@ +#!/usr/bin/env bash +# +# Copyright The CloudNativePG Contributors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +#  +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -Eeuo pipefail + +cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" + +versions=("$@") +if [ ${#versions[@]} -eq 0 ]; then + for version in */; do + [[ $version = src/ ]] && continue + versions+=("$version") + done +fi +versions=("${versions[@]%/}") + +# Get the last postgres base image tag and update time +fetch_postgres_image_version() { + local suite="$1"; + local item="$2"; + curl -SsL "https://registry.hub.docker.com/v2/repositories/library/postgres/tags/?name=bullseye&ordering=last_updated&page_size=20" | \ + jq -c ".results[] | select( .name | match(\"^${suite}.[a-z0-9]+-bullseye\"))" | \ + jq -r ".${item}" | \ + head -n1 +} + + +# Get the latest Barman version +latest_barman_version= +_raw_get_latest_barman_version() { + curl -s https://pypi.org/pypi/barman/json | jq -r '.releases | keys[]' | sort -Vr | head -n1 +} +get_latest_barman_version() { + if [ -z "$latest_barman_version" ]; then + latest_barman_version=$(_raw_get_latest_barman_version) + fi + echo "$latest_barman_version" +} + +# record_version(versionFile, component, componentVersion) +# Parameters: +# versionFile: the file containing the version of each component +# component: the component to be updated +# componentVersion: the new component version to be set +record_version() { + local versionFile="$1"; shift + local component="$1"; shift + local componentVersion="$1"; shift + + jq -S --arg component "${component}" \ + --arg componentVersion "${componentVersion}" \ + '.[$component] = $componentVersion' <"${versionFile}" >>"${versionFile}.new" + + mv "${versionFile}.new" "${versionFile}" +} + +generate_postgres() { + local version="$1"; shift + versionFile="${version}/.versions.json" + imageReleaseVersion=1 + + postgresImageVersion=$(fetch_postgres_image_version "${version}" "name") + if [ -z "$postgresImageVersion" ]; then + echo "Unable to retrieve latest postgres ${version} image version" + exit 1 + fi + postgresImageLastUpdate=$(fetch_postgres_image_version "${version}" "last_updated") + if [ -z "$postgresImageLastUpdate" ]; then + echo "Unable to retrieve latest postgres ${version} image version last update time" + exit 1 + fi + + + barmanVersion=$(get_latest_barman_version) + if [ -z "$barmanVersion" ]; then + echo "Unable to retrieve latest barman-cli-cloud version" + exit 1 + fi + + if [ -f "${versionFile}" ]; then + oldImageReleaseVersion=$(jq -r '.IMAGE_RELEASE_VERSION' "${versionFile}") + oldBarmanVersion=$(jq -r '.BARMAN_VERSION' "${versionFile}") + oldPostgresImageLastUpdate=$(jq -r '.POSTGRES_IMAGE_LAST_UPDATED' "${versionFile}") + oldPostgresImageVersion=$(jq -r '.POSTGRES_IMAGE_VERSION' "${versionFile}") + imageReleaseVersion=$oldImageReleaseVersion + else + imageReleaseVersion=1 + echo "{}" > "${versionFile}" + record_version "${versionFile}" "IMAGE_RELEASE_VERSION" "${imageReleaseVersion}" + record_version "${versionFile}" "BARMAN_VERSION" "${barmanVersion}" + record_version "${versionFile}" "POSTGRES_IMAGE_LAST_UPDATED" "${postgresImageLastUpdate}" + record_version "${versionFile}" "POSTGRES_IMAGE_VERSION" "${postgresImageVersion}" + return + fi + + newRelease="false" + + # Detect if postgres image updated + if [ "$oldPostgresImageLastUpdate" != "$postgresImageLastUpdate" ]; then + echo "Debian Image changed from $oldPostgresImageLastUpdate to $postgresImageLastUpdate" + newRelease="true" + record_version "${versionFile}" "POSTGRES_IMAGE_LAST_UPDATED" "${postgresImageLastUpdate}" + fi + + # Detect an update of Barman + if [ "$oldBarmanVersion" != "$barmanVersion" ]; then + echo "Barman changed from $oldBarmanVersion to $barmanVersion" + newRelease="true" + record_version "${versionFile}" "BARMAN_VERSION" "${barmanVersion}" + fi + + if [ "$oldPostgresImageVersion" != "$postgresImageVersion" ]; then + echo "PostgreSQL base image changed from $oldPostgresImageVersion to $postgresImageVersion" + record_version "${versionFile}" "IMAGE_RELEASE_VERSION" 1 + record_version "${versionFile}" "POSTGRES_IMAGE_VERSION" "${postgresImageVersion}" + imageReleaseVersion=1 + elif [ "$newRelease" = "true" ]; then + imageReleaseVersion=$((oldImageReleaseVersion + 1)) + record_version "${versionFile}" "IMAGE_RELEASE_VERSION" $imageReleaseVersion + fi + + dockerTemplate="Dockerfile.template" + if [ "${version}" -gt '16' ]; then + dockerTemplate="Dockerfile-beta.template" + fi + + cp -r src/* "$version/" + sed -e 's/%%POSTGRES_IMAGE_VERSION%%/'"$postgresImageVersion"'/g' \ + -e 's/%%IMAGE_RELEASE_VERSION%%/'"$imageReleaseVersion"'/g' \ + ${dockerTemplate} \ + > "$version/Dockerfile" +} + +update_requirements() { + barmanVersion=$(get_latest_barman_version) + # If there's a new version we need to recreate the requirements files + echo "barman[cloud,azure,snappy,google] == $barmanVersion" > requirements.in + + # This will take the requirements.in file and generate a file + # requirements.txt with the hashes for the required packages + pip-compile --generate-hashes 2> /dev/null + + # Removes psycopg from the list of packages to install + sed -i '/psycopg/{:a;N;/barman/!ba};/via barman/d' requirements.txt + + # Then the file needs to be moved into the src/root/ that will + # be added to every container later + mv requirements.txt src/ +} + +update_requirements +for version in "${versions[@]}"; do + generate_postgres "${version}" +done From 9e4dddb823182dda5246cf7542a34e67f86ad28f Mon Sep 17 00:00:00 2001 From: Saarko Date: Fri, 1 Mar 2024 17:02:32 -0600 Subject: [PATCH 2/2] Alpine/Dockerfile: remove runtime dependency Postgres client is already included in the base image. --- Alpine/16/Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Alpine/16/Dockerfile b/Alpine/16/Dockerfile index 43df28f0..18969f08 100644 --- a/Alpine/16/Dockerfile +++ b/Alpine/16/Dockerfile @@ -27,7 +27,6 @@ WORKDIR /barman RUN apk add -U --no-cache -t .run-deps \ python3 \ rsync \ - postgresql-client \ py3-argcomplete \ py3-dateutil \ py3-psycopg2 \