Files
Keybard-Vagabond-Demo/build/postgresql-postgis/Dockerfile.upgrade

268 lines
12 KiB
Docker

# =============================================================================
# PostgreSQL 16→18 Upgrade Image for CloudNativePG pg_upgrade
# =============================================================================
# This special image contains BOTH PG16 and PG18 binaries + PostGIS, required
# for CloudNativePG's declarative pg_upgrade feature.
#
# Use this image ONLY for the upgrade process. After upgrade completes,
# switch to the regular cnpg-postgis:18-3.6 image.
#
# Build: docker build --platform linux/arm64 -f Dockerfile.upgrade -t cnpg-postgis:upgrade-16-to-18 .
# =============================================================================
# -----------------------------------------------------------------------------
# Build arguments - Pin versions for reproducible builds
# -----------------------------------------------------------------------------
ARG PG_OLD=16
ARG PG_NEW=18
ARG POSTGIS_OLD=3.4.3
ARG POSTGIS_NEW=3.6.1
ARG GEOS_VERSION=3.13.0
ARG PROJ_VERSION=9.4.1
ARG GDAL_VERSION=3.10.1
# =============================================================================
# Stage 1: Build PostGIS for PG16 (old version)
# =============================================================================
FROM postgres:16-bookworm AS builder-pg16
ARG POSTGIS_OLD
ARG GEOS_VERSION
ARG PROJ_VERSION
ARG GDAL_VERSION
# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential cmake ninja-build pkg-config git wget ca-certificates \
postgresql-server-dev-16 \
libxml2-dev libjson-c-dev libprotobuf-c-dev protobuf-c-compiler \
libsqlite3-dev sqlite3 libtiff-dev libcurl4-openssl-dev libssl-dev \
zlib1g-dev liblzma-dev libzstd-dev libpng-dev libjpeg-dev libwebp-dev \
libpcre2-dev autoconf automake libtool nlohmann-json3-dev libgeotiff-dev \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /build
# Build GEOS
RUN wget -q https://download.osgeo.org/geos/geos-${GEOS_VERSION}.tar.bz2 \
&& tar xjf geos-${GEOS_VERSION}.tar.bz2 \
&& cd geos-${GEOS_VERSION} && mkdir build && cd build \
&& cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local -DBUILD_TESTING=OFF \
&& ninja && ninja install \
&& cd /build && rm -rf geos-*
# Build PROJ
RUN wget -q https://download.osgeo.org/proj/proj-${PROJ_VERSION}.tar.gz \
&& tar xzf proj-${PROJ_VERSION}.tar.gz \
&& cd proj-${PROJ_VERSION} && mkdir build && cd build \
&& cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local \
-DBUILD_TESTING=OFF -DENABLE_CURL=ON -DENABLE_TIFF=ON \
&& ninja && ninja install \
&& cd /build && rm -rf proj-* && ldconfig
# Build GDAL
RUN wget -q https://github.com/OSGeo/gdal/releases/download/v${GDAL_VERSION}/gdal-${GDAL_VERSION}.tar.gz \
&& tar xzf gdal-${GDAL_VERSION}.tar.gz \
&& cd gdal-${GDAL_VERSION} && mkdir build && cd build \
&& cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local \
-DBUILD_TESTING=OFF -DBUILD_APPS=OFF \
-DGDAL_BUILD_OPTIONAL_DRIVERS=OFF -DOGR_BUILD_OPTIONAL_DRIVERS=OFF \
-DGDAL_USE_GEOS=ON -DGDAL_USE_PROJ=ON -DGDAL_USE_TIFF=ON \
-DGDAL_USE_GEOTIFF=ON -DGDAL_USE_PNG=ON -DGDAL_USE_JPEG=ON \
-DGDAL_USE_WEBP=ON -DGDAL_USE_CURL=ON -DGDAL_USE_SQLITE3=ON \
-DGDAL_USE_POSTGRESQL=ON \
&& ninja && ninja install \
&& cd /build && rm -rf gdal-* && ldconfig
# Build PostGIS for PG16
ENV LD_LIBRARY_PATH=/usr/local/lib
ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
RUN wget -q https://download.osgeo.org/postgis/source/postgis-${POSTGIS_OLD}.tar.gz \
&& tar xzf postgis-${POSTGIS_OLD}.tar.gz \
&& cd postgis-${POSTGIS_OLD} \
&& LDFLAGS="-L/usr/local/lib" CPPFLAGS="-I/usr/local/include" \
./configure \
--with-pgconfig=/usr/lib/postgresql/16/bin/pg_config \
--with-geosconfig=/usr/local/bin/geos-config \
--with-projdir=/usr/local \
--with-gdalconfig=/usr/local/bin/gdal-config \
--with-protobufdir=/usr \
--without-sfcgal \
&& make -j$(nproc) \
&& make install DESTDIR=/postgis-install-pg16 \
&& cd /build && rm -rf postgis-*
# =============================================================================
# Stage 2: Build PostGIS for PG18 (new version)
# =============================================================================
FROM postgres:18-bookworm AS builder-pg18
ARG POSTGIS_NEW
ARG GEOS_VERSION
ARG PROJ_VERSION
ARG GDAL_VERSION
# Install build dependencies (same as PG16)
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential cmake ninja-build pkg-config git wget ca-certificates \
postgresql-server-dev-18 \
libxml2-dev libjson-c-dev libprotobuf-c-dev protobuf-c-compiler \
libsqlite3-dev sqlite3 libtiff-dev libcurl4-openssl-dev libssl-dev \
zlib1g-dev liblzma-dev libzstd-dev libpng-dev libjpeg-dev libwebp-dev \
libpcre2-dev autoconf automake libtool nlohmann-json3-dev libgeotiff-dev \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /build
# Build GEOS
RUN wget -q https://download.osgeo.org/geos/geos-${GEOS_VERSION}.tar.bz2 \
&& tar xjf geos-${GEOS_VERSION}.tar.bz2 \
&& cd geos-${GEOS_VERSION} && mkdir build && cd build \
&& cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local -DBUILD_TESTING=OFF \
&& ninja && ninja install \
&& cd /build && rm -rf geos-*
# Build PROJ
RUN wget -q https://download.osgeo.org/proj/proj-${PROJ_VERSION}.tar.gz \
&& tar xzf proj-${PROJ_VERSION}.tar.gz \
&& cd proj-${PROJ_VERSION} && mkdir build && cd build \
&& cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local \
-DBUILD_TESTING=OFF -DENABLE_CURL=ON -DENABLE_TIFF=ON \
&& ninja && ninja install \
&& cd /build && rm -rf proj-* && ldconfig
# Build GDAL
RUN wget -q https://github.com/OSGeo/gdal/releases/download/v${GDAL_VERSION}/gdal-${GDAL_VERSION}.tar.gz \
&& tar xzf gdal-${GDAL_VERSION}.tar.gz \
&& cd gdal-${GDAL_VERSION} && mkdir build && cd build \
&& cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local \
-DBUILD_TESTING=OFF -DBUILD_APPS=OFF \
-DGDAL_BUILD_OPTIONAL_DRIVERS=OFF -DOGR_BUILD_OPTIONAL_DRIVERS=OFF \
-DGDAL_USE_GEOS=ON -DGDAL_USE_PROJ=ON -DGDAL_USE_TIFF=ON \
-DGDAL_USE_GEOTIFF=ON -DGDAL_USE_PNG=ON -DGDAL_USE_JPEG=ON \
-DGDAL_USE_WEBP=ON -DGDAL_USE_CURL=ON -DGDAL_USE_SQLITE3=ON \
-DGDAL_USE_POSTGRESQL=ON \
&& ninja && ninja install \
&& cd /build && rm -rf gdal-* && ldconfig
# Build PostGIS for PG18
ENV LD_LIBRARY_PATH=/usr/local/lib
ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
RUN wget -q https://download.osgeo.org/postgis/source/postgis-${POSTGIS_NEW}.tar.gz \
&& tar xzf postgis-${POSTGIS_NEW}.tar.gz \
&& cd postgis-${POSTGIS_NEW} \
&& LDFLAGS="-L/usr/local/lib" CPPFLAGS="-I/usr/local/include" \
./configure \
--with-pgconfig=/usr/lib/postgresql/18/bin/pg_config \
--with-geosconfig=/usr/local/bin/geos-config \
--with-projdir=/usr/local \
--with-gdalconfig=/usr/local/bin/gdal-config \
--with-protobufdir=/usr \
--without-sfcgal \
&& make -j$(nproc) \
&& make install DESTDIR=/postgis-install-pg18 \
&& cd /build && rm -rf postgis-*
# =============================================================================
# Stage 3: Get CNPG tools
# =============================================================================
FROM ghcr.io/cloudnative-pg/postgresql:18 AS cnpg-tools
# =============================================================================
# Stage 4: Final multi-version runtime image
# =============================================================================
FROM postgres:18-bookworm
ARG PG_OLD=16
ARG PG_NEW=18
ARG POSTGIS_NEW
LABEL maintainer="Keyboard Vagabond <admin@mail.keyboardvagabond.com>"
LABEL description="PostgreSQL 16→18 upgrade image with PostGIS for CloudNativePG pg_upgrade (ARM64)"
LABEL org.opencontainers.image.source="https://keyboardvagabond.com"
LABEL pg.upgrade.from="16"
LABEL pg.upgrade.to="18"
ENV POSTGIS_MAJOR=3
ENV POSTGIS_VERSION=${POSTGIS_NEW}
# Install runtime dependencies + PostgreSQL 16 binaries
RUN apt-get update && apt-get install -y --no-install-recommends \
# Runtime libraries for GEOS/PROJ/GDAL/PostGIS
libxml2 libjson-c5 libprotobuf-c1 libsqlite3-0 libtiff6 libcurl4 \
libssl3 zlib1g liblzma5 libzstd1 libpng16-16 libjpeg62-turbo libwebp7 \
libpcre2-8-0 ca-certificates curl jq \
# Python for barman-cloud
python3 python3-boto3 python3-botocore \
# PostgreSQL 16 binaries (required for pg_upgrade)
postgresql-16 \
&& rm -rf /var/lib/apt/lists/*
# Copy compiled libraries from PG18 builder (shared between both versions)
COPY --from=builder-pg18 /usr/local/lib/ /usr/local/lib/
COPY --from=builder-pg18 /usr/local/share/proj/ /usr/local/share/proj/
COPY --from=builder-pg18 /usr/local/share/gdal/ /usr/local/share/gdal/
COPY --from=builder-pg18 /usr/local/bin/geos-config /usr/local/bin/
COPY --from=builder-pg18 /usr/local/bin/gdal-config /usr/local/bin/
COPY --from=builder-pg18 /usr/local/bin/proj /usr/local/bin/
COPY --from=builder-pg18 /usr/local/bin/projinfo /usr/local/bin/
# Copy PostGIS for PG16 (old version)
COPY --from=builder-pg16 /postgis-install-pg16/usr/lib/postgresql/16/lib/ /usr/lib/postgresql/16/lib/
COPY --from=builder-pg16 /postgis-install-pg16/usr/share/postgresql/16/extension/ /usr/share/postgresql/16/extension/
# Copy PostGIS for PG18 (new version)
COPY --from=builder-pg18 /postgis-install-pg18/usr/lib/postgresql/18/lib/ /usr/lib/postgresql/18/lib/
COPY --from=builder-pg18 /postgis-install-pg18/usr/share/postgresql/18/extension/ /usr/share/postgresql/18/extension/
# Update library cache
RUN ldconfig
# Copy barman-cloud tools from CNPG image
COPY --from=cnpg-tools /usr/local/bin/barman* /usr/local/bin/
# -----------------------------------------------------------------------------
# Fix user ID for CloudNativePG compatibility (requires UID 26)
# -----------------------------------------------------------------------------
RUN set -eux; \
CURRENT_UID=$(id -u postgres); \
if [ "$CURRENT_UID" != "26" ]; then \
if getent passwd 26 >/dev/null 2>&1; then \
EXISTING_USER=$(getent passwd 26 | cut -d: -f1); \
usermod -u 9999 "$EXISTING_USER" 2>/dev/null || true; \
fi; \
usermod -u 26 postgres; \
find /var/lib/postgresql -user $CURRENT_UID -exec chown -h 26 {} \; 2>/dev/null || true; \
find /var/run/postgresql -user $CURRENT_UID -exec chown -h 26 {} \; 2>/dev/null || true; \
chown -R postgres:postgres /var/lib/postgresql /var/run/postgresql 2>/dev/null || true; \
fi
# Copy initialization scripts
RUN mkdir -p /docker-entrypoint-initdb.d
COPY ./initdb-postgis.sh /docker-entrypoint-initdb.d/10_postgis.sh
COPY ./update-postgis.sh /usr/local/bin/
RUN chmod +x /docker-entrypoint-initdb.d/10_postgis.sh /usr/local/bin/update-postgis.sh
# -----------------------------------------------------------------------------
# Verify installation - both PG versions and PostGIS
# -----------------------------------------------------------------------------
RUN set -eux; \
echo "=== PostgreSQL Versions ==="; \
/usr/lib/postgresql/16/bin/postgres --version; \
/usr/lib/postgresql/18/bin/postgres --version; \
echo "=== PostGIS Libraries ==="; \
ls -la /usr/lib/postgresql/16/lib/postgis*.so; \
ls -la /usr/lib/postgresql/18/lib/postgis*.so; \
echo "=== pg_upgrade Available ==="; \
/usr/lib/postgresql/18/bin/pg_upgrade --version; \
echo "=== Shared Libraries ==="; \
echo "GEOS: $(geos-config --version)"; \
echo "GDAL: $(gdal-config --version)"; \
id postgres
USER postgres
EXPOSE 5432