Skip to content
Merged
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
6 changes: 3 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ POSTGRES_DB=postgres
# PostgreSQL listens on 5433 by default so PgBouncer can own 5432
# This ensures pooled connections are the default path for clients
POSTGRES_PORT=5433
PG_VERSION=17
PG_VERSION=18

# Application databases and owners to create automatically.
# Format: db_name:db_owner:owner_password
Expand All @@ -25,12 +25,12 @@ DATABASES_TO_CREATE=app_main:app_user:change_me,analytics:analytics_user:change_
# Docker image build metadata
# Set *_TAG values to the stack release you want to consume (default: latest).
# Helpers such as ci-verify/ci-up also respect CORE_DATA_STACK_TAG / CORE_DATA_STACK_REGISTRY:
# CORE_DATA_STACK_TAG=17.2-v1.0.11
# CORE_DATA_STACK_TAG=18.4-v1.0.11
# CORE_DATA_STACK_REGISTRY=ghcr.io/paudley/core_data
POSTGRES_IMAGE_NAME=ghcr.io/paudley/core_data/postgres
POSTGRES_IMAGE_TAG=latest
CORE_DATA_BUILD_IMAGE=0
AGE_VERSION=PG17/v1.7.0-rc0
AGE_VERSION=PG18/v1.7.0-rc0

# Published container images (override to point at a private registry if needed)
VALKEY_IMAGE=ghcr.io/paudley/core_data/valkey:latest
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ jobs:
echo "POSTGRES_RUNTIME_USER=${POSTGRES_RUNTIME_USER:-postgres}"
echo "POSTGRES_RUNTIME_GECOS=${POSTGRES_RUNTIME_GECOS:-Core Data PostgreSQL Administrator}"
echo "POSTGRES_RUNTIME_HOME=${POSTGRES_RUNTIME_HOME:-/home/postgres}"
echo "PG_VERSION=${PG_VERSION:-17}"
echo "AGE_VERSION=${AGE_VERSION:-master}"
echo "PG_VERSION=${PG_VERSION:-18}"
echo "AGE_VERSION=${AGE_VERSION:-PG18/v1.7.0-rc0}"
} >> "$GITHUB_ENV"

- name: Set up Docker Buildx
Expand All @@ -65,8 +65,8 @@ jobs:
--build-arg CORE_USERNAME="${POSTGRES_RUNTIME_USER:-postgres}" \
--build-arg CORE_GECOS="${POSTGRES_RUNTIME_GECOS:-Core Data PostgreSQL Administrator}" \
--build-arg CORE_HOME="${POSTGRES_RUNTIME_HOME:-/home/postgres}" \
--build-arg PG_VERSION="${PG_VERSION:-17}" \
--build-arg AGE_VERSION="${AGE_VERSION:-master}" \
--build-arg PG_VERSION="${PG_VERSION:-18}" \
--build-arg AGE_VERSION="${AGE_VERSION:-PG18/v1.7.0-rc0}" \
--tag "${STACK_REGISTRY}/${service}:${STACK_TAG}" \
.
;;
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/publish-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Publish Docker Image to GHCR
on:
push:
tags:
- '*-v*.*.*' # Matches hybrid tags like 17.2-v1.0.0
- '*-v*.*.*' # Matches hybrid tags like 18.4-v1.0.0
- 'v*.*.*' # Also matches simple semantic tags like v1.0.0

env:
Expand Down Expand Up @@ -93,7 +93,7 @@ jobs:
case "${{ matrix.service }}" in
postgres)
title="Core Data PostgreSQL"
desc="Hardened PostgreSQL 17 image with spatial/vector/graph extensions."
desc="Hardened PostgreSQL 18 image with spatial/vector/graph extensions."
;;
valkey)
title="Core Data ValKey"
Expand Down Expand Up @@ -132,7 +132,7 @@ jobs:
- name: Prepare build args
id: build-args
env:
PG_VERSION: ${{ steps.version.outputs.pg_major || '17' }}
PG_VERSION: ${{ steps.version.outputs.pg_major || '18' }}
shell: bash
run: |
if [[ "${{ matrix.service }}" == "postgres" ]]; then
Expand All @@ -144,7 +144,7 @@ jobs:
echo "CORE_GECOS=Core Data PostgreSQL Administrator"
echo "CORE_HOME=/home/postgres"
echo "PG_VERSION=${PG_VERSION}"
echo "AGE_VERSION=master"
echo "AGE_VERSION=PG${PG_VERSION}/v1.7.0-rc0"
echo "EOT"
} >>"$GITHUB_OUTPUT"
else
Expand All @@ -157,7 +157,7 @@ jobs:
with:
images: ${{ env.REGISTRY }}/${{ github.repository }}/${{ matrix.service }}
tags: |
# For hybrid tags (17.2-v1.0.0), create multiple tags
# For hybrid tags (18.4-v1.0.0), create multiple tags
type=raw,value=${{ steps.version.outputs.tag }},enable=${{ steps.version.outputs.is_hybrid == 'true' }}
type=raw,value=${{ steps.version.outputs.pg_version }}-v${{ steps.version.outputs.sem_minor }},enable=${{ steps.version.outputs.is_hybrid == 'true' }}
type=raw,value=${{ steps.version.outputs.pg_version }}-v${{ steps.version.outputs.sem_major }},enable=${{ steps.version.outputs.is_hybrid == 'true' }}
Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ docker-compose.override.yml
*.swp
.DS_Store
.claude
.code-ethos/cache/
.coding-ethos/cache/
.coding-ethos/hook-runs/
.coding-ethos/lint-runs/
.coding-ethos/prune-runs/
.coding-ethos/state/
.coding-ethos/code-intel.db

# Node (if used for tooling)
node_modules/
Expand Down
12 changes: 6 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Allow PostgreSQL superuser names with hyphens by quoting the role in init scripts when creating the `core_data_admin` schema.
* Fixed `./scripts/manage.sh backup` so it no longer treats the command name as an argument, restoring pgBackRest backup/verify flows.

## [17.2-v1.0.0] - TBD
## [18.4-v1.0.0] - TBD

### Added

#### Core Database

* PostgreSQL 17.2 on Debian Bookworm base image
* PostgreSQL 18.4 on Debian Bookworm base image
* Custom Docker image with comprehensive extension suite
* Automated database initialization and configuration templating
* User and permission management via environment variables
Expand All @@ -33,7 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
#### Vector and Graph Database

* pgvector for AI/ML vector similarity search
* Apache AGE (latest) for graph database capabilities built from source
* Apache AGE `PG18/v1.7.0-rc0` for graph database capabilities built from source

#### Performance and Optimization

Expand Down Expand Up @@ -90,7 +90,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

#### Documentation

* Best practices guide for Dockerized PostgreSQL 17
* Best practices guide for Dockerized PostgreSQL 18
* Initial concept and architecture documentation
* Service configuration examples
* Environment variable reference
Expand Down Expand Up @@ -126,6 +126,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Secure credential management via environment variables
* No hardcoded secrets in repository

[17.2-v1.0.0]: https://github.com/paudley/core_data/releases/tag/17.2-v1.0.0
[18.4-v1.0.0]: https://github.com/paudley/core_data/releases/tag/18.4-v1.0.0

