Skip to content

Commit

Permalink
Move and configure lib directories (#98)
Browse files Browse the repository at this point in the history
Instead of OS-specific and Postgres version-specific `lib` directories,
just have `mod` for Postgres extension module files and `lib` for shared
libraries they depend on. For example, the `pgsql_http` extension's
`http.so` file would be installed in `mod` and its dependency,
`libcurl`, in `lib`. Both remain part of the `postgres` binary's
runpath:

```console
/usr/lib/postgresql/bin/postgres: RUNPATH=/usr/lib/postgresql/lib:/var/lib/postgresql/tembo/mod:/var/lib/postgresql/tembo/lib
```

While at it, remove LLVM, Python, Tcl, and Perl from the base image,
eliminating around 180MB from the image size. LLVM is not needed on the
image, and the dynamic language libraries only needed if their
accompanying extensions are installed; we'll want to install them when
their extensions are installed.

Update `docker-entrypoint.sh` to add `/var/lib/postgresql/tembo/mod` to
the `dynamic_library_path`, so that Postgres can find extension modules
there. Control files will need `$libdir/` stripped from
`module_pathname` for this to work, a change likely to be included in
Postgres 18 but we'll have to do when installing extensions there.

Other changes:

*   Fix workflow push on main an move a couple of `Dockerfile` items around.
*   Update the image URLs and directory descriptions the READMEs.
  • Loading branch information
theory committed Mar 11, 2025
1 parent a3df8ae commit 1934219
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 31 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/bake.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ jobs:
with:
pull: true
# Push only on main.
set: ${{ github.ref_name == 'main' && '' || '*.output=type=cacheonly' }}
set: "*.output=type=${{ github.ref_name == 'main' && 'image,push-by-digest=true,push=true' || 'cacheonly' }}"
- name: Save Metadata
run: echo '${{ steps.build.outputs.metadata }}' > build-${{ matrix.arch[1] }}-${{ matrix.os[1] }}-${{ matrix.pg }}.json
- name: Upload Metadata
Expand Down
9 changes: 2 additions & 7 deletions CONTAINER_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,12 @@ their purposes:
* `tembo`: The directory that [Tembo Cloud] mounts as the persistent volume
for the database and extensions.
* `tembo/pgdata`: The data directory initialized by [Tembo Cloud].
* `tembo/lib`: A directory for shared library files required by extensions.
* `tembo/mod`: A directory for extension module library files.
* `tembo/share`: The directory for architecture-independent support files
used by Postgres. This is the directory used by `pg_config --sharedir` to
install non-binary extension files. Its files are copied from
`/tmp/pg_sharedir` when the Tembo operator initializes the volume.
* `tembo/${PG_MAJOR}/lib`: A directory for extension shared library files
compiled for a specific major version of Postgres.
* `tembo/${OS_NAME}/lib`: A directory for OS shared library files.
* `tembo/${OS_NAME}/etc`: The home of the library loading cache, updated
by `ldconfig` when new files are installed into
`tembo/${OS_NAME}/lib`. The canonical cache file, `/etc/ld.so.cache`,
is a symlink into this directory.


Other useful locations around the system:
Expand Down
14 changes: 6 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ ARG CNPG_VOLUME=${PG_HOME}/data
# System LLD dir.
ARG TEMBO_VOLUME=${PG_HOME}/tembo
ARG TEMBO_SHARE_DIR=${TEMBO_VOLUME}/share
ARG TEMBO_PG_LIB_DIR=${TEMBO_VOLUME}/${PG_MAJOR}/lib
ARG TEMBO_LD_LIB_DIR=${TEMBO_VOLUME}/${OS_NAME}/lib
ARG TEMBO_PG_LIB_DIR=${TEMBO_VOLUME}/mod
ARG TEMBO_LD_LIB_DIR=${TEMBO_VOLUME}/lib

# Set rpath to search the Postgres lib directory, then the Tembo Postgres lib
# directory, where Trunk-installed extension libraries will live, and the
Expand Down Expand Up @@ -126,7 +126,8 @@ RUN set -ex; \
useradd -r -g postgres --uid=26 --home-dir=${PG_HOME} --shell=/bin/bash postgres && \
chown -R postgres:postgres ${PG_HOME};

# Add the entrypoint script
# Add the README and entrypoint script.
COPY CONTAINER_README.md "${PG_HOME}/README.md"
COPY docker-entrypoint.sh /usr/local/bin/

##############################################################################
Expand Down Expand Up @@ -163,7 +164,6 @@ RUN apt-get update && apt-get upgrade -y && apt-get install --no-install-recomme
libxml2 \
libxslt1.1 \
libreadline8 \
libtcl8.6 \
xz-utils \
libgss3 \
libkrb5-3 \
Expand All @@ -182,17 +182,15 @@ RUN set -xe; \
# initialization without a temp copy: https://stackoverflow.com/a/72269316/79202)
cp -lr "$(pg_config --sharedir)" /tmp/pg_sharedir;

# Add the README.
# Add the README and entrypoint script.
COPY CONTAINER_README.md "${PG_HOME}/README.md"
COPY docker-entrypoint.sh /usr/local/bin/

# Create the Postgres user and set its uid to what CNPG expects.
RUN groupadd -r postgres --gid=999 && \
useradd -r -g postgres --uid=26 --home-dir=${PG_HOME} --shell=/bin/bash postgres && \
chown -R postgres:postgres ${PG_HOME};

# Add the entrypoint script
COPY docker-entrypoint.sh /usr/local/bin/

##############################################################################
# Build the postgres image as a single layer.
FROM scratch AS postgres
Expand Down
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Ubuntu Noble (24.04) and Jimmy (22.04) for the ARM64 and AMD64 processors.
inside the container:

```sh
docker run --name tembo-postgres -d localhost:5001/postgres:17
docker run --name tembo-postgres -d quay.io/tembo/postgres
docker exec -it tembo-postgres psql
```

Expand Down Expand Up @@ -97,7 +97,7 @@ To run the image locally with the Tembo Operator, you'll need:
5. Edit `yaml/sample-standard.yaml` and set `image` to the image name:

```yaml
image: localhost:5001/postgres:17
image: localhost:5001/postgres:latest
```

6. Load the image into the `kind` Kubernetes registry and create the cluster:
Expand Down Expand Up @@ -158,11 +158,12 @@ And an image built on the latest Postgres includes the tag:

* `/var/lib/postgresql/tembo`: The directory where [Tembo Cloud] mounts a
persistent volume and stores persistent data:
* Tembo initializes and runs the cluster from the `pgdata` subdirectory.
* Given a Postgres major version, e.g., `17`, the Tembo stores extension
shared libraries in `17/lib` and extension data files in `17/share`.
* Given an Ubuntu code name, such as `noble`, Tembo stores shared system
libraries required by extensions in `noble/lib`.
* `pgdata`: Tembo initializes and runs the cluster from this
subdirectory.
* `mod`: Tembo stores extension module libraries this subdirectory.
* `share`: Tembo stores and extension data files in this subdirectory.
* `lib`: Tembo stores shared libraries required by extensions in this
subdirectory.

* `/usr/lib/postgresql`: The home of the PostgreSQL binaries, libraries, and
header & locale files. Immutable in [CloudNativePG] and [Tembo Cloud].
Expand Down
4 changes: 2 additions & 2 deletions docker-bake.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ variable os_spec {
noble = {
image = "quay.io/tembo/ubuntu:24.04",
digest = "72297848456d5d37d1262630108ab308d3e9ec7ed1c3286a32fe09856619a782"
packages = "libicu74 libllvm19 libpython3.12 libperl5.38"
packages = "libicu74"
},
jammy = {
image = "quay.io/tembo/ubuntu:22.04",
digest = "ed1544e454989078f5dec1bfdabd8c5cc9c48e0705d07b678ab6ae3fb61952d2"
packages = "libicu70 libllvm15 libpython3.11 libperl5.34"
packages = "libicu70"
}
}
}
Expand Down
21 changes: 15 additions & 6 deletions docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,24 @@ main() {
chmod 700 "$PGDATA" || :

if [ ! -s "$PGDATA/PG_VERSION" ]; then
VERSION="$(pg_config --version)"
VERSION="${VERSION%.*}"
if [ "${VERSION#* }" -ge 17 ]; then
# Prefer C.UTF-8.
initdb -D "$PGDATA" -U postgres -c listen_addresses='*' --auth=trust --locale-provider builtin --builtin-locale C.UTF-8 --encoding UNICODE
opts=(
-D "$PGDATA"
-U postgres
-c listen_addresses='*'
-c dynamic_library_path="\$libdir:/var/lib/postgresql/tembo/mod"
--auth trust
--encoding UNICODE
)

if [ "$(pg_config --version | perl -ne '/(\d+)/ & print $1')" -ge 17 ]; then
# Prefer builtin C.UTF-8.
opts+=(--locale-provider builtin --builtin-locale C.UTF-8)
else
# Default to en_US.UTF-8.
initdb -D "$PGDATA" -U postgres -c listen_addresses='*' --auth=trust --locale en_US.UTF-8 --encoding UNICODE
opts+=(--locale en_US.UTF-8)
fi

initdb "${opts[@]}"
fi

# Start the server. Logs go to STDOUT.
Expand Down

0 comments on commit 1934219

Please sign in to comment.