Skip to content

Commit 1e3da8c

Browse files
committed
update Dockerfile to match new format and add slim build support
1 parent f4663ae commit 1e3da8c

File tree

6 files changed

+131
-214
lines changed

6 files changed

+131
-214
lines changed

Dockerfile-18

Lines changed: 120 additions & 213 deletions
Original file line numberDiff line numberDiff line change
@@ -1,215 +1,130 @@
11
# syntax=docker/dockerfile:1.6
2-
ARG postgresql_major=18
3-
ARG postgresql_release=${postgresql_major}.1
4-
5-
# Bump default build arg to build a package from source
6-
# Bump vars.yml to specify runtime package version
7-
ARG sfcgal_release=1.3.10
8-
ARG postgis_release=3.3.2
9-
ARG pgrouting_release=3.4.1
10-
ARG pgtap_release=1.2.0
11-
ARG pg_cron_release=1.6.2
12-
ARG pgaudit_release=1.7.0
13-
ARG pgjwt_release=9742dab1b2f297ad3811120db7b21451bca2d3c9
14-
ARG pgsql_http_release=1.5.0
15-
ARG plpgsql_check_release=2.2.5
16-
ARG pg_safeupdate_release=1.4
17-
ARG timescaledb_release=2.9.1
18-
ARG wal2json_release=2_5
19-
ARG pljava_release=1.6.4
20-
ARG plv8_release=3.1.5
21-
ARG pg_plan_filter_release=5081a7b5cb890876e67d8e7486b6a64c38c9a492
22-
ARG pg_net_release=0.7.1
23-
ARG rum_release=1.3.13
24-
ARG pg_hashids_release=cd0e1b31d52b394a0df64079406a14a4f7387cd6
25-
ARG libsodium_release=1.0.18
26-
ARG pgsodium_release=3.1.6
27-
ARG pg_graphql_release=1.5.11
28-
ARG pg_stat_monitor_release=1.1.1
29-
ARG pg_jsonschema_release=0.1.4
30-
ARG pg_repack_release=1.4.8
31-
ARG vault_release=0.2.8
32-
ARG groonga_release=12.0.8
33-
ARG pgroonga_release=2.4.0
34-
ARG wrappers_release=0.5.7
35-
ARG hypopg_release=1.3.1
36-
ARG pgvector_release=0.4.0
37-
ARG pg_tle_release=1.3.2
38-
ARG index_advisor_release=0.2.0
39-
ARG supautils_release=2.2.0
40-
ARG wal_g_release=3.0.5
41-
42-
FROM ubuntu:noble as base
43-
44-
# Create reusable apt mirror fallback function
45-
RUN echo '#!/bin/bash\n\
46-
apt_update_with_fallback() {\n\
47-
local sources_file="/etc/apt/sources.list.d/ubuntu.sources"\n\
48-
local max_attempts=2\n\
49-
local attempt=1\n\
50-
local mirrors="archive.ubuntu.com us.archive.ubuntu.com"\n\
51-
\n\
52-
for mirror in $mirrors; do\n\
53-
echo "========================================="\n\
54-
echo "Attempting apt-get update with mirror: ${mirror}"\n\
55-
echo "Attempt ${attempt} of ${max_attempts}"\n\
56-
echo "========================================="\n\
57-
\n\
58-
if [ -f "${sources_file}" ]; then\n\
59-
sed -i "s|http://[^/]*/ubuntu/|http://${mirror}/ubuntu/|g" "${sources_file}"\n\
60-
fi\n\
61-
\n\
62-
if timeout 300 apt-get update 2>&1; then\n\
63-
echo "========================================="\n\
64-
echo "✓ Successfully updated apt cache using mirror: ${mirror}"\n\
65-
echo "========================================="\n\
66-
return 0\n\
67-
else\n\
68-
local exit_code=$?\n\
69-
echo "========================================="\n\
70-
echo "✗ Failed to update using mirror: ${mirror}"\n\
71-
echo "Exit code: ${exit_code}"\n\
72-
echo "========================================="\n\
73-
\n\
74-
apt-get clean\n\
75-
rm -rf /var/lib/apt/lists/*\n\
76-
\n\
77-
if [ ${attempt} -lt ${max_attempts} ]; then\n\
78-
local sleep_time=$((attempt * 5))\n\
79-
echo "Waiting ${sleep_time} seconds before trying next mirror..."\n\
80-
sleep ${sleep_time}\n\
81-
fi\n\
82-
fi\n\
83-
\n\
84-
attempt=$((attempt + 1))\n\
85-
done\n\
86-
\n\
87-
echo "========================================="\n\
88-
echo "ERROR: All mirror tiers failed after ${max_attempts} attempts"\n\
89-
echo "========================================="\n\
90-
return 1\n\
91-
}' > /usr/local/bin/apt-update-fallback.sh && chmod +x /usr/local/bin/apt-update-fallback.sh
92-
93-
RUN bash -c 'source /usr/local/bin/apt-update-fallback.sh && apt_update_with_fallback' && apt install -y \
2+
# Alpine-based slim PostgreSQL 18 image with Nix extensions
3+
4+
####################
5+
# Stage 1: Nix builder
6+
####################
7+
FROM alpine:3.21 AS nix-builder
8+
9+
# Install dependencies for nix installer (coreutils for GNU cp, sudo for installer)
10+
RUN apk add --no-cache \
11+
bash \
12+
coreutils \
9413
curl \
95-
gnupg \
96-
lsb-release \
97-
software-properties-common \
98-
wget \
14+
shadow \
9915
sudo \
100-
tree \
101-
&& apt clean
16+
xz
10217

18+
# Create users (Alpine syntax)
19+
RUN addgroup -S postgres && \
20+
adduser -S -h /var/lib/postgresql -s /bin/bash -G postgres postgres && \
21+
addgroup -S wal-g && \
22+
adduser -S -s /bin/bash -G wal-g wal-g
10323

104-
RUN adduser --system --home /var/lib/postgresql --no-create-home --shell /bin/bash --group --gecos "PostgreSQL administrator" postgres
105-
RUN adduser --system --no-create-home --shell /bin/bash --group wal-g
24+
# Create nix config
10625
RUN cat <<EOF > /tmp/extra-nix.conf
10726
extra-experimental-features = nix-command flakes
10827
extra-substituters = https://nix-postgres-artifacts.s3.amazonaws.com
10928
extra-trusted-public-keys = nix-postgres-artifacts:dGZlQOvKcNEjvT7QEAJbcV6b6uk7VF/hWMjhYleiaLI=
11029
EOF
111-
RUN curl -L https://releases.nixos.org/nix/nix-2.33.1/install | sh -s -- --daemon --no-channel-add --yes --nix-extra-conf-file /tmp/extra-nix.conf
30+
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
11231

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

115-
COPY . /nixpg
116-
11734
WORKDIR /nixpg
35+
COPY . .
11836

119-
RUN nix profile add path:.#psql_18/bin
37+
# Build PostgreSQL with extensions
38+
RUN nix profile add path:.#psql_18_slim/bin
12039

12140
RUN nix store gc
12241

123-
WORKDIR /
124-
125-
126-
RUN mkdir -p /usr/lib/postgresql/bin \
127-
/usr/lib/postgresql/share/postgresql \
128-
/usr/share/postgresql \
129-
/var/lib/postgresql \
130-
&& chown -R postgres:postgres /usr/lib/postgresql \
131-
&& chown -R postgres:postgres /var/lib/postgresql \
132-
&& chown -R postgres:postgres /usr/share/postgresql
133-
134-
# Create symbolic links
135-
RUN ln -s /nix/var/nix/profiles/default/bin/* /usr/lib/postgresql/bin/ \
136-
&& ln -s /nix/var/nix/profiles/default/bin/* /usr/bin/ \
137-
&& chown -R postgres:postgres /usr/bin
138-
139-
# Create symbolic links for PostgreSQL shares
140-
RUN ln -s /nix/var/nix/profiles/default/share/postgresql/* /usr/lib/postgresql/share/postgresql/
141-
RUN ln -s /nix/var/nix/profiles/default/share/postgresql/* /usr/share/postgresql/
142-
RUN chown -R postgres:postgres /usr/lib/postgresql/share/postgresql/
143-
RUN chown -R postgres:postgres /usr/share/postgresql/
144-
145-
RUN tree /nix > /tmp/tree.txt && cat /tmp/tree.txt && cat /tmp/tree.txt >&2
146-
147-
RUN chown -R postgres:postgres /usr/lib/postgresql
148-
149-
RUN ln -sf /usr/lib/postgresql/share/postgresql/timezonesets /usr/share/postgresql/timezonesets
42+
# Build groonga and copy plugins
43+
RUN nix profile add path:.#supabase-groonga && \
44+
mkdir -p /tmp/groonga-plugins && \
45+
cp -r /nix/var/nix/profiles/default/lib/groonga/plugins /tmp/groonga-plugins/
15046

47+
RUN nix store gc
15148

152-
RUN bash -c 'source /usr/local/bin/apt-update-fallback.sh && apt_update_with_fallback' && \
153-
apt-get install -y --no-install-recommends tzdata
49+
####################
50+
# Stage 2: Gosu builder
51+
####################
52+
FROM alpine:3.21 AS gosu-builder
15453

155-
RUN ln -fs /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
156-
dpkg-reconfigure --frontend noninteractive tzdata
54+
ARG TARGETARCH
55+
ARG GOSU_VERSION=1.16
15756

158-
RUN bash -c 'source /usr/local/bin/apt-update-fallback.sh && apt_update_with_fallback' && \
159-
apt-get install -y --no-install-recommends \
160-
build-essential \
161-
checkinstall \
162-
cmake
57+
RUN apk add --no-cache gnupg curl
16358

164-
ENV PGDATA=/var/lib/postgresql/data
59+
# Download and verify gosu
60+
RUN curl -fsSL "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-${TARGETARCH}" -o /usr/local/bin/gosu && \
61+
curl -fsSL "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-${TARGETARCH}.asc" -o /usr/local/bin/gosu.asc && \
62+
GNUPGHOME="$(mktemp -d)" && \
63+
export GNUPGHOME && \
64+
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 && \
65+
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu && \
66+
rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc && \
67+
chmod +x /usr/local/bin/gosu
16568

166-
WORKDIR /
16769
####################
168-
# setup-groonga
70+
# Stage 3: Final production image
16971
####################
170-
FROM base as groonga
171-
172-
WORKDIR /nixpg
72+
FROM alpine:3.21 AS production
17373

174-
RUN nix profile add path:.#supabase-groonga && \
175-
mkdir -p /tmp/groonga-plugins && \
176-
cp -r /nix/var/nix/profiles/default/lib/groonga/plugins /tmp/groonga-plugins/
74+
# Install minimal runtime dependencies
75+
RUN apk add --no-cache \
76+
bash \
77+
curl \
78+
shadow \
79+
su-exec \
80+
tzdata \
81+
musl-locales \
82+
musl-locales-lang \
83+
&& rm -rf /var/cache/apk/*
84+
85+
# Create postgres user/group
86+
RUN addgroup -S postgres && \
87+
adduser -S -G postgres -h /var/lib/postgresql -s /bin/bash postgres && \
88+
addgroup -S wal-g && \
89+
adduser -S -G wal-g -s /bin/bash wal-g && \
90+
adduser postgres wal-g
91+
92+
# Copy Nix store and profiles from builder (profile already created by nix profile install)
93+
COPY --from=nix-builder /nix /nix
94+
95+
# Copy groonga plugins
96+
COPY --from=nix-builder /tmp/groonga-plugins/plugins /usr/lib/groonga/plugins
97+
98+
# Copy gosu
99+
COPY --from=gosu-builder /usr/local/bin/gosu /usr/local/bin/gosu
100+
101+
# Setup PostgreSQL directories
102+
RUN mkdir -p /usr/lib/postgresql/bin \
103+
/usr/lib/postgresql/share/postgresql \
104+
/usr/share/postgresql \
105+
/var/lib/postgresql/data \
106+
/var/run/postgresql \
107+
&& chown -R postgres:postgres /usr/lib/postgresql \
108+
&& chown -R postgres:postgres /var/lib/postgresql \
109+
&& chown -R postgres:postgres /usr/share/postgresql \
110+
&& chown -R postgres:postgres /var/run/postgresql
177111

178-
RUN nix store gc
112+
# Create symbolic links for binaries
113+
RUN for f in /nix/var/nix/profiles/default/bin/*; do \
114+
ln -sf "$f" /usr/lib/postgresql/bin/ 2>/dev/null || true; \
115+
ln -sf "$f" /usr/bin/ 2>/dev/null || true; \
116+
done
179117

180-
WORKDIR /
181-
# ####################
182-
# # Download gosu for easy step-down from root
183-
# ####################
184-
FROM base as gosu
185-
ARG TARGETARCH
186-
# Install dependencies
187-
RUN bash -c 'source /usr/local/bin/apt-update-fallback.sh && apt_update_with_fallback' && apt-get install -y --no-install-recommends \
188-
gnupg \
189-
ca-certificates \
190-
&& rm -rf /var/lib/apt/lists/*
191-
# Download binary
192-
ARG GOSU_VERSION=1.16
193-
ARG GOSU_GPG_KEY=B42F6819007F00F88E364FD4036A9C25BF357DD4
194-
ADD https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$TARGETARCH \
195-
/usr/local/bin/gosu
196-
ADD https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$TARGETARCH.asc \
197-
/usr/local/bin/gosu.asc
198-
# Verify checksum
199-
RUN gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys $GOSU_GPG_KEY && \
200-
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu && \
201-
gpgconf --kill all && \
202-
chmod +x /usr/local/bin/gosu
118+
# Create symbolic links for PostgreSQL shares
119+
RUN ln -sf /nix/var/nix/profiles/default/share/postgresql/* /usr/lib/postgresql/share/postgresql/ 2>/dev/null || true && \
120+
ln -sf /nix/var/nix/profiles/default/share/postgresql/* /usr/share/postgresql/ 2>/dev/null || true && \
121+
ln -sf /usr/lib/postgresql/share/postgresql/timezonesets /usr/share/postgresql/timezonesets 2>/dev/null || true
203122

204-
# ####################
205-
# # Build final image
206-
# ####################
207-
FROM gosu as production
208-
RUN id postgres || (echo "postgres user does not exist" && exit 1)
209-
# # Setup extensions
210-
COPY --from=groonga /tmp/groonga-plugins/plugins /usr/lib/groonga/plugins
123+
# Set permissions
124+
RUN chown -R postgres:postgres /usr/lib/postgresql && \
125+
chown -R postgres:postgres /usr/share/postgresql
211126

212-
# # Initialise configs
127+
# Setup configs
213128
COPY --chown=postgres:postgres ansible/files/postgresql_config/postgresql.conf.j2 /etc/postgresql/postgresql.conf
214129
COPY --chown=postgres:postgres ansible/files/postgresql_config/pg_hba.conf.j2 /etc/postgresql/pg_hba.conf
215130
COPY --chown=postgres:postgres ansible/files/postgresql_config/pg_ident.conf.j2 /etc/postgresql/pg_ident.conf
@@ -223,61 +138,53 @@ COPY --chown=postgres:postgres ansible/files/postgresql_config/custom_read_repli
223138
COPY --chown=postgres:postgres ansible/files/walg_helper_scripts/wal_fetch.sh /home/postgres/wal_fetch.sh
224139
COPY ansible/files/walg_helper_scripts/wal_change_ownership.sh /root/wal_change_ownership.sh
225140

141+
# Configure PostgreSQL settings
226142
RUN sed -i \
227143
-e "s|#unix_socket_directories = '/tmp'|unix_socket_directories = '/var/run/postgresql'|g" \
228144
-e "s|#session_preload_libraries = ''|session_preload_libraries = 'supautils'|g" \
229145
-e "s|#include = '/etc/postgresql-custom/supautils.conf'|include = '/etc/postgresql-custom/supautils.conf'|g" \
230146
-e "s|#include = '/etc/postgresql-custom/wal-g.conf'|include = '/etc/postgresql-custom/wal-g.conf'|g" /etc/postgresql/postgresql.conf && \
231147
echo "pgsodium.getkey_script= '/usr/lib/postgresql/bin/pgsodium_getkey.sh'" >> /etc/postgresql/postgresql.conf && \
232148
echo "vault.getkey_script= '/usr/lib/postgresql/bin/pgsodium_getkey.sh'" >> /etc/postgresql/postgresql.conf && \
233-
usermod -aG postgres wal-g && \
234149
chown -R postgres:postgres /etc/postgresql-custom
235150

236-
# Remove items from postgresql.conf
237-
RUN sed -i 's/ timescaledb,//g;' "/etc/postgresql/postgresql.conf"
238-
#as of pg 16.4 + this db_user_namespace totally deprecated and will break the server if setting is present
239-
RUN sed -i 's/db_user_namespace = off/#db_user_namespace = off/g;' "/etc/postgresql/postgresql.conf"
240-
RUN sed -i 's/ timescaledb,//g; s/ plv8,//g' "/etc/postgresql-custom/supautils.conf"
241-
151+
# Remove timescaledb and plv8 references (not in pg18)
152+
RUN sed -i 's/ timescaledb,//g;' "/etc/postgresql/postgresql.conf" && \
153+
sed -i 's/db_user_namespace = off/#db_user_namespace = off/g;' "/etc/postgresql/postgresql.conf" && \
154+
sed -i 's/ timescaledb,//g; s/ plv8,//g' "/etc/postgresql-custom/supautils.conf"
242155

243-
244-
# # Include schema migrations
156+
# Include schema migrations
245157
COPY migrations/db /docker-entrypoint-initdb.d/
246158
COPY ansible/files/pgbouncer_config/pgbouncer_auth_schema.sql /docker-entrypoint-initdb.d/init-scripts/00-schema.sql
247159
COPY ansible/files/stat_extension.sql /docker-entrypoint-initdb.d/migrations/00-extension.sql
248160

249-
# # Add upstream entrypoint script pinned for now to last tested version
250-
COPY --from=gosu /usr/local/bin/gosu /usr/local/bin/gosu
161+
# Add entrypoint script
251162
ADD --chmod=0755 \
252163
https://github.com/docker-library/postgres/raw/889f9447cd2dfe21cccfbe9bb7945e3b037e02d8/17/bullseye/docker-entrypoint.sh \
253164
/usr/local/bin/docker-entrypoint.sh
254165

255-
RUN mkdir -p /var/run/postgresql && chown postgres:postgres /var/run/postgresql
256-
257-
ENTRYPOINT ["docker-entrypoint.sh"]
258-
259-
HEALTHCHECK --interval=2s --timeout=2s --retries=10 CMD pg_isready -U postgres -h localhost
260-
STOPSIGNAL SIGINT
261-
EXPOSE 5432
166+
# Setup pgsodium key script
167+
RUN mkdir -p /usr/share/postgresql/extension/ && \
168+
ln -s /usr/lib/postgresql/bin/pgsodium_getkey.sh /usr/share/postgresql/extension/pgsodium_getkey && \
169+
chmod +x /usr/lib/postgresql/bin/pgsodium_getkey.sh
262170

171+
# Environment variables
172+
ENV PATH="/nix/var/nix/profiles/default/bin:/usr/lib/postgresql/bin:${PATH}"
173+
ENV PGDATA=/var/lib/postgresql/data
263174
ENV POSTGRES_HOST=/var/run/postgresql
264175
ENV POSTGRES_USER=supabase_admin
265176
ENV POSTGRES_DB=postgres
266177
ENV POSTGRES_INITDB_ARGS="--allow-group-access --locale-provider=icu --encoding=UTF-8 --icu-locale=en_US.UTF-8"
267-
RUN bash -c 'source /usr/local/bin/apt-update-fallback.sh && apt_update_with_fallback' && apt-get install -y --no-install-recommends \
268-
locales \
269-
&& rm -rf /var/lib/apt/lists/* && \
270-
localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 \
271-
&& localedef -i C -c -f UTF-8 -A /usr/share/locale/locale.alias C.UTF-8
272-
RUN echo "C.UTF-8 UTF-8" > /etc/locale.gen && echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen && locale-gen
273-
ENV LANG en_US.UTF-8
274-
ENV LANGUAGE en_US:en
275-
ENV LC_ALL en_US.UTF-8
276-
ENV LOCALE_ARCHIVE /usr/lib/locale/locale-archive
277-
RUN mkdir -p /usr/share/postgresql/extension/ && \
278-
ln -s /usr/lib/postgresql/bin/pgsodium_getkey.sh /usr/share/postgresql/extension/pgsodium_getkey && \
279-
chmod +x /usr/lib/postgresql/bin/pgsodium_getkey.sh
280-
178+
ENV LANG=en_US.UTF-8
179+
ENV LANGUAGE=en_US:en
180+
ENV LC_ALL=en_US.UTF-8
281181
ENV GRN_PLUGINS_DIR=/usr/lib/groonga/plugins
182+
# Point to minimal glibc locales included in slim Nix package for initdb locale support
183+
ENV LOCALE_ARCHIVE=/nix/var/nix/profiles/default/lib/locale/locale-archive
184+
185+
ENTRYPOINT ["docker-entrypoint.sh"]
186+
HEALTHCHECK --interval=2s --timeout=2s --retries=10 CMD pg_isready -U postgres -h localhost
187+
STOPSIGNAL SIGINT
188+
EXPOSE 5432
282189

283190
CMD ["postgres", "-D", "/etc/postgresql"]

0 commit comments

Comments
 (0)