Skip to content

Commit

Permalink
Merge pull request #1 from phracek/add_postgresql_image_mode
Browse files Browse the repository at this point in the history
Add image_mode based postgresql server
  • Loading branch information
phracek authored Feb 13, 2025
2 parents e7f559f + aa72586 commit 9134f8c
Show file tree
Hide file tree
Showing 18 changed files with 1,049 additions and 0 deletions.
50 changes: 50 additions & 0 deletions postgresql/Containerfile.c9s
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
FROM quay.io/centos-bootc/centos-bootc:stream9

ENV POSTGRESQL_VERSION=13 \
HOME=/var/lib/pgsql \
PGUSER=postgres \
STI_SCRIPTS_PATH=/usr/libexec/s2i \
APP_ROOT=/opt/app-root \
HOME=/opt/app-root/src \
PATH=/opt/app-root/src/bin:/opt/app-root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
PLATFORM="el9" \
APP_DATA=/opt/app-root

ENV SUMMARY="PostgreSQL is an advanced Object-Relational database management system" \
DESCRIPTION="PostgreSQL is an advanced Object-Relational database management system (DBMS). \
The image contains the client and server programs that you'll need to \
create, run, maintain and access a PostgreSQL DBMS server."

ENV INSTALL_PKGS="rsync tar bind-utils nss_wrapper-libs glibc-locale-source xz pgaudit" \
INSTALL_PKGS="$INSTALL_PKGS procps-ng util-linux postgresql-upgrade"
EXPOSE 5432

COPY root/usr/libexec/fix-permissions /usr/libexec/fix-permissions

# This image must forever use UID 26 for postgres user so our volumes are
# safe in the future. This should *never* change, the last test is there
# to make sure of that.
RUN PSQL_PKGS="postgresql-server postgresql-contrib" && \
dnf -y --setopt=tsflags=nodocs install $INSTALL_PKGS $PSQL_PKGS && \
postgres -V | grep -qe "$POSTGRESQL_VERSION\." && echo "Found VERSION $POSTGRESQL_VERSION" && \
dnf -y clean all --enablerepo='*' && \
test "$(id postgres)" = "uid=26(postgres) gid=26(postgres) groups=26(postgres)" && \
mkdir -p /var/lib/pgsql/data && \
mkdir -p /run/postgresql && \
mkdir -p $APP_DATA && \
/usr/libexec/fix-permissions /var/lib/pgsql /run/postgresql

COPY root /
COPY ./s2i/bin/ $STI_SCRIPTS_PATH

ENV CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/postgresql

RUN ln -s /usr/bin/run-postgresql $STI_SCRIPTS_PATH/run

RUN usermod -a -G root postgres && \
/usr/libexec/fix-permissions --read-only "$APP_DATA"

USER 26

ENTRYPOINT ["container-entrypoint"]
CMD ["run-postgresql"]
29 changes: 29 additions & 0 deletions postgresql/Containerfile.rhel10
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FROM registry.stage.redhat.io/rhel10/rhel-bootc:10.0

ENV POSTGRESQL_VERSION=16 \
HOME=/var/lib/pgsql \
PGUSER=postgres

ENV SUMMARY="PostgreSQL is an advanced Object-Relational database management system" \
DESCRIPTION="PostgreSQL is an advanced Object-Relational database management system (DBMS). \
The image contains the client and server programs that you'll need to \
create, run, maintain and access a PostgreSQL DBMS server."

EXPOSE 5432

# This image must forever use UID 26 for postgres user so our volumes are
# safe in the future. This should *never* change, the last test is there
# to make sure of that.
RUN INSTALL_PKGS="rsync tar gettext-envsubst bind-utils nss_wrapper-libs glibc-locale-source xz" && \
PSQL_PKGS="postgresql16-server postgresql16-contrib" && \
INSTALL_PKGS="$INSTALL_PKGS pgaudit" && \
INSTALL_PKGS="$INSTALL_PKGS procps-ng util-linux postgresql-upgrade" && \
dnf -y --setopt=tsflags=nodocs install $INSTALL_PKGS $PSQL_PKGS && \
rpm -V $INSTALL_PKGS && \
postgres -V | grep -qe "$POSTGRESQL_VERSION\." && echo "Found VERSION $POSTGRESQL_VERSION" && \
dnf -y clean all --enablerepo='*' && \
localedef -f UTF-8 -i en_US en_US.UTF-8 && \
test "$(id postgres)" = "uid=26(postgres) gid=26(postgres) groups=26(postgres)" && \
mkdir -p /var/lib/pgsql/data && \
mkdir -p /run/postgresql && \
/usr/libexec/fix-permissions /var/lib/pgsql /run/postgresql
3 changes: 3 additions & 0 deletions postgresql/root/usr/bin/container-entrypoint
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

exec "$@"
59 changes: 59 additions & 0 deletions postgresql/root/usr/bin/run-postgresql
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/bin/bash

export ENABLE_REPLICATION=${ENABLE_REPLICATION:-false}

set -eu
export_vars=$(cgroup-limits) ; export $export_vars

source "${CONTAINER_SCRIPTS_PATH}/common.sh"

set_pgdata

process_extending_files \
"${APP_DATA}/src/postgresql-pre-start" \
"${CONTAINER_SCRIPTS_PATH}/pre-start"

