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.
This commit is contained in:
Ryan Malloy 2026-02-16 00:16:16 -07:00
parent 28511a34a2
commit 07bc4e47c6
4 changed files with 121 additions and 0 deletions

18
.dockerignore Normal file
View File

@ -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/

63
Dockerfile Normal file
View File

@ -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 / /

View File

@ -34,3 +34,33 @@ include $(PGXS)
# Rule for compiling sat_code C++ files # Rule for compiling sat_code C++ files
$(SAT_CODE_DIR)/%.o: $(SAT_CODE_DIR)/%.cpp $(SAT_CODE_DIR)/%.o: $(SAT_CODE_DIR)/%.cpp
$(CXX) $(CXXFLAGS) -fPIC -I$(SAT_CODE_DIR) -c -o $@ $< $(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

10
docker/020_install_pg_orbit.sh Executable file
View File

@ -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