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
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
target
**/node_modules
.git
packer/staging
76 changes: 76 additions & 0 deletions .github/workflows/release-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Release image
on:
push:
tags:
- image/v*
permissions:
contents: read
packages: write
env:
IMAGE: ghcr.io/beyondoss/beyond-postgres
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- runs-on: ubuntu-latest
arch: amd64
- runs-on: ubuntu-24.04-arm
arch: arm64
runs-on: ${{ matrix.runs-on }}
steps:
- uses: actions/checkout@v7
- uses: docker/setup-buildx-action@v4
- uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- id: build
uses: docker/build-push-action@v7
with:
context: .
file: docker/Dockerfile
platforms: linux/${{ matrix.arch }}
outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true
cache-from: type=gha,scope=image-${{ matrix.arch }}
cache-to: type=gha,mode=max,scope=image-${{ matrix.arch }}
- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- uses: actions/upload-artifact@v7
with:
name: digest-${{ matrix.arch }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
merge:
runs-on: ubuntu-latest
needs: [build]
steps:
- uses: actions/download-artifact@v8
with:
path: /tmp/digests
pattern: digest-*
merge-multiple: true
- uses: docker/setup-buildx-action@v4
- uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Resolve version
id: meta
run: echo "version=${GITHUB_REF_NAME#image/v}" >> "$GITHUB_OUTPUT"
- name: Create manifest list
working-directory: /tmp/digests
run: |
docker buildx imagetools create \
-t ${{ env.IMAGE }}:${{ steps.meta.outputs.version }} \
-t ${{ env.IMAGE }}:latest \
$(printf '${{ env.IMAGE }}@sha256:%s ' *)
- name: Inspect
run: docker buildx imagetools inspect ${{ env.IMAGE }}:${{ steps.meta.outputs.version }}
43 changes: 43 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# syntax=docker/dockerfile:1
# Postgres 18 bundled with the beyond_auth extension + the queue schema, for
# local-dev / docker-compose (ghcr.io/beyondoss/beyond-postgres).
#
# This is the Docker analogue of the production rootfs: prod builds the same
# beyond_auth/beyond_queue extensions (packer/scripts/build-beyond-extensions.sh,
# pinned in extensions.toml) into an ubuntu-noble Firecracker image. Here we layer
# them onto the official postgres:18 image so a generated app can `docker pull` a
# working database. Extension sources are cloned at AUTH_REF / QUEUE_REF.
ARG AUTH_REF=main
ARG QUEUE_REF=main

# ---- build the beyond_auth pgrx extension against pg18 -----------------------
FROM postgres:18-bookworm AS extbuilder
ARG AUTH_REF
RUN apt-get update && apt-get install -y --no-install-recommends \
curl build-essential clang libclang-dev pkg-config libssl-dev \
postgresql-server-dev-18 ca-certificates git \
&& rm -rf /var/lib/apt/lists/*
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
| sh -s -- -y --default-toolchain 1.92.0 --profile minimal
ENV PATH="/root/.cargo/bin:${PATH}"
# cargo-pgrx must match the extension's pgrx dependency (=0.18.0).
RUN cargo install cargo-pgrx --version 0.18.0 --locked
# Register pg18 (system install) so PGRX_HOME exists; no postgres is downloaded.
RUN cargo pgrx init --pg18 /usr/bin/pg_config
RUN git clone --depth 1 --branch "${AUTH_REF}" https://github.com/beyondoss/auth /src/auth
WORKDIR /src/auth/beyond-auth-extension
# Installs control + SQL + .so into this image's postgres dirs.
RUN cargo pgrx install --release --features pg18 --no-default-features --pg-config /usr/bin/pg_config

# ---- fetch the queue schema (PL/pgSQL hot paths; no pgrx ext needed) ---------
FROM alpine/git AS queuesrc
ARG QUEUE_REF
RUN git clone --depth 1 --branch "${QUEUE_REF}" https://github.com/beyondoss/queue /src/queue

# ---- final image ------------------------------------------------------------
FROM postgres:18-bookworm
COPY --from=extbuilder /usr/share/postgresql/18/extension/beyond_auth* /usr/share/postgresql/18/extension/
COPY --from=extbuilder /usr/lib/postgresql/18/lib/beyond_auth.so /usr/lib/postgresql/18/lib/
COPY --from=queuesrc /src/queue/beyond-queue-extension/sql/schema.sql /opt/queue/schema.sql
COPY --from=queuesrc /src/queue/tests/fixtures/hot_paths.sql /opt/queue/hot_paths.sql
COPY docker/initdb.sh /docker-entrypoint-initdb.d/10-beyond-init.sh
23 changes: 23 additions & 0 deletions docker/initdb.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
# Runs once on first DB init (against POSTGRES_DB). Sets up the schemas the
# primitives expect in the shared app database:
# - auth : auth server auto-migrates + CREATE EXTENSION beyond_auth (installed in the image)
# - queue : schema + PL/pgSQL hot paths
# - public : the app's own migrations
set -euo pipefail

# beyond_auth owns (creates) the `auth` schema, so let the extension make it
# rather than pre-creating it (pre-creating triggers "schema auth is not a member
# of extension"). The auth server's CREATE EXTENSION IF NOT EXISTS is then a no-op.
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<'SQL'
CREATE EXTENSION IF NOT EXISTS beyond_auth;
CREATE SCHEMA IF NOT EXISTS queue;
SQL

# Queue: base schema then the PL/pgSQL hot-path overrides (search_path=queue).
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" \
-c 'SET search_path = queue, public;' -f /opt/queue/schema.sql
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" \
-c 'SET search_path = queue, public;' -f /opt/queue/hot_paths.sql

echo "[beyond-init] auth/queue schemas ready in ${POSTGRES_DB}"