From 07bc4e47c6b3517ef19eefbdf9b1e5d48da4983e Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Mon, 16 Feb 2026 00:16:16 -0700 Subject: [PATCH] Add Docker packaging for pg_orbit extension Three-stage Dockerfile: Ubuntu 22.04 builder (glibc-matched to TimescaleDB-HA), scratch artifact image (~748KB), and standalone postgres:17 image. All 6 regression suites run during build. Makefile gains docker-build, docker-push, and docker-test targets. --- .dockerignore | 18 ++++++++++ Dockerfile | 63 ++++++++++++++++++++++++++++++++++ Makefile | 30 ++++++++++++++++ docker/020_install_pg_orbit.sh | 10 ++++++ 4 files changed, 121 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100755 docker/020_install_pg_orbit.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..81c9376 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,18 @@ +.git +**/*.o +**/*.bc +**/*.so +**/*.dylib +results/ +tmp_check/ +log/ +regression.diffs +regression.out +docs/ +README.md +LICENSE +*.swp +*.swo +*~ +.vscode/ +.idea/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..244ccec --- /dev/null +++ b/Dockerfile @@ -0,0 +1,63 @@ +ARG PG_MAJOR=17 + +# ── Stage 1: Compile against PostgreSQL on Ubuntu 22.04 ───── +# Ubuntu Jammy matches TimescaleDB-HA's glibc (2.35). +# Building on Debian Bookworm (glibc 2.36) risks symbol version +# mismatches when the .so loads in TimescaleDB's runtime. +FROM ubuntu:22.04 AS builder + +ARG PG_MAJOR +ARG DEBIAN_FRONTEND=noninteractive + +# PGDG apt repository (same source TimescaleDB-HA uses) +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates curl gnupg lsb-release && \ + curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc \ + | gpg --dearmor -o /usr/share/keyrings/postgresql.gpg && \ + echo "deb [signed-by=/usr/share/keyrings/postgresql.gpg] \ + http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" \ + > /etc/apt/sources.list.d/pgdg.list && \ + apt-get update && apt-get install -y --no-install-recommends \ + postgresql-${PG_MAJOR} \ + postgresql-server-dev-${PG_MAJOR} \ + gcc g++ make && \ + rm -rf /var/lib/apt/lists/* + +# Copy source tree (submodule content included as regular files) +WORKDIR /build/pg_orbit +COPY . . + +ENV PG_CONFIG=/usr/lib/postgresql/${PG_MAJOR}/bin/pg_config + +# Build extension +RUN make PG_CONFIG=${PG_CONFIG} + +# Install to system location (needed for installcheck) +RUN make PG_CONFIG=${PG_CONFIG} install + +# Run all 6 regression test suites against a throwaway cluster +RUN su postgres -c "/usr/lib/postgresql/${PG_MAJOR}/bin/initdb -D /tmp/pgtest" && \ + su postgres -c "/usr/lib/postgresql/${PG_MAJOR}/bin/pg_ctl -D /tmp/pgtest -l /tmp/pgtest.log start" && \ + su postgres -c "/usr/lib/postgresql/${PG_MAJOR}/bin/createuser -s root" && \ + make PG_CONFIG=${PG_CONFIG} installcheck && \ + su postgres -c "/usr/lib/postgresql/${PG_MAJOR}/bin/pg_ctl -D /tmp/pgtest stop" + +# Capture artifacts under /pg_orbit prefix for the next stage +RUN make PG_CONFIG=${PG_CONFIG} DESTDIR=/pg_orbit install + + +# ── Stage 2: Minimal artifact (COPY --from target) ────────── +# ~525 KB total: .so + .control + .sql + init script. +# Downstream images (TimescaleDB-HA, vanilla PG) pull from here. +FROM scratch AS artifact + +COPY --from=builder /pg_orbit/ / +COPY docker/020_install_pg_orbit.sh /docker-entrypoint-initdb.d/ + + +# ── Stage 3: Standalone dev/test image ─────────────────────── +# Ready-to-run PostgreSQL with pg_orbit pre-installed. +# For development, CI, and standalone experiments. +FROM postgres:${PG_MAJOR}-bookworm AS standalone + +COPY --from=artifact / / diff --git a/Makefile b/Makefile index 320d4df..4255fd5 100644 --- a/Makefile +++ b/Makefile @@ -34,3 +34,33 @@ include $(PGXS) # Rule for compiling sat_code C++ files $(SAT_CODE_DIR)/%.o: $(SAT_CODE_DIR)/%.cpp $(CXX) $(CXXFLAGS) -fPIC -I$(SAT_CODE_DIR) -c -o $@ $< + +# ── Docker packaging ──────────────────────────────────────── +REGISTRY ?= git.supported.systems/warehack.ing +IMAGE ?= pg_orbit +PG_MAJOR ?= 17 +TAG ?= pg$(PG_MAJOR) + +docker-build: + docker build --build-arg PG_MAJOR=$(PG_MAJOR) \ + --target artifact -t $(REGISTRY)/$(IMAGE):$(TAG)-artifact . + docker build --build-arg PG_MAJOR=$(PG_MAJOR) \ + --target standalone -t $(REGISTRY)/$(IMAGE):$(TAG) . + +docker-push: + docker push $(REGISTRY)/$(IMAGE):$(TAG)-artifact + docker push $(REGISTRY)/$(IMAGE):$(TAG) + +docker-test: + @echo "Smoke-testing standalone image..." + docker run --rm -d --name pg_orbit_test \ + -e POSTGRES_PASSWORD=test $(REGISTRY)/$(IMAGE):$(TAG) + @echo "Waiting for PostgreSQL to initialize..." + @sleep 10 + docker exec pg_orbit_test psql -U postgres -tAc \ + "SELECT tle_norad_id(E'1 25544U 98067A 24001.50000000 .00016717 00000-0 10270-3 0 9025\n2 25544 51.6400 208.9163 0006703 30.1694 61.7520 15.50100486 00001'::tle);" \ + | grep -q 25544 + @docker stop pg_orbit_test + @echo "Smoke test passed." + +.PHONY: docker-build docker-push docker-test diff --git a/docker/020_install_pg_orbit.sh b/docker/020_install_pg_orbit.sh new file mode 100755 index 0000000..2cc1e3d --- /dev/null +++ b/docker/020_install_pg_orbit.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e + +# Create the pg_orbit extension on first container startup. +# The 020_ prefix orders this after TimescaleDB's own init scripts +# (000_, 001_, 010_) when used in timescaledb-ha images. + +psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "${POSTGRES_DB:-postgres}" <<-'EOSQL' + CREATE EXTENSION IF NOT EXISTS pg_orbit; +EOSQL