Skip to content
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
100 changes: 100 additions & 0 deletions .github/dockerfiles/Dockerfile_extension
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# DocumentDB extension image for CNPG ImageVolume mode.
# Contains only extension artifacts (.so, .control, .sql, bitcode) and
# runtime shared-library dependencies. PostgreSQL is provided by the
# CNPG base image at runtime.
#
# Follows the pattern from:
# https://github.com/cloudnative-pg/postgres-extensions-containers
#
# Usage:
# docker build \
# --build-arg PG_MAJOR=18 \
# --build-arg DEB_PACKAGE_REL_PATH=packages/documentdb_0.110-0_arm64.deb \
# -t documentdb-extension:latest \
# -f Dockerfile_extension .

ARG BASE=ghcr.io/cloudnative-pg/postgresql:18-minimal-trixie
FROM ${BASE} AS builder

ARG PG_MAJOR=18
ARG DEB_PACKAGE_REL_PATH

USER 0

RUN set -eux && \
# Snapshot base image system libraries for later diffing
ldconfig -p | awk '{print $NF}' | grep '^/' | sort | uniq > /tmp/base-image-libs.out && \
# Install pgdg extension packages
apt-get update && \
apt-get install -y --no-install-recommends \
postgresql-${PG_MAJOR}-cron \
postgresql-${PG_MAJOR}-pgvector \
postgresql-${PG_MAJOR}-postgis-3

# Install the DocumentDB extension from a pre-built .deb
COPY ${DEB_PACKAGE_REL_PATH} /tmp/documentdb.deb
RUN dpkg -i /tmp/documentdb.deb && \
rm -f /tmp/documentdb.deb

# Gather system library dependencies not present in the CNPG base image
RUN set -eux && \
mkdir -p /system /licenses && \
find /usr/lib/postgresql/${PG_MAJOR}/lib/ -name '*.so' -print0 | \
xargs -0 ldd 2>/dev/null | \
awk '{print $3}' | grep '^/' | sort | uniq > /tmp/all-deps.out && \
comm -13 /tmp/base-image-libs.out /tmp/all-deps.out > /tmp/libraries.out && \
while read -r lib; do \
resolved=$(readlink -f "$lib"); \
dir=$(dirname "$lib"); \
base=$(basename "$lib"); \
cp -a "$resolved" /system/; \
for file in "$dir"/"${base%.so*}.so"*; do \
[ -e "$file" ] || continue; \
if [ -L "$file" ] && [ "$(readlink -f "$file")" = "$resolved" ]; then \
ln -sf "$(basename "$resolved")" "/system/$(basename "$file")"; \
fi; \
done; \
done < /tmp/libraries.out && \
for lib in $(find /system -maxdepth 1 -type f -name '*.so*'); do \
pkg=$(dpkg -S "$(basename "$lib")" 2>/dev/null | grep -v "diversion by" | awk -F: '/:/{print $1; exit}'); \
[ -z "$pkg" ] && continue; \
mkdir -p "/licenses/$pkg" && \
cp -a "/usr/share/doc/$pkg/copyright" "/licenses/$pkg/copyright" 2>/dev/null || true; \
done

