Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
59e3e29
add 18 to nix config
encima Feb 7, 2026
1a49b8a
add references to 18 in pkgs
encima Feb 7, 2026
3cc699e
add 18 to extension versions
encima Feb 7, 2026
78af79e
fix issue with extensions failing if not supported by any major versions
encima Feb 7, 2026
09801a9
bump pg_cron to 1.6.7, http to 1.6.3 and supautils to 3.1.0, as well …
encima Feb 8, 2026
5fc81ac
updated pg_stat_monitor to 2.3.1 for 18
encima Feb 8, 2026
f3acc6a
update pg_graphql to 1.5.12 for 18 support
encima Feb 8, 2026
c72b23d
update pgtap to 1.3.4
encima Feb 8, 2026
6008306
update plpgsql_check to 2.8.8 for 18
encima Feb 8, 2026
6c4c222
update rum to 1.3.15
encima Feb 8, 2026
b4710ea
update pgroonga to 4.0.5 for 18
encima Feb 8, 2026
1fc8d22
update vector to 0.8.1 for 18
encima Feb 8, 2026
7e8d974
update roonga to 14.0.5 for latest pgroonga
encima Feb 8, 2026
ab80d7f
amend patches for groonga due to line number changes
encima Feb 8, 2026
8718d3a
update pg_graphql rust deps for pgrx to support 18
encima Feb 8, 2026
d474d51
update rust deps for jsonschema and other pgrx based builds
encima Feb 8, 2026
8fea4dc
update jsonschema to 0.3.4
encima Feb 8, 2026
366b68d
update postgis to 3.6.1
encima Feb 8, 2026
45b045b
fix: extension version issues on arm linux and rebase against develop
encima Mar 2, 2026
f14f1b2
add conf exceptions for 18 and bump to 18.3
encima Mar 6, 2026
7233077
add alternative tests for 18 (not versioned but additionally checked …
encima Mar 6, 2026
50fef18
update major PG instructions and ansible file for handling pg18 config
encima Mar 9, 2026
14e8969
update dbmate to use the local flake for checking version to gen for
encima Mar 19, 2026
f4663ae
revert version checks now that all have an 18 equivalent
encima Mar 19, 2026
14d8dd1
update Dockerfile to match new format and add slim build support
encima Mar 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 190 additions & 0 deletions Dockerfile-18
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# syntax=docker/dockerfile:1.6
# Alpine-based slim PostgreSQL 18 image with Nix extensions

####################
# Stage 1: Nix builder
####################
FROM alpine:3.21 AS nix-builder

# Install dependencies for nix installer (coreutils for GNU cp, sudo for installer)
RUN apk add --no-cache \
bash \
coreutils \
curl \
shadow \
sudo \
xz

# Create users (Alpine syntax)
RUN addgroup -S postgres && \
adduser -S -h /var/lib/postgresql -s /bin/bash -G postgres postgres && \
addgroup -S wal-g && \
adduser -S -s /bin/bash -G wal-g wal-g

# Create nix config
RUN cat <<EOF > /tmp/extra-nix.conf
extra-experimental-features = nix-command flakes
extra-substituters = https://nix-postgres-artifacts.s3.amazonaws.com
extra-trusted-public-keys = nix-postgres-artifacts:dGZlQOvKcNEjvT7QEAJbcV6b6uk7VF/hWMjhYleiaLI=
EOF
RUN curl -L https://releases.nixos.org/nix/nix-2.33.2/install | sh -s -- --daemon --no-channel-add --yes --nix-extra-conf-file /tmp/extra-nix.conf

ENV PATH="${PATH}:/nix/var/nix/profiles/default/bin"

WORKDIR /nixpg
COPY . .

# Build PostgreSQL with extensions
RUN nix profile add path:.#psql_18_slim/bin

RUN nix store gc

# Build groonga and copy plugins
RUN nix profile add path:.#supabase-groonga && \
mkdir -p /tmp/groonga-plugins && \
cp -r /nix/var/nix/profiles/default/lib/groonga/plugins /tmp/groonga-plugins/

RUN nix store gc

####################
# Stage 2: Gosu builder
####################
FROM alpine:3.21 AS gosu-builder

ARG TARGETARCH
ARG GOSU_VERSION=1.16

RUN apk add --no-cache gnupg curl

# Download and verify gosu
RUN curl -fsSL "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-${TARGETARCH}" -o /usr/local/bin/gosu && \
curl -fsSL "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-${TARGETARCH}.asc" -o /usr/local/bin/gosu.asc && \
GNUPGHOME="$(mktemp -d)" && \
export GNUPGHOME && \
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 && \
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu && \
rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc && \
chmod +x /usr/local/bin/gosu

####################
# Stage 3: Final production image
####################
FROM alpine:3.21 AS production

# Install minimal runtime dependencies
RUN apk add --no-cache \
bash \
curl \
shadow \
su-exec \
tzdata \
musl-locales \
musl-locales-lang \
&& rm -rf /var/cache/apk/*

# Create postgres user/group
RUN addgroup -S postgres && \
adduser -S -G postgres -h /var/lib/postgresql -s /bin/bash postgres && \
addgroup -S wal-g && \
adduser -S -G wal-g -s /bin/bash wal-g && \
adduser postgres wal-g

# Copy Nix store and profiles from builder (profile already created by nix profile install)
COPY --from=nix-builder /nix /nix

# Copy groonga plugins
COPY --from=nix-builder /tmp/groonga-plugins/plugins /usr/lib/groonga/plugins

# Copy gosu
COPY --from=gosu-builder /usr/local/bin/gosu /usr/local/bin/gosu

# Setup PostgreSQL directories
RUN mkdir -p /usr/lib/postgresql/bin \
/usr/lib/postgresql/share/postgresql \
/usr/share/postgresql \
/var/lib/postgresql/data \
/var/run/postgresql \
&& chown -R postgres:postgres /usr/lib/postgresql \
&& chown -R postgres:postgres /var/lib/postgresql \
&& chown -R postgres:postgres /usr/share/postgresql \
&& chown -R postgres:postgres /var/run/postgresql

# Create symbolic links for binaries
RUN for f in /nix/var/nix/profiles/default/bin/*; do \
ln -sf "$f" /usr/lib/postgresql/bin/ 2>/dev/null || true; \
ln -sf "$f" /usr/bin/ 2>/dev/null || true; \
done

# Create symbolic links for PostgreSQL shares
RUN ln -sf /nix/var/nix/profiles/default/share/postgresql/* /usr/lib/postgresql/share/postgresql/ 2>/dev/null || true && \
ln -sf /nix/var/nix/profiles/default/share/postgresql/* /usr/share/postgresql/ 2>/dev/null || true && \
ln -sf /usr/lib/postgresql/share/postgresql/timezonesets /usr/share/postgresql/timezonesets 2>/dev/null || true

# Set permissions
RUN chown -R postgres:postgres /usr/lib/postgresql && \
chown -R postgres:postgres /usr/share/postgresql

# Setup configs
COPY --chown=postgres:postgres ansible/files/postgresql_config/postgresql.conf.j2 /etc/postgresql/postgresql.conf
COPY --chown=postgres:postgres ansible/files/postgresql_config/pg_hba.conf.j2 /etc/postgresql/pg_hba.conf
COPY --chown=postgres:postgres ansible/files/postgresql_config/pg_ident.conf.j2 /etc/postgresql/pg_ident.conf
COPY --chown=postgres:postgres ansible/files/postgresql_config/conf.d /etc/postgresql-custom/conf.d
COPY --chown=postgres:postgres ansible/files/postgresql_config/postgresql-stdout-log.conf /etc/postgresql/logging.conf
COPY --chown=postgres:postgres ansible/files/postgresql_config/supautils.conf.j2 /etc/postgresql-custom/supautils.conf
COPY --chown=postgres:postgres ansible/files/postgresql_extension_custom_scripts /etc/postgresql-custom/extension-custom-scripts
COPY --chown=postgres:postgres ansible/files/pgsodium_getkey_urandom.sh.j2 /usr/lib/postgresql/bin/pgsodium_getkey.sh
COPY --chown=postgres:postgres ansible/files/postgresql_config/custom_walg.conf /etc/postgresql-custom/wal-g.conf
COPY --chown=postgres:postgres ansible/files/postgresql_config/custom_read_replica.conf /etc/postgresql-custom/read-replica.conf
COPY --chown=postgres:postgres ansible/files/walg_helper_scripts/wal_fetch.sh /home/postgres/wal_fetch.sh
COPY ansible/files/walg_helper_scripts/wal_change_ownership.sh /root/wal_change_ownership.sh

# Configure PostgreSQL settings
RUN sed -i \
-e "s|#unix_socket_directories = '/tmp'|unix_socket_directories = '/var/run/postgresql'|g" \
-e "s|#session_preload_libraries = ''|session_preload_libraries = 'supautils'|g" \
-e "s|#include = '/etc/postgresql-custom/supautils.conf'|include = '/etc/postgresql-custom/supautils.conf'|g" \
-e "s|#include = '/etc/postgresql-custom/wal-g.conf'|include = '/etc/postgresql-custom/wal-g.conf'|g" /etc/postgresql/postgresql.conf && \
echo "pgsodium.getkey_script= '/usr/lib/postgresql/bin/pgsodium_getkey.sh'" >> /etc/postgresql/postgresql.conf && \
echo "vault.getkey_script= '/usr/lib/postgresql/bin/pgsodium_getkey.sh'" >> /etc/postgresql/postgresql.conf && \
chown -R postgres:postgres /etc/postgresql-custom

# Remove timescaledb and plv8 references (not in pg18)
RUN sed -i 's/ timescaledb,//g;' "/etc/postgresql/postgresql.conf" && \
sed -i 's/db_user_namespace = off/#db_user_namespace = off/g;' "/etc/postgresql/postgresql.conf" && \
sed -i 's/ timescaledb,//g; s/ plv8,//g' "/etc/postgresql-custom/supautils.conf"

# Include schema migrations
COPY migrations/db /docker-entrypoint-initdb.d/
COPY ansible/files/pgbouncer_config/pgbouncer_auth_schema.sql /docker-entrypoint-initdb.d/init-scripts/00-schema.sql
COPY ansible/files/stat_extension.sql /docker-entrypoint-initdb.d/migrations/00-extension.sql

# Add entrypoint script
ADD --chmod=0755 \
https://github.com/docker-library/postgres/raw/889f9447cd2dfe21cccfbe9bb7945e3b037e02d8/17/bullseye/docker-entrypoint.sh \
/usr/local/bin/docker-entrypoint.sh

# Setup pgsodium key script
RUN mkdir -p /usr/share/postgresql/extension/ && \
ln -s /usr/lib/postgresql/bin/pgsodium_getkey.sh /usr/share/postgresql/extension/pgsodium_getkey && \
chmod +x /usr/lib/postgresql/bin/pgsodium_getkey.sh

# Environment variables
ENV PATH="/nix/var/nix/profiles/default/bin:/usr/lib/postgresql/bin:${PATH}"
ENV PGDATA=/var/lib/postgresql/data
ENV POSTGRES_HOST=/var/run/postgresql
ENV POSTGRES_USER=supabase_admin
ENV POSTGRES_DB=postgres
ENV POSTGRES_INITDB_ARGS="--allow-group-access --locale-provider=icu --encoding=UTF-8 --icu-locale=en_US.UTF-8"
ENV LANG=en_US.UTF-8
ENV LANGUAGE=en_US:en
ENV LC_ALL=en_US.UTF-8
ENV GRN_PLUGINS_DIR=/usr/lib/groonga/plugins
# Point to minimal glibc locales included in slim Nix package for initdb locale support
ENV LOCALE_ARCHIVE=/nix/var/nix/profiles/default/lib/locale/locale-archive

ENTRYPOINT ["docker-entrypoint.sh"]
HEALTHCHECK --interval=2s --timeout=2s --retries=10 CMD pg_isready -U postgres -h localhost
STOPSIGNAL SIGINT
EXPOSE 5432

CMD ["postgres", "-D", "/etc/postgresql"]
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Supabase Postgres follows these core principles:

1. **Unmodified PostgreSQL** - We don't fork or modify PostgreSQL itself. You get standard PostgreSQL with extensions.
2. **Curated Extensions** - We include well-maintained, production-tested extensions that solve real problems.
3. **Multi-version Support** - Currently supporting PostgreSQL 15, 17, and OrioleDB-17.
3. **Multi-version Support** - Currently supporting PostgreSQL 15, 17, 18, and OrioleDB-17.
4. **Ready for Production** - Configured with sensible defaults for replication, security, and performance.
5. **Open Source** - Everything is open source and can be self-hosted.

Expand Down
5 changes: 3 additions & 2 deletions ansible/tasks/stage2-setup-postgres.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
- name: Check psql_version and modify supautils.conf and postgresql.conf if necessary
block:
- name: Check if psql_version is psql_orioledb-17 and if psql_version is psql_15 or psql_17
- name: Check if psql_version is psql_orioledb-17 and if psql_version is psql_15 or psql_17 or psql_18
ansible.builtin.set_fact:
is_psql_oriole: "{{ psql_version in ['psql_orioledb-17'] }}"
is_psql_17: "{{ psql_version in ['psql_17'] }}"
is_psql_18: "{{ psql_version in ['psql_18'] }}"
is_psql_15: "{{ psql_version in ['psql_15'] }}"

- name: Execute tasks when (is_psql_oriole or is_psql_17) and stage2_nix
become: true
when:
- (is_psql_oriole or is_psql_17)
- (is_psql_oriole or is_psql_17 or is_psql_18)
- stage2_nix
block:
- name: Remove specified extensions from postgresql.conf if orioledb-17 or 17 build
Expand Down
8 changes: 5 additions & 3 deletions migrations/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ from the root of the `supabase/postgres` project, you can run the following comm
Usage: nix run .#dbmate-tool -- [options]

Options:
-v, --version [15|16|orioledb-17|all] Specify the PostgreSQL version to use (required defaults to --version all)
-v, --version [15|17|18|orioledb-17|all] Specify the PostgreSQL version to use (defaults to all)
-p, --port PORT Specify the port number to use (default: 5435)
-u, --user USER Specify the PostgreSQL user to use (default: postgres)
-h, --help Show this help message
-f, --flake-url URL Specify the flake URL to use (default: current repo if available, otherwise github:supabase/postgres)

Description:
Runs 'dbmate up' against a locally running the version of database you specify. Or 'all' to run against all versions.
Expand All @@ -18,7 +20,7 @@ Description:
Examples:
nix run .#dbmate-tool
nix run .#dbmate-tool -- --version 15
nix run .#dbmate-tool -- --version 16 --port 5433
nix run .#dbmate-tool -- --version 18 --port 5433

```

Expand All @@ -29,7 +31,7 @@ nix run github:supabase/postgres#dbmate-tool -- --version 15

or

nix run github:supabase/postgres/mybranch#dbmate-tool -- --version 15
nix run github:supabase/postgres/mybranch#dbmate-tool -- --version 18
```
# supabase/migrations

Expand Down
Loading
Loading