[unreleased]: https://github.com/paudley/core_data/compare/17.2-v1.0.0...HEAD
[unreleased]: https://github.com/paudley/core_data/compare/18.4-v1.0.0...HEAD
2 changes: 1 addition & 1 deletion CI_USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ This repository ships helpers and workflows tuned for CI pipelines that rely on
```

## Published images and attestations
- Postgres image tag is `${POSTGRES_IMAGE_NAME:-core_data/postgres}:${POSTGRES_IMAGE_TAG:-17.2-bookworm-core}`. CI builds/publishes to GHCR; attestations can be checked with:
- Postgres image tag is `${POSTGRES_IMAGE_NAME:-core_data/postgres}:${POSTGRES_IMAGE_TAG:-18.4-bookworm-core}`. CI builds/publishes to GHCR; attestations can be checked with:
```bash
gh attestation verify oci://ghcr.io/paudley/core_data/postgres:<tag> --repo paudley/core_data
```
Expand Down
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ SPDX-License-Identifier: MIT
[![CI](https://github.com/paudley/core_data/actions/workflows/ci.yml/badge.svg)](https://github.com/paudley/core_data/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

A reproducible PostgreSQL 17 platform delivered as code. core\_data builds a hardened database image with spatial, vector, and graph extensions and ships a management CLI that automates backups, restores, QA cloning, and upgrades. Everything lives in version control so environments can be rebuilt consistently across laptops, CI, and production.
A reproducible PostgreSQL 18 platform delivered as code. core\_data builds a hardened database image with spatial, vector, and graph extensions and ships a management CLI that automates backups, restores, QA cloning, and upgrades. Everything lives in version control so environments can be rebuilt consistently across laptops, CI, and production.

## Why You Want This

* Run the same Postgres 17 stack everywhere: laptop, CI runner, or production.
* Run the same Postgres 18 stack everywhere: laptop, CI runner, or production.
* Ship with the heavy hitters pre-installed—PostGIS, pgvector, AGE, pg\_cron, pgBackRest—without custom build scripts.
* Automate the boring-but-critical tasks: backups, restores, QA clones, log analytics, and even major version upgrades via pgautoupgrade.
* Treat your database like code with reproducible `.env` configs, templated init scripts, and a pytest smoke test that catches regressions early.
Expand All @@ -28,7 +28,7 @@ Pre-built images are available from GitHub Container Registry with full SLSA att
docker pull ghcr.io/paudley/core-data-postgres:latest

# Or specify a version
docker pull ghcr.io/paudley/core-data-postgres:17.2-v1.0.0
docker pull ghcr.io/paudley/core-data-postgres:18.4-v1.0.0
```

### Available Tags
Expand All @@ -38,15 +38,15 @@ Images follow a hybrid versioning strategy combining PostgreSQL version with sem
| Tag Pattern | Example | Description |
| --------------------------------------- | ------------- | ---------------------------------------------- |
| `latest` | `latest` | Latest stable release |
| `{PG_VERSION}-v{MAJOR}.{MINOR}.{PATCH}` | `17.2-v1.0.0` | Exact version (recommended for production) |
| `{PG_VERSION}-v{MAJOR}.{MINOR}` | `17.2-v1.0` | Latest patch for minor version |
| `{PG_VERSION}-v{MAJOR}` | `17.2-v1` | Latest minor for major version |
| `{PG_VERSION}` | `17.2` | Latest semantic version for PostgreSQL version |
| `{PG_MAJOR}` | `17` | Latest for PostgreSQL major version |
| `{PG_VERSION}-v{MAJOR}.{MINOR}.{PATCH}` | `18.4-v1.0.0` | Exact version (recommended for production) |
| `{PG_VERSION}-v{MAJOR}.{MINOR}` | `18.4-v1.0` | Latest patch for minor version |
| `{PG_VERSION}-v{MAJOR}` | `18.4-v1` | Latest minor for major version |
| `{PG_VERSION}` | `18.4` | Latest semantic version for PostgreSQL version |
| `{PG_MAJOR}` | `18` | Latest for PostgreSQL major version |

**Version Format**: `{PostgreSQL_Version}-v{Semantic_Version}`

* Example: `17.2-v1.0.0` means PostgreSQL 17.2 with semantic version 1.0.0
* Example: `18.4-v1.0.0` means PostgreSQL 18.4 with semantic version 1.0.0
* See [docs/RELEASING.md](docs/RELEASING.md) for complete versioning details

### Security & Verification
Expand All @@ -55,12 +55,12 @@ All published images include cryptographic attestations that prove build provena