# Resolve Debian-alternatives symlinks — they break in ImageVolume mode
# because /etc/alternatives/ is outside the volume mount.
RUN set -eux && \
for link in \
/usr/share/postgresql/${PG_MAJOR}/extension/*.control \
/usr/share/postgresql/${PG_MAJOR}/extension/*.sql \
/usr/lib/postgresql/${PG_MAJOR}/lib/*.so; do \
[ -L "$link" ] || continue; \
target=$(readlink -f "$link" 2>/dev/null); \
if [ -n "$target" ] && [ -f "$target" ]; then \
cp --remove-destination "$target" "$link"; \
elif [ -L "$link" ] && [ ! -e "$link" ]; then \
rm -f "$link"; \
fi; \
done

# ---------- minimal final image with only extension artifacts ----------
FROM scratch
ARG PG_MAJOR=18

# Licenses
COPY --from=builder /licenses/ /licenses/

# Extension shared libraries (.so and bitcode)
COPY --from=builder /usr/lib/postgresql/${PG_MAJOR}/lib/ /lib/

# Extension SQL and control files
COPY --from=builder /usr/share/postgresql/${PG_MAJOR}/extension/ /share/extension/

# PostGIS supporting data (spatial_ref_sys, topology, etc.)
COPY --from=builder /usr/share/postgresql/${PG_MAJOR}/contrib/ /share/contrib/

# System library dependencies not present in the CNPG base image
COPY --from=builder /system/ /system/

USER 65532:65532
60 changes: 60 additions & 0 deletions .github/dockerfiles/Dockerfile_gateway_deb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Lean gateway image — contains only the DocumentDB gateway binary
# Designed for use with the DocumentDB Kubernetes Operator (CNPG-based)
#
# Usage:
# docker build \
# --build-arg GATEWAY_DEB_REL_PATH=packages/documentdb_gateway_0.1.0-1_arm64.deb \
# -t documentdb-gateway:latest \
# -f Dockerfile_gateway_deb <build-context>
#
# The build context must contain:
# - The gateway .deb at GATEWAY_DEB_REL_PATH
# - scripts/gateway_entrypoint.sh
# - scripts/utils.sh
# - pg_documentdb_gw/SetupConfiguration.json
ARG BASE_IMAGE=debian:trixie-slim
FROM ${BASE_IMAGE}

ARG DEBIAN_FRONTEND=noninteractive
# Required: path (relative to build context) to the pre-built gateway .deb.
ARG GATEWAY_DEB_REL_PATH

# Fail fast when the caller forgets the deb path.
RUN [ -n "${GATEWAY_DEB_REL_PATH}" ] || \
(echo "ERROR: GATEWAY_DEB_REL_PATH build-arg is required." >&2; exit 1)

# ---------- minimal runtime deps + PG client (psql, pg_isready) ----------
RUN apt-get update && \
apt-get install -y --no-install-recommends \
ca-certificates \
jq \
openssl \
postgresql-client && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# ---------- gateway binary (from deb) ----------
COPY ${GATEWAY_DEB_REL_PATH} /tmp/gateway.deb
RUN dpkg -i /tmp/gateway.deb && \
rm -f /tmp/gateway.deb

# ---------- runtime config & scripts ----------
RUN useradd -ms /bin/bash -u 1000 documentdb

RUN mkdir -p /home/documentdb/gateway/scripts \
&& mkdir -p /home/documentdb/gateway/pg_documentdb_gw/target

COPY pg_documentdb_gw/SetupConfiguration.json \
/home/documentdb/gateway/pg_documentdb_gw/SetupConfiguration.json
COPY scripts/utils.sh \
/home/documentdb/gateway/scripts/utils.sh
COPY scripts/gateway_entrypoint.sh \
/home/documentdb/gateway/scripts/gateway_entrypoint.sh

RUN chown -R documentdb:documentdb /home/documentdb/gateway \
&& chmod +x /home/documentdb/gateway/scripts/*.sh

USER documentdb
WORKDIR /home/documentdb/gateway

ENTRYPOINT ["/bin/bash", "/home/documentdb/gateway/scripts/gateway_entrypoint.sh"]
68 changes: 68 additions & 0 deletions .github/dockerfiles/gateway_entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/bin/bash
# Lean gateway entrypoint for CNPG sidecar mode.
# Handles args passed by the sidecar-injector plugin:
# --create-user, --start-pg, --pg-port, --cert-path, --key-file
set -e

CREATE_USER="true"
PG_PORT="5432"
CERT_PATH=""
KEY_FILE=""
# In CNPG clusters the superuser is always "postgres"
OWNER="${OWNER:-postgres}"
USERNAME="${USERNAME:-}"
PASSWORD="${PASSWORD:-}"

while [[ $# -gt 0 ]]; do
case $1 in
--create-user) shift; CREATE_USER="$1"; shift;;
--start-pg) shift; shift;; # ignored — PG managed by CNPG
--pg-port) shift; PG_PORT="$1"; shift;;
--cert-path) shift; CERT_PATH="$1"; shift;;
--key-file) shift; KEY_FILE="$1"; shift;;
--owner) shift; OWNER="$1"; shift;;
--username) shift; USERNAME="$1"; shift;;
--password) shift; PASSWORD="$1"; shift;;
*) echo "Unknown option: $1" >&2; shift;;
esac
done

# PG is in a separate container; force TCP connection via localhost
export PGHOST=localhost

# Set up gateway configuration
CONFIG="/home/documentdb/gateway/pg_documentdb_gw/target/SetupConfiguration_temp.json"
cp /home/documentdb/gateway/pg_documentdb_gw/SetupConfiguration.json "$CONFIG"

if ! [[ "$PG_PORT" =~ ^[0-9]+$ ]]; then
echo "ERROR: PG_PORT must be a number, got: $PG_PORT" >&2
exit 1
fi
jq --argjson port "$PG_PORT" '.PostgresPort = $port' "$CONFIG" > "$CONFIG.tmp" && mv "$CONFIG.tmp" "$CONFIG"

if [ -n "$CERT_PATH" ] && [ -n "$KEY_FILE" ]; then
jq --arg c "$CERT_PATH" --arg k "$KEY_FILE" \
'.CertificateOptions = {"CertType":"PemFile","FilePath":$c,"KeyFilePath":$k}' \
"$CONFIG" > "$CONFIG.tmp" && mv "$CONFIG.tmp" "$CONFIG"
fi

# Wait for PostgreSQL (TCP readiness check)
echo "Waiting for PostgreSQL on localhost:$PG_PORT..."
timeout=600; elapsed=0
while ! pg_isready -h localhost -p "$PG_PORT" -q 2>/dev/null; do
if [ "$elapsed" -ge "$timeout" ]; then
echo "PostgreSQL did not become ready within ${timeout}s"; exit 1
fi
sleep 2; elapsed=$((elapsed + 2))
done
echo "PostgreSQL is ready."

# Create admin user if requested
if [ "$CREATE_USER" = "true" ] && [ -n "$USERNAME" ] && [ -n "$PASSWORD" ]; then
echo "Creating admin user $USERNAME..."
source /home/documentdb/gateway/scripts/utils.sh
SetupCustomAdminUser "$USERNAME" "$PASSWORD" "$PG_PORT" "$OWNER"
fi

# Start gateway
exec /usr/bin/documentdb_gateway "$CONFIG"
Loading
Loading