Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: add Alpine Dockerfile #94

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Alpine/16/.versions.json
Original file line number Diff line number Diff line change
@@ -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"
}
75 changes: 75 additions & 0 deletions Alpine/16/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
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 \
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
54 changes: 54 additions & 0 deletions Alpine/Dockerfile-beta.template
Original file line number Diff line number Diff line change
@@ -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
57 changes: 57 additions & 0 deletions Alpine/Dockerfile.template
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions Alpine/requirements.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
barman[cloud,azure,snappy,google] == 3.10.0
168 changes: 168 additions & 0 deletions Alpine/update.sh
Original file line number Diff line number Diff line change
@@ -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