@@ -12,21 +12,37 @@ RUN set -ex; \
1212 fi
1313
1414# explicitly set user/group IDs
15- RUN groupadd -r postgres --gid=999 && useradd -r -g postgres --uid=999 postgres
15+ RUN set -eux; \
16+ groupadd -r postgres --gid=999; \
17+ # https://salsa.debian.org/postgresql/postgresql-common/blob/997d842ee744687d99a2b2d95c1083a2615c79e8/debian/postgresql-common.postinst#L32-35
18+ useradd -r -g postgres --uid=999 --home-dir=/var/lib/postgresql --shell=/bin/bash postgres; \
19+ # also create the postgres user's home directory with appropriate permissions
20+ # see https://github.com/docker-library/postgres/issues/274
21+ mkdir -p /var/lib/postgresql; \
22+ chown -R postgres:postgres /var/lib/postgresql
1623
1724# grab gosu for easy step-down from root
18- ENV GOSU_VERSION 1.10
19- RUN set -x \
20- && apt-get update && apt-get install -y --no-install-recommends ca-certificates wget && rm -rf /var/lib/apt/lists/* \
21- && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \
22- && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \
23- && export GNUPGHOME="$(mktemp -d)" \
24- && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
25- && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \
26- && rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc \
27- && chmod +x /usr/local/bin/gosu \
28- && gosu nobody true \
29- && apt-get purge -y --auto-remove ca-certificates wget
25+ # https://github.com/tianon/gosu/releases
26+ ENV GOSU_VERSION 1.12
27+ RUN set -eux; \
28+ savedAptMark="$(apt-mark showmanual)" ; \
29+ apt-get update; \
30+ apt-get install -y --no-install-recommends ca-certificates wget; \
31+ rm -rf /var/lib/apt/lists/*; \
32+ dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')" ; \
33+ wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch" ; \
34+ wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc" ; \
35+ export GNUPGHOME="$(mktemp -d)" ; \
36+ gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
37+ gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
38+ gpgconf --kill all; \
39+ rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
40+ apt-mark auto '.*' > /dev/null; \
41+ [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \
42+ apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
43+ chmod +x /usr/local/bin/gosu; \
44+ gosu --version; \
45+ gosu nobody true
3046
3147# make the "en_US.UTF-8" locale so postgres will be utf-8 enabled by default
3248RUN set -eux; \
@@ -36,10 +52,22 @@ RUN set -eux; \
3652 sed -ri '/\/ usr\/ share\/ locale/d' /etc/dpkg/dpkg.cfg.d/docker; \
3753 ! grep -q '/usr/share/locale' /etc/dpkg/dpkg.cfg.d/docker; \
3854 fi; \
39- apt-get update; apt-get install -y locales; rm -rf /var/lib/apt/lists/*; \
55+ apt-get update; apt-get install -y --no-install-recommends locales; rm -rf /var/lib/apt/lists/*; \
4056 localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
4157ENV LANG en_US.utf8
4258
59+ RUN set -eux; \
60+ apt-get update; \
61+ apt-get install -y --no-install-recommends \
62+ # install "nss_wrapper" in case we need to fake "/etc/passwd" and "/etc/group" (especially for OpenShift)
63+ # https://github.com/docker-library/postgres/issues/359
64+ # https://cwrap.org/nss_wrapper.html
65+ libnss-wrapper \
66+ # install "xz-utils" for .sql.xz docker-entrypoint-initdb.d files
67+ xz-utils \
68+ ; \
69+ rm -rf /var/lib/apt/lists/*
70+
4371RUN mkdir /docker-entrypoint-initdb.d
4472
4573RUN set -ex; \
@@ -48,19 +76,23 @@ RUN set -ex; \
4876# uid PostgreSQL Debian Repository
4977 key='B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8' ; \
5078 export GNUPGHOME="$(mktemp -d)" ; \
51- gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key" ; \
52- gpg --export "$key" > /etc/apt/trusted.gpg.d/postgres.gpg; \
79+ gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "$key" ; \
80+ gpg --batch --export "$key" > /etc/apt/trusted.gpg.d/postgres.gpg; \
81+ command -v gpgconf > /dev/null && gpgconf --kill all; \
5382 rm -rf "$GNUPGHOME" ; \
5483 apt-key list
5584
5685ENV PG_MAJOR 10
57- ENV PG_VERSION 10.3 -1.pgdg90+1
86+ ENV PG_VERSION 10.14 -1.pgdg90+1
5887
5988RUN set -ex; \
6089 \
90+ # see note below about "*.pyc" files
91+ export PYTHONDONTWRITEBYTECODE=1; \
92+ \
6193 dpkgArch="$(dpkg --print-architecture)" ; \
6294 case "$dpkgArch" in \
63- amd64| i386| ppc64el) \
95+ amd64 | i386 | ppc64el) \
6496# arches officialy built by upstream
6597 echo "deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main $PG_MAJOR" > /etc/apt/sources.list.d/pgdg.list; \
6698 apt-get update; \
@@ -70,6 +102,15 @@ RUN set -ex; \
70102# let's build binaries from their published source packages
71103 echo "deb-src http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main $PG_MAJOR" > /etc/apt/sources.list.d/pgdg.list; \
72104 \
105+ case "$PG_MAJOR" in \
106+ 9.* | 10 ) ;; \
107+ *) \
108+ # https://github.com/docker-library/postgres/issues/484 (clang-6.0 required, only available in stretch-backports)
109+ # TODO remove this once we hit buster+
110+ echo 'deb http://deb.debian.org/debian stretch-backports main' >> /etc/apt/sources.list.d/pgdg.list; \
111+ ;; \
112+ esac; \
113+ \
73114 tempDir="$(mktemp -d)" ; \
74115 cd "$tempDir" ; \
75116 \
@@ -106,9 +147,9 @@ RUN set -ex; \
106147 ;; \
107148 esac; \
108149 \
109- apt-get install -y postgresql-common; \
150+ apt-get install -y --no-install-recommends postgresql-common; \
110151 sed -ri 's/#(create_main_cluster) .*$/\1 = false/' /etc/postgresql-common/createcluster.conf; \
111- apt-get install -y \
152+ apt-get install -y --no-install-recommends \
112153 "postgresql-$PG_MAJOR=$PG_VERSION" \
113154 ; \
114155 \
@@ -118,23 +159,60 @@ RUN set -ex; \
118159# if we have leftovers from building, let's purge them (including extra, unnecessary build deps)
119160 apt-get purge -y --auto-remove; \
120161 rm -rf "$tempDir" /etc/apt/sources.list.d/temp.list; \
121- fi
162+ fi; \
163+ \
164+ # some of the steps above generate a lot of "*.pyc" files (and setting "PYTHONDONTWRITEBYTECODE" beforehand doesn't propagate properly for some reason), so we clean them up manually (as long as they aren't owned by a package)
165+ find /usr -name '*.pyc' -type f -exec bash -c 'for pyc; do dpkg -S "$pyc" &> /dev/null || rm -vf "$pyc"; done' -- '{}' +
122166
123167# make the sample config easier to munge (and "correct by default")
124- RUN mv -v "/usr/share/postgresql/$PG_MAJOR/postgresql.conf.sample" /usr/share/postgresql/ \
125- && ln -sv ../postgresql.conf.sample "/usr/share/postgresql/$PG_MAJOR/" \
126- && sed -ri "s!^#?(listen_addresses)\s *=\s *\S +.*!\1 = '*'!" /usr/share/postgresql/postgresql.conf.sample
168+ RUN set -eux; \
169+ dpkg-divert --add --rename --divert "/usr/share/postgresql/postgresql.conf.sample.dpkg" "/usr/share/postgresql/$PG_MAJOR/postgresql.conf.sample" ; \
170+ cp -v /usr/share/postgresql/postgresql.conf.sample.dpkg /usr/share/postgresql/postgresql.conf.sample; \
171+ ln -sv ../postgresql.conf.sample "/usr/share/postgresql/$PG_MAJOR/" ; \
172+ sed -ri "s!^#?(listen_addresses)\s *=\s *\S +.*!\1 = '*'!" /usr/share/postgresql/postgresql.conf.sample; \
173+ grep -F "listen_addresses = '*'" /usr/share/postgresql/postgresql.conf.sample
127174
128175RUN mkdir -p /var/run/postgresql && chown -R postgres:postgres /var/run/postgresql && chmod 2777 /var/run/postgresql
129176
130177ENV PATH $PATH:/usr/lib/postgresql/$PG_MAJOR/bin
131178ENV PGDATA /var/lib/postgresql/data
132- RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA" # this 777 will be replaced by 700 at runtime (allows semi-arbitrary "--user" values)
179+ # this 777 will be replaced by 700 at runtime (allows semi-arbitrary "--user" values)
180+ RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA"
133181VOLUME /var/lib/postgresql/data
134182
135183COPY docker-entrypoint.sh /usr/local/bin/
136184RUN ln -s usr/local/bin/docker-entrypoint.sh / # backwards compat
137185ENTRYPOINT ["docker-entrypoint.sh" ]
138186
187+ # We set the default STOPSIGNAL to SIGINT, which corresponds to what PostgreSQL
188+ # calls "Fast Shutdown mode" wherein new connections are disallowed and any
189+ # in-progress transactions are aborted, allowing PostgreSQL to stop cleanly and
190+ # flush tables to disk, which is the best compromise available to avoid data
191+ # corruption.
192+ #
193+ # Users who know their applications do not keep open long-lived idle connections
194+ # may way to use a value of SIGTERM instead, which corresponds to "Smart
195+ # Shutdown mode" in which any existing sessions are allowed to finish and the
196+ # server stops when all sessions are terminated.
197+ #
198+ # See https://www.postgresql.org/docs/12/server-shutdown.html for more details
199+ # about available PostgreSQL server shutdown signals.
200+ #
201+ # See also https://www.postgresql.org/docs/12/server-start.html for further
202+ # justification of this as the default value, namely that the example (and
203+ # shipped) systemd service files use the "Fast Shutdown mode" for service
204+ # termination.
205+ #
206+ STOPSIGNAL SIGINT
207+ #
208+ # An additional setting that is recommended for all users regardless of this
209+ # value is the runtime "--stop-timeout" (or your orchestrator/runtime's
210+ # equivalent) for controlling how long to wait between sending the defined
211+ # STOPSIGNAL and sending SIGKILL (which is likely to cause data corruption).
212+ #
213+ # The default in most runtimes (such as Docker) is 10 seconds, and the
214+ # documentation at https://www.postgresql.org/docs/12/server-start.html notes
215+ # that even 90 seconds may not be long enough in many instances.
216+
139217EXPOSE 5432
140218CMD ["postgres" ]
0 commit comments