Skip to content

Add ParadeDB image#21419

Open
isaacvando wants to merge 1 commit into
docker-library:masterfrom
paradedb:main
Open

Add ParadeDB image#21419
isaacvando wants to merge 1 commit 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

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.

@tianon

tianon commented Jun 5, 2026

Copy link
Copy Markdown
Member

Please, don't merge into this PR -- we'll review the PR when we can. If you wish to update it, please rebase on our branch, then force push (which should also remove all the errant merge commits). Generally, this change adds a brand new file, so there shouldn't be any conflicts and thus very little reason to update/rebase unless you have something about the PR itself you need to update (or there's some new test, etc we merged into our branch that you'd like the CI to test, but that's pretty rare too).

Beyond that, please, please be patient -- our new-image queue takes a lot more maintainer energy to review / process, so it tends to be a lower priority but you are in queue and we'll get to it eventually. ❤️

@github-actions

github-actions Bot commented Jun 6, 2026

Copy link
Copy Markdown
Diff for b8ce632:
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!"

@philippemnoel
philippemnoel deleted the main branch June 6, 2026 22:20
@philippemnoel

Copy link
Copy Markdown

Please, don't merge into this PR -- we'll review the PR when we can. If you wish to update it, please rebase on our branch, then force push (which should also remove all the errant merge commits). Generally, this change adds a brand new file, so there shouldn't be any conflicts and thus very little reason to update/rebase unless you have something about the PR itself you need to update (or there's some new test, etc we merged into our branch that you'd like the CI to test, but that's pretty rare too).

Beyond that, please, please be patient -- our new-image queue takes a lot more maintainer energy to review / process, so it tends to be a lower priority but you are in queue and we'll get to it eventually. ❤️

Hi! Thank you for the kind message, and really sorry about the noise. If you want, we can open a new PR that doesn't have all these commits. I went ahead and force-pushed as you suggested, and our main is now exactly one commit ahead of yours. We won't be touching it until you're ready to review it.

Thanks again for taking a look and we'll sit tight. Thank you 🙏

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.

4 participants