check_env_vars
generate_passwd_file
generate_postgresql_config

# Is this brand new data volume?
PG_INITIALIZED=false

if [ ! -f "$PGDATA/postgresql.conf" ]; then
initialize_database
PG_INITIALIZED=:
else
try_pgupgrade
fi

# Use insanely large timeout (24h) to ensure that the potential recovery has
# enough time here to happen (unless liveness probe kills us). Note that in
# case of server failure this command still exists immediately.
pg_ctl start -w --timeout 86400 -o "-h ''"

# This is just a pedantic safety measure (the timeout above is unlikely to
# happen), but `pt_ctl -w` is not reliable prior to PostgreSQL v10 where it
# returns exit_status=0 even if the server is still starting. For more info
# see the issue#297 and
# https://www.postgresql.org/message-id/CAB7nPqSJs85wK9aknm%3D_jmS6GnH3SQBhpzKcqs8Qo2LhEg2etw%40mail.gmail.com
pg_isready

if $PG_INITIALIZED ; then
process_extending_files \
"${APP_DATA}/src/postgresql-init" \
"${CONTAINER_SCRIPTS_PATH}/init"
migrate_db
create_users
fi

create_extensions
process_extending_files \
"${APP_DATA}/src/postgresql-start" \
"${CONTAINER_SCRIPTS_PATH}/start"

pg_ctl stop

unset_env_vars
echo "Starting server..."
exec postgres "$@"
5 changes: 5 additions & 0 deletions postgresql/root/usr/bin/run-postgresql-master
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

export ENABLE_REPLICATION=true

exec run-postgresql "$@"
39 changes: 39 additions & 0 deletions postgresql/root/usr/bin/run-postgresql-slave
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash

export ENABLE_REPLICATION=true

set -eu
export_vars=$(cgroup-limits) ; export $export_vars

source "$CONTAINER_SCRIPTS_PATH"/common.sh

set_pgdata

function initialize_replica() {
echo "Initializing PostgreSQL slave ..."
# TODO: Validate and reuse existing data?
rm -rf $PGDATA
PGPASSWORD="${POSTGRESQL_MASTER_PASSWORD}" pg_basebackup -X fetch --no-password --pgdata ${PGDATA} --host=${MASTER_FQDN} --port=5432 -U "${POSTGRESQL_MASTER_USER}"

# PostgreSQL recovery configuration.
generate_postgresql_recovery_config
cat >> "$PGDATA/postgresql.auto.conf" <<EOF
# Custom OpenShift recovery configuration:
include '${POSTGRESQL_RECOVERY_FILE}'
EOF
# activate standby mode
touch "$PGDATA/standby.signal"
}

check_env_vars
generate_passwd_file
generate_postgresql_config

wait_for_postgresql_master
export MASTER_FQDN=$(postgresql_master_addr)
initialize_replica

unset_env_vars
echo "Starting server..."
exec postgres "$@"
4 changes: 4 additions & 0 deletions postgresql/root/usr/bin/usage
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

cat /usr/share/container-scripts/postgresql/README.md

27 changes: 27 additions & 0 deletions postgresql/root/usr/libexec/check-container
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#! /bin/sh

# Try whether the PostgreSQL in container accepts connections.
#
# With --live, be tolerant to starting PG server. If the /bin/postgres binary
# has not been executed yet (the shell script is initializing the container),
# wait for it (this script might run forever, we expect that the timeout is
# maintained externally).

test -z "$ENABLED_COLLECTIONS" || . scl_source enable $ENABLED_COLLECTIONS

if test x"$1" = "x--live"; then
# Since livenessProbe is about to detect container deadlocks, and we
# so far don't know about real deadlocks to be detected -- we keep
# liveness probe to report that container is always ready (as long as
# we are able to execute shell, enable collections, etc., which is
# good for container sanity testing anyways).
exit 0
fi

# Readiness check follows, the --timeout is set to "infinite" because it
# is handled externally (readinessProbe.timeoutSeconds).
pg_isready -q \
-h 127.0.0.1 \
${POSTGRESQL_USER+-U "$POSTGRESQL_USER"} \
${POSTGRESQL_DATABASE+-d "$POSTGRESQL_DATABASE"} \
--timeout 0
39 changes: 39 additions & 0 deletions postgresql/root/usr/libexec/fix-permissions
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/sh

documentation="\
Recursively fix permissions on the given directories to allow GID=0
read/write regular files and read/write/execute directories.
To run this command, you have to be in the group root=0!"

uid=26
write=w

usage ()
{
cat >&2 <<EOF
$0: Error: ${1-usage error}
Usage: $0 [--read-only] DIR [DIR ..]
$documentation
EOF
exit 1
}

while test $# -gt 0; do
case $1 in
--read-only) write= ; shift ;;
*) break ;;
esac
done

test $# -eq 0 && usage "no DIR specified"

for dir; do
test -d "$dir" || usage "no such directory '$dir'"
echo >&2 "fixing permissions on '$dir' directory"
find "$dir" -exec chown "$uid:0" {} \;
find "$dir" -exec chmod "g+r$write" {} \;
find "$dir" -type d -exec chmod g+x {} +
done
Loading

0 comments on commit 9134f8c

Please sign in to comment.