```bash
# Verify image attestation (requires GitHub CLI)
gh attestation verify oci://ghcr.io/paudley/core-data-postgres:17.2-v1.0.0 \
gh attestation verify oci://ghcr.io/paudley/core-data-postgres:18.4-v1.0.0 \
--owner paudley

# Pull and verify in one step
docker pull ghcr.io/paudley/core-data-postgres:17.2-v1.0.0
gh attestation verify oci://ghcr.io/paudley/core-data-postgres:17.2-v1.0.0 \
docker pull ghcr.io/paudley/core-data-postgres:18.4-v1.0.0
gh attestation verify oci://ghcr.io/paudley/core-data-postgres:18.4-v1.0.0 \
--owner paudley

# Verify every referenced image from your .env (pretty console output)
Expand Down Expand Up @@ -94,7 +94,7 @@ Expected verification output:

sha256:abc123... was attested by:
REPO PREDICATE_TYPE WORKFLOW
paudley/core_data https://slsa.dev/provenance/v1 .github/workflows/publish-docker.yml@refs/tags/17.2-v1.0.0
paudley/core_data https://slsa.dev/provenance/v1 .github/workflows/publish-docker.yml@refs/tags/18.4-v1.0.0
```

**What's Verified:**
Expand All @@ -115,7 +115,7 @@ Update your `docker-compose.yml` to use the published image instead of building
```yaml
services:
postgres:
image: ghcr.io/paudley/core-data-postgres:17.2-v1.0.0 # Use published image
image: ghcr.io/paudley/core-data-postgres:18.4-v1.0.0 # Use published image
# Remove or comment out the 'build:' section
# build:
# context: .
Expand All @@ -126,7 +126,7 @@ Or override via `.env`:

```bash
POSTGRES_IMAGE_NAME=ghcr.io/paudley/core-data-postgres
POSTGRES_IMAGE_TAG=17.2-v1.0.0
POSTGRES_IMAGE_TAG=18.4-v1.0.0
```

### Important: UID/GID Configuration for Pre-built Images
Expand Down
2 changes: 1 addition & 1 deletion ci.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ DATABASES_TO_CREATE=ci_db:ci_user:ci_password

# Consume published images (override tags to match the release you pinned).
# Set CORE_DATA_STACK_TAG / CORE_DATA_STACK_REGISTRY to propagate the same tag/registry across helpers:
# CORE_DATA_STACK_TAG=17.2-v1.0.11
# CORE_DATA_STACK_TAG=18.4-v1.0.11
# CORE_DATA_STACK_REGISTRY=ghcr.io/paudley/core_data
POSTGRES_IMAGE_NAME=ghcr.io/paudley/core_data/postgres
POSTGRES_IMAGE_TAG=latest
Expand Down
10 changes: 5 additions & 5 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ services:
- ./scripts/network_probe.sh:/opt/core_data/scripts/network_probe.sh:ro

volume_prep:
image: ${POSTGRES_IMAGE_NAME:-core_data/postgres}:${POSTGRES_IMAGE_TAG:-17.2-bookworm-core}
image: ${POSTGRES_IMAGE_NAME:-core_data/postgres}:${POSTGRES_IMAGE_TAG:-18.4-bookworm-core}
container_name: ${COMPOSE_PROJECT_NAME:-core_data}_volume_prep
restart: "no"
# Runs as root briefly to fix ownership; uses Docker's default capabilities.
Expand Down Expand Up @@ -121,9 +121,9 @@ services:
CORE_GECOS: ${POSTGRES_RUNTIME_GECOS:-Core Data PostgreSQL Administrator}
CORE_HOME: ${POSTGRES_RUNTIME_HOME:-/home/postgres}
SECRETS_GID: ${SECRETS_GID:-65532}
PG_VERSION: ${PG_VERSION:-17}
AGE_VERSION: ${AGE_VERSION:-PG17/v1.7.0-rc0}
image: ${POSTGRES_IMAGE_NAME:-core_data/postgres}:${POSTGRES_IMAGE_TAG:-17.2-bookworm-core}
PG_VERSION: ${PG_VERSION:-18}
AGE_VERSION: ${AGE_VERSION:-PG18/v1.7.0-rc0}
image: ${POSTGRES_IMAGE_NAME:-core_data/postgres}:${POSTGRES_IMAGE_TAG:-18.4-bookworm-core}
container_name: ${COMPOSE_PROJECT_NAME:-core_data}_postgres
restart: unless-stopped
user: "${POSTGRES_UID:-1000}:${POSTGRES_GID:-1000}"
Expand Down Expand Up @@ -224,7 +224,7 @@ services:
- "no-new-privileges:true"
- "${CORE_DATA_SECCOMP_LOGICAL_BACKUP:-seccomp:./seccomp/logical_backup.json}"
- "${CORE_DATA_APPARMOR_LOGICAL_BACKUP:-apparmor:unconfined}"
image: ${POSTGRES_IMAGE_NAME:-core_data/postgres}:${POSTGRES_IMAGE_TAG:-17.2-bookworm-core}
image: ${POSTGRES_IMAGE_NAME:-core_data/postgres}:${POSTGRES_IMAGE_TAG:-18.4-bookworm-core}
container_name: ${COMPOSE_PROJECT_NAME:-core_data}_logical_backup
restart: unless-stopped
user: "${POSTGRES_UID:-1000}:${POSTGRES_GID:-1000}"
Expand Down
8 changes: 4 additions & 4 deletions docs/Initial_Concept.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ SPDX-License-Identifier: MIT

## Overview

core\_data packages a production-focused PostgreSQL 17 environment using Docker Compose. The platform builds a custom PostgreSQL image with spatial, graph, auditing, and automation extensions and ships helper scripts for day-two operations such as backups, tuning, and log analytics. All behavior is driven from version-controlled assets so the stack can be reproduced consistently across environments.
core\_data packages a production-focused PostgreSQL 18 environment using Docker Compose. The platform builds a custom PostgreSQL image with spatial, graph, auditing, and automation extensions and ships helper scripts for day-two operations such as backups, tuning, and log analytics. All behavior is driven from version-controlled assets so the stack can be reproduced consistently across environments.

## Repository Layout

Expand Down Expand Up @@ -69,10 +69,10 @@ The `.env` file is the single source of truth for runtime tuning. The template d
| `POSTGRES_SUPERUSER_PASSWORD` | Password for the superuser; required before running the stack. | `change_me` |
| `POSTGRES_DB` | Name of the primary database created by the official entrypoint. | `postgres` |
| `POSTGRES_PORT` | Host port mapped to PostgreSQL (5433 default, allowing PgBouncer to own 5432). | `5433` |
| `PG_VERSION` | Major PostgreSQL version that drives the Dockerfile build ARG. | `17` |
| `PG_VERSION` | Major PostgreSQL version that drives the Dockerfile build ARG. | `18` |
| `DATABASES_TO_CREATE` | Comma-delimited list of `db:owner:password` tuples consumed by `01-init-db-user-creation.sh`. | `app_main:app_user:secret` |
| `POSTGRES_IMAGE_NAME` / `POSTGRES_IMAGE_TAG` | Optional overrides for tagging the custom image. | `core_data/postgres` / `17.2-bookworm-core` |
| `AGE_VERSION` | Git ref used when cloning and compiling Apache AGE. | `master` |
| `POSTGRES_IMAGE_NAME` / `POSTGRES_IMAGE_TAG` | Optional overrides for tagging the custom image. | `core_data/postgres` / `18.4-bookworm-core` |
| `AGE_VERSION` | Git ref used when cloning and compiling Apache AGE. | `PG18/v1.7.0-rc0` |
| `POSTGRES_MEMORY_LIMIT` | Memory limit passed to the PostgreSQL container. | `4g` |
| `POSTGRES_CPU_LIMIT` | CPU cores allocated to the PostgreSQL container. | `2` |
| `POSTGRES_SHM_SIZE` | `/dev/shm` allocation to support parallel workers. | `1g` |
Expand Down
Loading
Loading