✨ Commits existing images to git
- Implemented sync-roles.sh to synchronize Active Directory group memberships as MariaDB roles and user accounts. - Created Containerfile for building a custom ldap2pg image with patched YAML decoding. - Added provision-user-db.sh for provisioning user databases and roles based on LDAP synchronization. - Introduced a new Containerfile for MariaDB with PAM authentication via pam_ldap. - Configured PAM service for MariaDB logins and added necessary plugins for LDAP authentication. - Implemented health checks and entrypoint scripts for MariaDB and pgpool containers. - Enhanced PostgreSQL image with additional extensions and custom pg_hba.conf for improved security and functionality.
This commit is contained in:
20 files changed
+1023
No files matched your search
@@ -0,0 +1,89 @@
|
||||
# images
|
||||
|
||||
Container images published to `containers.kritikos.io`, built with Docker Compose.
|
||||
|
||||
```powershell
|
||||
docker compose build # all images
|
||||
docker compose build postgres # one image
|
||||
```
|
||||
|
||||
Every version is a build arg supplied from [database/.env](database/.env); see
|
||||
[database/compose.yaml](database/compose.yaml) for the wiring.
|
||||
|
||||
## Alpine version vs. PostgreSQL major
|
||||
|
||||
`ALPINE_VERSION` and `PG_MAJOR` are not independent. The Alpine-based images
|
||||
(`pgpool`, `ldap2pg`, `ldap2mariadb`) install PostgreSQL packages with
|
||||
`apk add postgresql${PG_MAJOR}-dev` / `-client`, and an Alpine image's `apk`
|
||||
repositories are fixed to that release's branch. Each branch packages only a
|
||||
subset of PostgreSQL majors, and that subset changes every release:
|
||||
|
||||
| Alpine branch | `postgresql*-dev` available |
|
||||
| ------------- | ----------------------------- |
|
||||
| edge | 18, 17, 16 |
|
||||
| v3.24 | 18, 17 (main), 16 (community) |
|
||||
| v3.23 | 18, 17 (main), 16 (community) |
|
||||
| v3.22 | 17, 16 (main), 15 (community) |
|
||||
|
||||
_Measured with `apk policy` inside each branch's image on 2026-08-15._
|
||||
|
||||
So `PG_MAJOR=18` requires Alpine 3.23 or newer. The coupling breaks in both
|
||||
directions:
|
||||
|
||||
- Raising `PG_MAJOR` before Alpine's stable branch packages that major fails the
|
||||
build — a September PostgreSQL release will not reach a stable Alpine until
|
||||
that branch ships.
|
||||
- Leaving `PG_MAJOR` behind while Alpine advances fails eventually too: ageing
|
||||
majors are demoted from `main` to `community`, then dropped. 16 has already
|
||||
fallen to community on v3.23, and 15 is gone from v3.23 onwards.
|
||||
|
||||
**Bump `ALPINE_VERSION` and `PG_MAJOR` together**, and confirm the target branch
|
||||
carries `postgresql${PG_MAJOR}-dev` before doing so.
|
||||
|
||||
Pinning matters because `alpine:latest` is a mutable tag that follows Alpine's
|
||||
roughly six-monthly releases, so the same commit can build against a different
|
||||
base OS and a different package set on a later day. Note that `--no-cache` on
|
||||
`apk add` does not pin anything — it only avoids a stale index, and package
|
||||
versions still float within the branch.
|
||||
|
||||
`pgpool` is the image most exposed to this, since it is the one that *compiles*
|
||||
against `postgresql${PG_MAJOR}-dev` rather than just installing a client. All
|
||||
three Alpine-based images (`pgpool`, `ldap2pg`, `ldap2mariadb`) take
|
||||
`ALPINE_VERSION` from `database/.env`, currently pinned to `3.23`.
|
||||
|
||||
## pgpool health check
|
||||
|
||||
pgpool ships no health endpoint of its own. Its `health_check_period` settings
|
||||
govern how pgpool probes *its backends* to drive failover, and the PCP tools
|
||||
(`pcp_node_info` and friends) need a `pcp.conf` user plus a password file, which
|
||||
is more than a container probe should carry. The image therefore probes with
|
||||
`pg_isready` against the pgpool port.
|
||||
|
||||
What that reports, measured against two live backends:
|
||||
|
||||
| Backend state | Health |
|
||||
| --------------------------------- | ------ |
|
||||
| all nodes up | green |
|
||||
| standby down, degenerated | green |
|
||||
| primary down, standby promoted | green |
|
||||
| during failover (~one check cycle)| red |
|
||||
| no node attached, or no primary | red |
|
||||
|
||||
So green means **pgpool can serve**, not that the cluster is healthy. Losing a
|
||||
standby is invisible to it, and because pgpool keeps a node `down` until
|
||||
`pcp_attach_node` is run, the probe stays green after a backend recovers while
|
||||
the pool is still running on one node. Track node-level state with
|
||||
`SHOW POOL_NODES` instead.
|
||||
|
||||
Two consequences for compose files consuming this image:
|
||||
|
||||
- `depends_on: condition: service_healthy` is the intended use — it stops
|
||||
dependents from starting against a pool that has no primary.
|
||||
- Do not restart pgpool on unhealthy. Bouncing it during a backend outage resets
|
||||
its node status and drops the pool without fixing anything.
|
||||
|
||||
In a real streaming-replication cluster the survivor of a primary loss is in
|
||||
recovery, so `find_primary_node` reports nothing until `failover_command`
|
||||
promotes it; connections fail with `failed to create a backend connection` and
|
||||
the probe goes red for that whole window. The check is therefore gated on
|
||||
failover automation working, not merely on a node being up.
|
||||
Reference in new issue
Block a user