feat: publish a prebuilt OpenLDAP-with-nestgroup base image (#187)
Extracts Dockerfile.openldap's `ldapbuild` stage (compile OpenLDAP from source for the nestgroup overlay, ~5 min, dependent on git.openldap.org being reachable) into its own Dockerfile, built and pushed to ghcr.io/theta42/openldap-nestgroup by this workflow whenever the pinned commit changes. This commit only adds the new image + workflow; Dockerfile.openldap itself still compiles from source. A follow-up change switches it to FROM the published image once this workflow has run once and the image exists. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
name: Build OpenLDAP Base Image
|
||||
|
||||
# Publishes ghcr.io/theta42/openldap-nestgroup, the prebuilt slapd-with-
|
||||
# nestgroup image Dockerfile.openldap's `ldapbuild` stage pulls FROM instead
|
||||
# of compiling from source on every build (see Dockerfile.openldap-builder
|
||||
# for why, and the ~5 minute + git.openldap.org-dependent cost it replaces).
|
||||
#
|
||||
# Runs only when the builder Dockerfile changes -- bumping OPENLDAP_COMMIT in
|
||||
# it is the only reason this image should ever need rebuilding -- or on
|
||||
# manual dispatch.
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
paths:
|
||||
- 'Dockerfile.openldap-builder'
|
||||
- '.github/workflows/build-openldap-image.yml'
|
||||
workflow_dispatch: {}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# Single source of truth for the tag: the ARG default in the Dockerfile
|
||||
# itself, not a value duplicated into this workflow.
|
||||
- name: Resolve pinned OpenLDAP commit
|
||||
id: commit
|
||||
run: |
|
||||
commit=$(grep -oP '^ARG OPENLDAP_COMMIT=\K[0-9a-f]+' Dockerfile.openldap-builder)
|
||||
if [ -z "$commit" ]; then
|
||||
echo "::error::Could not resolve OPENLDAP_COMMIT from Dockerfile.openldap-builder"
|
||||
exit 1
|
||||
fi
|
||||
echo "commit=$commit" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile.openldap-builder
|
||||
build-args: |
|
||||
OPENLDAP_COMMIT=${{ steps.commit.outputs.commit }}
|
||||
push: true
|
||||
tags: |
|
||||
ghcr.io/theta42/openldap-nestgroup:${{ steps.commit.outputs.commit }}
|
||||
ghcr.io/theta42/openldap-nestgroup:latest
|
||||
@@ -0,0 +1,75 @@
|
||||
# OpenLDAP-with-nestgroup builder, published to
|
||||
# ghcr.io/theta42/openldap-nestgroup:<OPENLDAP_COMMIT short hash>.
|
||||
#
|
||||
# Extracted out of Dockerfile.openldap's `ldapbuild` stage so the ~5 minute
|
||||
# from-source compile (which also depends on git.openldap.org being up)
|
||||
# happens once, here, instead of on every `docker build` of the app image --
|
||||
# including every CI run's 3-way test matrix. Dockerfile.openldap's ldapbuild
|
||||
# stage becomes `FROM ghcr.io/theta42/openldap-nestgroup:<commit>` and the
|
||||
# rest of that file (the COPY --from=ldapbuild lines) is unchanged, since
|
||||
# COPY --from also accepts an external image, not just a local stage name.
|
||||
#
|
||||
# Bumping OPENLDAP_COMMIT is a two-step change: update the ARG below, push
|
||||
# (the build-openldap-image workflow rebuilds+republishes the tag on changes
|
||||
# to this file), then update the matching FROM line in Dockerfile.openldap.
|
||||
#
|
||||
# See Dockerfile.openldap's own "OpenLDAP from source" comment for *why*
|
||||
# from-source at all (the nestgroup overlay, ITS#10161) and the LMDB format
|
||||
# note (master's 1.0.0 vs 2.6.x's 0.9.x).
|
||||
FROM node:20-alpine AS build
|
||||
|
||||
# groff is not optional despite producing nothing we ship: the build descends
|
||||
# into doc/man unconditionally and its Makefile calls soelim, which groff
|
||||
# provides. Without it the whole `make` fails at the man-page stage
|
||||
# ("soelim: not found") long after slapd itself has compiled fine.
|
||||
RUN apk add --no-cache \
|
||||
build-base autoconf automake libtool \
|
||||
openssl-dev cyrus-sasl-dev \
|
||||
git make pkgconf util-linux-dev groff
|
||||
|
||||
# Pinned to an exact commit, not a branch tip -- see Dockerfile.openldap for
|
||||
# why (this is the directory server the whole lab authenticates against).
|
||||
ARG OPENLDAP_COMMIT=350e9eb38b2270c2bad97c61ee02e85fb8f3196d
|
||||
|
||||
WORKDIR /src
|
||||
RUN git init -q . \
|
||||
&& git remote add origin https://git.openldap.org/openldap/openldap.git \
|
||||
&& git fetch -q --depth 1 origin "${OPENLDAP_COMMIT}" \
|
||||
&& git checkout -q FETCH_HEAD \
|
||||
&& git rev-parse HEAD > /opt-openldap-commit.txt
|
||||
|
||||
# Overlays are built as loadable modules (=mod) because docker-entrypoint.sh
|
||||
# `moduleload`s them individually; nestgroup joins that set.
|
||||
RUN ./configure \
|
||||
--prefix=/opt/openldap \
|
||||
--enable-slapd \
|
||||
--enable-modules \
|
||||
--enable-mdb \
|
||||
--enable-memberof=mod \
|
||||
--enable-refint=mod \
|
||||
--enable-ppolicy=mod \
|
||||
--enable-dynlist=mod \
|
||||
--enable-nestgroup=mod \
|
||||
--enable-syncprov=mod \
|
||||
--enable-auditlog=mod \
|
||||
--with-tls=openssl \
|
||||
--with-cyrus-sasl \
|
||||
&& make depend \
|
||||
&& make -j"$(nproc)" \
|
||||
&& make install
|
||||
|
||||
# pw-sha2 provides {SSHA512}, which every existing user password is stored as.
|
||||
# It lives in contrib and is not covered by the configure flags above, so it is
|
||||
# built separately against the just-built tree -- omitting it would make every
|
||||
# user password unverifiable.
|
||||
RUN cd contrib/slapd-modules/passwd/sha2 \
|
||||
&& make prefix=/opt/openldap OPENLDAP_SRC=/src \
|
||||
&& cp .libs/pw-sha2.so* /opt/openldap/libexec/openldap/
|
||||
|
||||
# Pure artifact holder -- no shell, no package manager, nothing but the
|
||||
# compiled tree. Dockerfile.openldap's COPY --from=ldapbuild only ever reads
|
||||
# files, never RUNs anything in this stage, so scratch is sufficient and
|
||||
# keeps the published image (and every pull of it) as small as possible.
|
||||
FROM scratch
|
||||
COPY --from=build /opt/openldap /opt/openldap
|
||||
COPY --from=build /opt-openldap-commit.txt /opt-openldap-commit.txt
|
||||
Reference in New Issue
Block a user