Skip to content

Add ParadeDB image#21419

Open
isaacvando wants to merge 9 commits into
docker-library:masterfrom
paradedb:main
Open

Add ParadeDB image#21419
isaacvando wants to merge 9 commits into
docker-library:masterfrom
paradedb:main

Conversation

@isaacvando
Copy link
Copy Markdown

Adds ParadeDB as an official image. Thank you for reviewing!

Docs PR: docker-library/docs#2671

@github-actions

This comment has been minimized.

@isaacvando isaacvando marked this pull request as ready for review May 8, 2026 22:34
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@isaacvando
Copy link
Copy Markdown
Author

Hi @tianon @yosifkit, could one of you take a look at this PR? Thanks for your help!

@github-actions
Copy link
Copy Markdown

Diff for 8cde1df:
diff --git a/_bashbrew-arches b/_bashbrew-arches
index 8b13789..e85a97f 100644
--- a/_bashbrew-arches
+++ b/_bashbrew-arches
@@ -1 +1,2 @@
-
+amd64
+arm64v8
diff --git a/_bashbrew-cat b/_bashbrew-cat
index bdfae4a..04e512d 100644
--- a/_bashbrew-cat
+++ b/_bashbrew-cat
@@ -1 +1,21 @@
-Maintainers: New Image! :D (@docker-library-bot)
+Maintainers: Isaac Van Doren <isaac@paradedb.com> (@isaacvando), Philippe Noël <phil@paradedb.com> (@philippemnoel), Ming Ying <ming@paradedb.com> (@rebasedming)
+Architectures: amd64, arm64v8
+GitRepo: https://github.com/paradedb/paradedb.git
+GitFetch: refs/heads/main
+GitCommit: d5b3c63b4d325e1aa4b75cee2c4770bf5c18d2ba
+
+Tags: 0.23.4-pg15, v0.23.4-pg15, 15-v0.23.4, pg15
+Directory: docker
+File: Dockerfile.official-15
+
+Tags: 0.23.4-pg16, v0.23.4-pg16, 16-v0.23.4, pg16
+Directory: docker
+File: Dockerfile.official-16
+
+Tags: 0.23.4-pg17, v0.23.4-pg17, 17-v0.23.4, pg17
+Directory: docker
+File: Dockerfile.official-17
+
+Tags: latest, 0.23.4, 0.23.4-pg18, v0.23.4, v0.23.4-pg18, 18-v0.23.4, pg18
+Directory: docker
+File: Dockerfile.official-18
diff --git a/_bashbrew-list b/_bashbrew-list
index e69de29..9faed7d 100644
--- a/_bashbrew-list
+++ b/_bashbrew-list
@@ -0,0 +1,19 @@
+paradedb:0.23.4
+paradedb:0.23.4-pg15
+paradedb:0.23.4-pg16
+paradedb:0.23.4-pg17
+paradedb:0.23.4-pg18
+paradedb:15-v0.23.4
+paradedb:16-v0.23.4
+paradedb:17-v0.23.4
+paradedb:18-v0.23.4
+paradedb:latest
+paradedb:pg15
+paradedb:pg16
+paradedb:pg17
+paradedb:pg18
+paradedb:v0.23.4
+paradedb:v0.23.4-pg15
+paradedb:v0.23.4-pg16
+paradedb:v0.23.4-pg17
+paradedb:v0.23.4-pg18
diff --git a/_bashbrew-list-build-order b/_bashbrew-list-build-order
index e69de29..12e5989 100644
--- a/_bashbrew-list-build-order
+++ b/_bashbrew-list-build-order
@@ -0,0 +1,4 @@
+paradedb:pg15
+paradedb:pg16
+paradedb:pg17
+paradedb:pg18
diff --git a/paradedb_pg15/Dockerfile.official-15 b/paradedb_pg15/Dockerfile.official-15
new file mode 100644
index 0000000..bfd844c
--- /dev/null
+++ b/paradedb_pg15/Dockerfile.official-15
@@ -0,0 +1,65 @@
+# Note: Debian Trixie = Debian 13
+FROM postgres:15-trixie AS paradedb
+
+LABEL maintainer="ParadeDB - https://paradedb.com" \
+    org.opencontainers.image.description="Simple, Elastic-quality search for Postgres" \
+    org.opencontainers.image.source="https://github.com/paradedb/paradedb"
+
+SHELL ["/bin/bash", "-o", "pipefail", "-c", "-e"]
+
+# Install pg_search from GitHub Releases
+RUN apt-get update && \
+    apt-get install -y --no-install-recommends ca-certificates curl && \
+    arch="$(dpkg --print-architecture)" && \
+    case "$arch" in \
+        amd64) checksum="a51be4f76a21e6387e5558f98695eca6a84ab8ae6e4b87bf2fdc9adeb8f3a36e" ;; \
+        arm64) checksum="5988d83174bbbb301da82df2045d774661cedd2f3ae0966615bbf49708a5938f" ;; \
+        *) echo "unsupported architecture: $arch" >&2; exit 1 ;; \
+    esac && \
+    curl -fsSL -o /tmp/pg_search.deb "https://github.com/paradedb/paradedb/releases/download/v0.23.4/postgresql-15-pg-search_0.23.4-1PARADEDB-trixie_${arch}.deb" && \
+    echo "${checksum}  /tmp/pg_search.deb" | sha256sum -c - && \
+    apt-get install -y --no-install-recommends /tmp/pg_search.deb && \
+    rm /tmp/pg_search.deb && \
+    rm -rf /var/lib/apt/lists/*
+
+# Install core extensions
+# Use the PGDG archive so these pinned extension versions remain available after newer
+# versions replace them in the live Debian and PGDG apt repositories.
+ENV POSTGIS_VERSION_MAJOR=3
+RUN apt-get update \
+    && apt-get install -y --no-install-recommends ca-certificates \
+    && echo "deb [ signed-by=/usr/local/share/keyrings/postgres.gpg.asc ] https://apt-archive.postgresql.org/pub/repos/apt trixie-pgdg-archive main" > /etc/apt/sources.list.d/pgdg-archive.list \
+    && apt-get update \
+    && apt-get install -y --no-install-recommends \
+    postgresql-15-pgvector=0.8.1-2.pgdg13+1 \
+    postgresql-15-cron=1.6.7-2.pgdg13+1 \
+    postgresql-15-pg-ivm=1.13-1.pgdg13+1 \
+    postgresql-15-postgis-$POSTGIS_VERSION_MAJOR \
+    postgresql-15-postgis-$POSTGIS_VERSION_MAJOR-scripts \
+    && rm /etc/apt/sources.list.d/pgdg-archive.list \
+    && rm -rf /var/lib/apt/lists/* && \
+    update-ca-certificates
+
+# The postgresql.conf.sample file is used as a template for the postgresql.conf file, which
+# does not exist until the first time the container is started. By adding our settings to the
+# postgresql.conf.sample file, we ensure that our settings are applied onto the postgresql.conf file.
+#
+# The `postgres` database is the default database that exists in every Postgres installation. The pg_cron
+# extension requires a database to store its metadata tables. By using `postgres`, we ensure that it has a
+# stable, always-available database for its operations, no matter what other databases are created or deleted.
+RUN sed -i "s/^#shared_preload_libraries = ''/shared_preload_libraries = 'pg_search,pg_cron,pg_stat_statements'/" /usr/share/postgresql/postgresql.conf.sample && \
+    grep "shared_preload_libraries = 'pg_search,pg_cron,pg_stat_statements'" /usr/share/postgresql/postgresql.conf.sample && \
+    echo "cron.database_name = 'postgres'" >> /usr/share/postgresql/postgresql.conf.sample && \
+    echo "pg_stat_statements.track = 'top'" >> /usr/share/postgresql/postgresql.conf.sample
+
+# Reset the working directory to the root directory
+WORKDIR /
+
+# Copy ParadeDB bootstrap script to install extensions and configure postgresql.conf
+COPY ./bootstrap.sh /docker-entrypoint-initdb.d/10_bootstrap_paradedb.sh
+
+# The upstream `postgres` Docker image comes with its own `entrypoint.sh` script which
+# starts as `root` and then switches to the `postgres` user after running chown and chmod
+# on the PostgreSQL data directory. To maintain compatibility with the upstream image and
+# ensure that the `postgres` user has the correct permissions on the data directory, we let
+# the upstream `entrypoint.sh` script run as the entrypoint and don't specify a custom user.
diff --git a/paradedb_pg15/bootstrap.sh b/paradedb_pg15/bootstrap.sh
new file mode 100755
index 0000000..8711dbd
--- /dev/null
+++ b/paradedb_pg15/bootstrap.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# shellcheck disable=SC2154
+
+# Executed at container start to bootstrap ParadeDB extensions and Postgres settings.
+
+# Exit on subcommand errors
+set -Eeuo pipefail
+
+# Perform all actions as $POSTGRES_USER
+export PGUSER="$POSTGRES_USER"
+
+# The `pg_cron` extension can only be installed in the `postgres` database, as per
+# our configuration in our Dockerfile. Therefore, we install it separately here.
+psql -d postgres -c "CREATE EXTENSION IF NOT EXISTS pg_cron;"
+
+# Always create a `paradedb` database, regardless of what $POSTGRES_DB is set to
+if [ "$POSTGRES_DB" != "paradedb" ]; then
+  echo "Creating default 'paradedb' database"
+  psql -d postgres -c "CREATE DATABASE paradedb;"
+fi
+
+# Load ParadeDB and third-party extensions into template1, paradedb, and $POSTGRES_DB
+# Creating extensions in template1 ensures that they are available in all new databases.
+for DB in template1 paradedb "$POSTGRES_DB"; do
+  echo "Loading ParadeDB extensions into $DB"
+  psql -d "$DB" <<-'EOSQL'
+    CREATE EXTENSION IF NOT EXISTS pg_search;
+    CREATE EXTENSION IF NOT EXISTS pg_ivm;
+    CREATE EXTENSION IF NOT EXISTS vector;
+    CREATE EXTENSION IF NOT EXISTS postgis;
+    CREATE EXTENSION IF NOT EXISTS postgis_topology;
+    CREATE EXTENSION IF NOT EXISTS fuzzystrmatch;
+    CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder;
+    CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
+EOSQL
+done
+
+# Add the `paradedb` schema to template1, paradedb, and $POSTGRES_DB
+for DB in template1 paradedb "$POSTGRES_DB"; do
+  echo "Adding 'paradedb' search_path to $DB"
+  psql -d "$DB" -c "ALTER DATABASE \"$DB\" SET search_path TO public,paradedb;"
+done
+
+echo "ParadeDB bootstrap completed!"
diff --git a/paradedb_pg16/Dockerfile.official-16 b/paradedb_pg16/Dockerfile.official-16
new file mode 100644
index 0000000..6942307
--- /dev/null
+++ b/paradedb_pg16/Dockerfile.official-16
@@ -0,0 +1,65 @@
+# Note: Debian Trixie = Debian 13
+FROM postgres:16-trixie AS paradedb
+
+LABEL maintainer="ParadeDB - https://paradedb.com" \
+    org.opencontainers.image.description="Simple, Elastic-quality search for Postgres" \
+    org.opencontainers.image.source="https://github.com/paradedb/paradedb"
+
+SHELL ["/bin/bash", "-o", "pipefail", "-c", "-e"]
+
+# Install pg_search from GitHub Releases
+RUN apt-get update && \
+    apt-get install -y --no-install-recommends ca-certificates curl && \
+    arch="$(dpkg --print-architecture)" && \
+    case "$arch" in \
+        amd64) checksum="fef3abb8b571dbaf125c472bb89639e36c27da165647dd6608b7cb09ff264b1b" ;; \
+        arm64) checksum="b96bd6e5e3ac32c4128b5091e9088cfcffa6468303288466f60ab25270c7803a" ;; \
+        *) echo "unsupported architecture: $arch" >&2; exit 1 ;; \
+    esac && \
+    curl -fsSL -o /tmp/pg_search.deb "https://github.com/paradedb/paradedb/releases/download/v0.23.4/postgresql-16-pg-search_0.23.4-1PARADEDB-trixie_${arch}.deb" && \
+    echo "${checksum}  /tmp/pg_search.deb" | sha256sum -c - && \
+    apt-get install -y --no-install-recommends /tmp/pg_search.deb && \
+    rm /tmp/pg_search.deb && \
+    rm -rf /var/lib/apt/lists/*
+
+# Install core extensions
+# Use the PGDG archive so these pinned extension versions remain available after newer
+# versions replace them in the live Debian and PGDG apt repositories.
+ENV POSTGIS_VERSION_MAJOR=3
+RUN apt-get update \
+    && apt-get install -y --no-install-recommends ca-certificates \
+    && echo "deb [ signed-by=/usr/local/share/keyrings/postgres.gpg.asc ] https://apt-archive.postgresql.org/pub/repos/apt trixie-pgdg-archive main" > /etc/apt/sources.list.d/pgdg-archive.list \
+    && apt-get update \
+    && apt-get install -y --no-install-recommends \
+    postgresql-16-pgvector=0.8.1-2.pgdg13+1 \
+    postgresql-16-cron=1.6.7-2.pgdg13+1 \
+    postgresql-16-pg-ivm=1.13-1.pgdg13+1 \
+    postgresql-16-postgis-$POSTGIS_VERSION_MAJOR \
+    postgresql-16-postgis-$POSTGIS_VERSION_MAJOR-scripts \
+    && rm /etc/apt/sources.list.d/pgdg-archive.list \
+    && rm -rf /var/lib/apt/lists/* && \
+    update-ca-certificates
+
+# The postgresql.conf.sample file is used as a template for the postgresql.conf file, which
+# does not exist until the first time the container is started. By adding our settings to the
+# postgresql.conf.sample file, we ensure that our settings are applied onto the postgresql.conf file.
+#
+# The `postgres` database is the default database that exists in every Postgres installation. The pg_cron
+# extension requires a database to store its metadata tables. By using `postgres`, we ensure that it has a
+# stable, always-available database for its operations, no matter what other databases are created or deleted.
+RUN sed -i "s/^#shared_preload_libraries = ''/shared_preload_libraries = 'pg_search,pg_cron,pg_stat_statements'/" /usr/share/postgresql/postgresql.conf.sample && \
+    grep "shared_preload_libraries = 'pg_search,pg_cron,pg_stat_statements'" /usr/share/postgresql/postgresql.conf.sample && \
+    echo "cron.database_name = 'postgres'" >> /usr/share/postgresql/postgresql.conf.sample && \
+    echo "pg_stat_statements.track = 'top'" >> /usr/share/postgresql/postgresql.conf.sample
+
+# Reset the working directory to the root directory
+WORKDIR /
+
+# Copy ParadeDB bootstrap script to install extensions and configure postgresql.conf
+COPY ./bootstrap.sh /docker-entrypoint-initdb.d/10_bootstrap_paradedb.sh
+
+# The upstream `postgres` Docker image comes with its own `entrypoint.sh` script which
+# starts as `root` and then switches to the `postgres` user after running chown and chmod
+# on the PostgreSQL data directory. To maintain compatibility with the upstream image and
+# ensure that the `postgres` user has the correct permissions on the data directory, we let
+# the upstream `entrypoint.sh` script run as the entrypoint and don't specify a custom user.
diff --git a/paradedb_pg16/bootstrap.sh b/paradedb_pg16/bootstrap.sh
new file mode 100755
index 0000000..8711dbd
--- /dev/null
+++ b/paradedb_pg16/bootstrap.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# shellcheck disable=SC2154
+
+# Executed at container start to bootstrap ParadeDB extensions and Postgres settings.
+
+# Exit on subcommand errors
+set -Eeuo pipefail
+
+# Perform all actions as $POSTGRES_USER
+export PGUSER="$POSTGRES_USER"
+
+# The `pg_cron` extension can only be installed in the `postgres` database, as per
+# our configuration in our Dockerfile. Therefore, we install it separately here.
+psql -d postgres -c "CREATE EXTENSION IF NOT EXISTS pg_cron;"
+
+# Always create a `paradedb` database, regardless of what $POSTGRES_DB is set to
+if [ "$POSTGRES_DB" != "paradedb" ]; then
+  echo "Creating default 'paradedb' database"
+  psql -d postgres -c "CREATE DATABASE paradedb;"
+fi
+
+# Load ParadeDB and third-party extensions into template1, paradedb, and $POSTGRES_DB
+# Creating extensions in template1 ensures that they are available in all new databases.
+for DB in template1 paradedb "$POSTGRES_DB"; do
+  echo "Loading ParadeDB extensions into $DB"
+  psql -d "$DB" <<-'EOSQL'
+    CREATE EXTENSION IF NOT EXISTS pg_search;
+    CREATE EXTENSION IF NOT EXISTS pg_ivm;
+    CREATE EXTENSION IF NOT EXISTS vector;
+    CREATE EXTENSION IF NOT EXISTS postgis;
+    CREATE EXTENSION IF NOT EXISTS postgis_topology;
+    CREATE EXTENSION IF NOT EXISTS fuzzystrmatch;
+    CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder;
+    CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
+EOSQL
+done
+
+# Add the `paradedb` schema to template1, paradedb, and $POSTGRES_DB
+for DB in template1 paradedb "$POSTGRES_DB"; do
+  echo "Adding 'paradedb' search_path to $DB"
+  psql -d "$DB" -c "ALTER DATABASE \"$DB\" SET search_path TO public,paradedb;"
+done
+
+echo "ParadeDB bootstrap completed!"
diff --git a/paradedb_pg17/Dockerfile.official-17 b/paradedb_pg17/Dockerfile.official-17
new file mode 100644
index 0000000..69b1296
--- /dev/null
+++ b/paradedb_pg17/Dockerfile.official-17
@@ -0,0 +1,65 @@
+# Note: Debian Trixie = Debian 13
+FROM postgres:17-trixie AS paradedb
+
+LABEL maintainer="ParadeDB - https://paradedb.com" \
+    org.opencontainers.image.description="Simple, Elastic-quality search for Postgres" \
+    org.opencontainers.image.source="https://github.com/paradedb/paradedb"
+
+SHELL ["/bin/bash", "-o", "pipefail", "-c", "-e"]
+
+# Install pg_search from GitHub Releases
+RUN apt-get update && \
+    apt-get install -y --no-install-recommends ca-certificates curl && \
+    arch="$(dpkg --print-architecture)" && \
+    case "$arch" in \
+        amd64) checksum="fd4ec8fec076910f60824176adddd57d192877a9ed271c1994202fdf4edb77cf" ;; \
+        arm64) checksum="0716d85321905a75ef5e088a6350161b32304901e14b31827ab0b6dd06306d2e" ;; \
+        *) echo "unsupported architecture: $arch" >&2; exit 1 ;; \
+    esac && \
+    curl -fsSL -o /tmp/pg_search.deb "https://github.com/paradedb/paradedb/releases/download/v0.23.4/postgresql-17-pg-search_0.23.4-1PARADEDB-trixie_${arch}.deb" && \
+    echo "${checksum}  /tmp/pg_search.deb" | sha256sum -c - && \
+    apt-get install -y --no-install-recommends /tmp/pg_search.deb && \
+    rm /tmp/pg_search.deb && \
+    rm -rf /var/lib/apt/lists/*
+
+# Install core extensions
+# Use the PGDG archive so these pinned extension versions remain available after newer
+# versions replace them in the live Debian and PGDG apt repositories.
+ENV POSTGIS_VERSION_MAJOR=3
+RUN apt-get update \
+    && apt-get install -y --no-install-recommends ca-certificates \
+    && echo "deb [ signed-by=/usr/local/share/keyrings/postgres.gpg.asc ] https://apt-archive.postgresql.org/pub/repos/apt trixie-pgdg-archive main" > /etc/apt/sources.list.d/pgdg-archive.list \
+    && apt-get update \
+    && apt-get install -y --no-install-recommends \
+    postgresql-17-pgvector=0.8.1-2.pgdg13+1 \
+    postgresql-17-cron=1.6.7-2.pgdg13+1 \
+    postgresql-17-pg-ivm=1.13-1.pgdg13+1 \
+    postgresql-17-postgis-$POSTGIS_VERSION_MAJOR \
+    postgresql-17-postgis-$POSTGIS_VERSION_MAJOR-scripts \
+    && rm /etc/apt/sources.list.d/pgdg-archive.list \
+    && rm -rf /var/lib/apt/lists/* && \
+    update-ca-certificates
+
+# The postgresql.conf.sample file is used as a template for the postgresql.conf file, which
+# does not exist until the first time the container is started. By adding our settings to the
+# postgresql.conf.sample file, we ensure that our settings are applied onto the postgresql.conf file.
+#
+# The `postgres` database is the default database that exists in every Postgres installation. The pg_cron
+# extension requires a database to store its metadata tables. By using `postgres`, we ensure that it has a
+# stable, always-available database for its operations, no matter what other databases are created or deleted.
+RUN sed -i "s/^#shared_preload_libraries = ''/shared_preload_libraries = 'pg_search,pg_cron,pg_stat_statements'/" /usr/share/postgresql/postgresql.conf.sample && \
+    grep "shared_preload_libraries = 'pg_search,pg_cron,pg_stat_statements'" /usr/share/postgresql/postgresql.conf.sample && \
+    echo "cron.database_name = 'postgres'" >> /usr/share/postgresql/postgresql.conf.sample && \
+    echo "pg_stat_statements.track = 'top'" >> /usr/share/postgresql/postgresql.conf.sample
+
+# Reset the working directory to the root directory
+WORKDIR /
+
+# Copy ParadeDB bootstrap script to install extensions and configure postgresql.conf
+COPY ./bootstrap.sh /docker-entrypoint-initdb.d/10_bootstrap_paradedb.sh
+
+# The upstream `postgres` Docker image comes with its own `entrypoint.sh` script which
+# starts as `root` and then switches to the `postgres` user after running chown and chmod
+# on the PostgreSQL data directory. To maintain compatibility with the upstream image and
+# ensure that the `postgres` user has the correct permissions on the data directory, we let
+# the upstream `entrypoint.sh` script run as the entrypoint and don't specify a custom user.
diff --git a/paradedb_pg17/bootstrap.sh b/paradedb_pg17/bootstrap.sh
new file mode 100755
index 0000000..8711dbd
--- /dev/null
+++ b/paradedb_pg17/bootstrap.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# shellcheck disable=SC2154
+
+# Executed at container start to bootstrap ParadeDB extensions and Postgres settings.
+
+# Exit on subcommand errors
+set -Eeuo pipefail
+
+# Perform all actions as $POSTGRES_USER
+export PGUSER="$POSTGRES_USER"
+
+# The `pg_cron` extension can only be installed in the `postgres` database, as per
+# our configuration in our Dockerfile. Therefore, we install it separately here.
+psql -d postgres -c "CREATE EXTENSION IF NOT EXISTS pg_cron;"
+
+# Always create a `paradedb` database, regardless of what $POSTGRES_DB is set to
+if [ "$POSTGRES_DB" != "paradedb" ]; then
+  echo "Creating default 'paradedb' database"
+  psql -d postgres -c "CREATE DATABASE paradedb;"
+fi
+
+# Load ParadeDB and third-party extensions into template1, paradedb, and $POSTGRES_DB
+# Creating extensions in template1 ensures that they are available in all new databases.
+for DB in template1 paradedb "$POSTGRES_DB"; do
+  echo "Loading ParadeDB extensions into $DB"
+  psql -d "$DB" <<-'EOSQL'
+    CREATE EXTENSION IF NOT EXISTS pg_search;
+    CREATE EXTENSION IF NOT EXISTS pg_ivm;
+    CREATE EXTENSION IF NOT EXISTS vector;
+    CREATE EXTENSION IF NOT EXISTS postgis;
+    CREATE EXTENSION IF NOT EXISTS postgis_topology;
+    CREATE EXTENSION IF NOT EXISTS fuzzystrmatch;
+    CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder;
+    CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
+EOSQL
+done
+
+# Add the `paradedb` schema to template1, paradedb, and $POSTGRES_DB
+for DB in template1 paradedb "$POSTGRES_DB"; do
+  echo "Adding 'paradedb' search_path to $DB"
+  psql -d "$DB" -c "ALTER DATABASE \"$DB\" SET search_path TO public,paradedb;"
+done
+
+echo "ParadeDB bootstrap completed!"
diff --git a/paradedb_pg18/Dockerfile.official-18 b/paradedb_pg18/Dockerfile.official-18
new file mode 100644
index 0000000..863f3a7
--- /dev/null
+++ b/paradedb_pg18/Dockerfile.official-18
@@ -0,0 +1,65 @@
+# Note: Debian Trixie = Debian 13
+FROM postgres:18-trixie AS paradedb
+
+LABEL maintainer="ParadeDB - https://paradedb.com" \
+    org.opencontainers.image.description="Simple, Elastic-quality search for Postgres" \
+    org.opencontainers.image.source="https://github.com/paradedb/paradedb"
+
+SHELL ["/bin/bash", "-o", "pipefail", "-c", "-e"]
+
+# Install pg_search from GitHub Releases
+RUN apt-get update && \
+    apt-get install -y --no-install-recommends ca-certificates curl && \
+    arch="$(dpkg --print-architecture)" && \
+    case "$arch" in \
+        amd64) checksum="6b042d61d156ca5fdcb1c417e291d90bffe3026848890be30bf6e578146b4676" ;; \
+        arm64) checksum="5ad13a80b76c46590914e0c366bd8deaf807d5b352f5ad489876ec836d06d3d1" ;; \
+        *) echo "unsupported architecture: $arch" >&2; exit 1 ;; \
+    esac && \
+    curl -fsSL -o /tmp/pg_search.deb "https://github.com/paradedb/paradedb/releases/download/v0.23.4/postgresql-18-pg-search_0.23.4-1PARADEDB-trixie_${arch}.deb" && \
+    echo "${checksum}  /tmp/pg_search.deb" | sha256sum -c - && \
+    apt-get install -y --no-install-recommends /tmp/pg_search.deb && \
+    rm /tmp/pg_search.deb && \
+    rm -rf /var/lib/apt/lists/*
+
+# Install core extensions
+# Use the PGDG archive so these pinned extension versions remain available after newer
+# versions replace them in the live Debian and PGDG apt repositories.
+ENV POSTGIS_VERSION_MAJOR=3
+RUN apt-get update \
+    && apt-get install -y --no-install-recommends ca-certificates \
+    && echo "deb [ signed-by=/usr/local/share/keyrings/postgres.gpg.asc ] https://apt-archive.postgresql.org/pub/repos/apt trixie-pgdg-archive main" > /etc/apt/sources.list.d/pgdg-archive.list \
+    && apt-get update \
+    && apt-get install -y --no-install-recommends \
+    postgresql-18-pgvector=0.8.1-2.pgdg13+1 \
+    postgresql-18-cron=1.6.7-2.pgdg13+1 \
+    postgresql-18-pg-ivm=1.13-1.pgdg13+1 \
+    postgresql-18-postgis-$POSTGIS_VERSION_MAJOR \
+    postgresql-18-postgis-$POSTGIS_VERSION_MAJOR-scripts \
+    && rm /etc/apt/sources.list.d/pgdg-archive.list \
+    && rm -rf /var/lib/apt/lists/* && \
+    update-ca-certificates
+
+# The postgresql.conf.sample file is used as a template for the postgresql.conf file, which
+# does not exist until the first time the container is started. By adding our settings to the
+# postgresql.conf.sample file, we ensure that our settings are applied onto the postgresql.conf file.
+#
+# The `postgres` database is the default database that exists in every Postgres installation. The pg_cron
+# extension requires a database to store its metadata tables. By using `postgres`, we ensure that it has a
+# stable, always-available database for its operations, no matter what other databases are created or deleted.
+RUN sed -i "s/^#shared_preload_libraries = ''/shared_preload_libraries = 'pg_search,pg_cron,pg_stat_statements'/" /usr/share/postgresql/postgresql.conf.sample && \
+    grep "shared_preload_libraries = 'pg_search,pg_cron,pg_stat_statements'" /usr/share/postgresql/postgresql.conf.sample && \
+    echo "cron.database_name = 'postgres'" >> /usr/share/postgresql/postgresql.conf.sample && \
+    echo "pg_stat_statements.track = 'top'" >> /usr/share/postgresql/postgresql.conf.sample
+
+# Reset the working directory to the root directory
+WORKDIR /
+
+# Copy ParadeDB bootstrap script to install extensions and configure postgresql.conf
+COPY ./bootstrap.sh /docker-entrypoint-initdb.d/10_bootstrap_paradedb.sh
+
+# The upstream `postgres` Docker image comes with its own `entrypoint.sh` script which
+# starts as `root` and then switches to the `postgres` user after running chown and chmod
+# on the PostgreSQL data directory. To maintain compatibility with the upstream image and
+# ensure that the `postgres` user has the correct permissions on the data directory, we let
+# the upstream `entrypoint.sh` script run as the entrypoint and don't specify a custom user.
diff --git a/paradedb_pg18/bootstrap.sh b/paradedb_pg18/bootstrap.sh
new file mode 100755
index 0000000..8711dbd
--- /dev/null
+++ b/paradedb_pg18/bootstrap.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# shellcheck disable=SC2154
+
+# Executed at container start to bootstrap ParadeDB extensions and Postgres settings.
+
+# Exit on subcommand errors
+set -Eeuo pipefail
+
+# Perform all actions as $POSTGRES_USER
+export PGUSER="$POSTGRES_USER"
+
+# The `pg_cron` extension can only be installed in the `postgres` database, as per
+# our configuration in our Dockerfile. Therefore, we install it separately here.
+psql -d postgres -c "CREATE EXTENSION IF NOT EXISTS pg_cron;"
+
+# Always create a `paradedb` database, regardless of what $POSTGRES_DB is set to
+if [ "$POSTGRES_DB" != "paradedb" ]; then
+  echo "Creating default 'paradedb' database"
+  psql -d postgres -c "CREATE DATABASE paradedb;"
+fi
+
+# Load ParadeDB and third-party extensions into template1, paradedb, and $POSTGRES_DB
+# Creating extensions in template1 ensures that they are available in all new databases.
+for DB in template1 paradedb "$POSTGRES_DB"; do
+  echo "Loading ParadeDB extensions into $DB"
+  psql -d "$DB" <<-'EOSQL'
+    CREATE EXTENSION IF NOT EXISTS pg_search;
+    CREATE EXTENSION IF NOT EXISTS pg_ivm;
+    CREATE EXTENSION IF NOT EXISTS vector;
+    CREATE EXTENSION IF NOT EXISTS postgis;
+    CREATE EXTENSION IF NOT EXISTS postgis_topology;
+    CREATE EXTENSION IF NOT EXISTS fuzzystrmatch;
+    CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder;
+    CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
+EOSQL
+done
+
+# Add the `paradedb` schema to template1, paradedb, and $POSTGRES_DB
+for DB in template1 paradedb "$POSTGRES_DB"; do
+  echo "Adding 'paradedb' search_path to $DB"
+  psql -d "$DB" -c "ALTER DATABASE \"$DB\" SET search_path TO public,paradedb;"
+done
+
+echo "ParadeDB bootstrap completed!"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants