Skip to content
This repository was archived by the owner on Aug 30, 2023. It is now read-only.

Commit c45e14c

Browse files
authored
ref(git): Switch git builds to multi-stage builds (#192)
This diff refactors git/Dockerfile to make use of [multi-stage builds](https://dockr.ly/2TxXT6p) which provides the following benefits: - Cleaner separation of `sdist` and `runtime` containers - Significantly smaller runtime image (~110MB, -12%) - Fewer layers on the runtime image (10 layers, down from 15) - Unified release and Docker image builds (no need for `Docker.sdist`) - Somewhat more maintainable Dockerfile
1 parent 05ae7d2 commit c45e14c

File tree

2 files changed

+126
-124
lines changed

2 files changed

+126
-124
lines changed

git/Dockerfile

Lines changed: 117 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,21 @@
11
# Build from any git sha by passing `--build-arg SENTRY_BUILD=<sha>`
2-
FROM python:2.7.16-slim-buster
3-
4-
# add our user and group first to make sure their IDs get assigned consistently
5-
RUN groupadd -r sentry && useradd -r -m -g sentry sentry
2+
FROM python:2.7.16-slim-buster as sdist
63

74
RUN apt-get update && apt-get install -y --no-install-recommends \
8-
gcc \
9-
git \
10-
libffi-dev \
11-
libgeoip-dev \
12-
libjpeg-dev \
13-
libmaxminddb-dev \
14-
libxml2-dev \
15-
libxmlsec1-dev \
16-
libxslt-dev \
17-
libyaml-dev \
18-
pkg-config \
19-
&& rm -rf /var/lib/apt/lists/*
20-
21-
# Sane defaults for pip
22-
ENV PIP_NO_CACHE_DIR off
23-
ENV PIP_DISABLE_PIP_VERSION_CHECK on
24-
ENV PIP_USE_PEP517 off
5+
# Needed for GPG
6+
dirmngr \
7+
gnupg \
8+
# Needed for fetching stuff
9+
wget \
10+
&& rm -rf /var/lib/apt/lists/*
2511

26-
# grab gosu for easy step-down from root
27-
RUN set -x \
28-
&& export GOSU_VERSION=1.11 \
29-
&& fetchDeps=" \
30-
dirmngr \
31-
gnupg \
32-
wget \
33-
" \
34-
&& apt-get update && apt-get install -y --no-install-recommends $fetchDeps && rm -rf /var/lib/apt/lists/* \
35-
&& wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \
36-
&& wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \
37-
&& export GNUPGHOME="$(mktemp -d)" \
38-
&& for key in \
12+
# Fetch trusted keys
13+
RUN for key in \
14+
# gosu
3915
B42F6819007F00F88E364FD4036A9C25BF357DD4 \
40-
; do \
41-
gpg --batch --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys "$key" || \
42-
gpg --batch --keyserver hkp://ipv4.pool.sks-keyservers.net --recv-keys "$key" || \
43-
gpg --batch --keyserver hkp://pgp.mit.edu:80 --recv-keys "$key" ; \
44-
done \
45-
&& gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \
46-
&& gpgconf --kill all \
47-
&& rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \
48-
&& chmod +x /usr/local/bin/gosu \
49-
&& gosu nobody true \
50-
&& apt-get purge -y --auto-remove $fetchDeps
51-
52-
# grab tini for signal processing and zombie killing
53-
RUN set -x \
54-
&& export TINI_VERSION=0.18.0 \
55-
&& fetchDeps=" \
56-
dirmngr \
57-
gnupg \
58-
wget \
59-
" \
60-
&& apt-get update && apt-get install -y --no-install-recommends $fetchDeps && rm -rf /var/lib/apt/lists/* \
61-
&& wget -O /usr/local/bin/tini "https://github.com/krallin/tini/releases/download/v$TINI_VERSION/tini" \
62-
&& wget -O /usr/local/bin/tini.asc "https://github.com/krallin/tini/releases/download/v$TINI_VERSION/tini.asc" \
63-
&& export GNUPGHOME="$(mktemp -d)" \
64-
&& for key in \
16+
# tini
6517
595E85A6B1B4779EA4DAAEC70B588DFF0527A9B7 \
66-
; do \
67-
gpg --batch --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys "$key" || \
68-
gpg --batch --keyserver hkp://ipv4.pool.sks-keyservers.net --recv-keys "$key" || \
69-
gpg --batch --keyserver hkp://pgp.mit.edu:80 --recv-keys "$key" ; \
70-
done \
71-
&& gpg --batch --verify /usr/local/bin/tini.asc /usr/local/bin/tini \
72-
&& gpgconf --kill all \
73-
&& rm -r "$GNUPGHOME" /usr/local/bin/tini.asc \
74-
&& chmod +x /usr/local/bin/tini \
75-
&& tini -h \
76-
&& apt-get purge -y --auto-remove $fetchDeps
77-
78-
# Support for RabbitMQ and GeoIP
79-
RUN set -x \
80-
&& apt-get update && apt-get install -y --no-install-recommends make && rm -rf /var/lib/apt/lists/* \
81-
&& pip install librabbitmq==1.6.1 maxminddb==1.4.1 \
82-
&& python -c 'import librabbitmq' \
83-
# Fully verify that the C extension is correctly installed, it unfortunately
84-
# requires a full check into maxminddb.extension.Reader
85-
&& python -c 'import maxminddb.extension; maxminddb.extension.Reader' \
86-
&& apt-get purge -y --auto-remove make
87-
88-
ARG SENTRY_BUILD=master
89-
ENV SENTRY_BUILD $SENTRY_BUILD
90-
91-
RUN [ "$SENTRY_BUILD" != '' ] \
92-
# Install node to build assets
93-
&& export NODE_VERSION=8.15.1 \
94-
&& export GNUPGHOME="$(mktemp -d)" \
95-
&& export YARN_CACHE_FOLDER="$(mktemp -d)" \
96-
&& buildDeps=" \
97-
g++ \
98-
dirmngr \
99-
gnupg \
100-
wget \
101-
" \
102-
&& apt-get update && apt-get install -y --no-install-recommends $buildDeps && rm -rf /var/lib/apt/lists/* \
103-
# gpg keys listed at https://github.com/nodejs/node
104-
&& set -ex \
105-
&& for key in \
18+
# Node - gpg keys listed at https://github.com/nodejs/node
10619
94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \
10720
FD3A5288F042B6850C66B31F09FE44734EB7990E \
10821
71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \
@@ -115,46 +28,126 @@ RUN [ "$SENTRY_BUILD" != '' ] \
11528
A48C2BEE680E841632CD4E44F07496B3EB3C1762 \
11629
B9E2F5981AA6E0CD28160D9FF13993A75599653C \
11730
; do \
118-
gpg --batch --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys "$key" || \
119-
gpg --batch --keyserver hkp://ipv4.pool.sks-keyservers.net --recv-keys "$key" || \
120-
gpg --batch --keyserver hkp://pgp.mit.edu:80 --recv-keys "$key" ; \
121-
done \
122-
&& mkdir -p /usr/local/node && PATH=/usr/local/node/bin:$PATH \
123-
&& rm -rf /var/lib/apt/lists/* \
124-
&& wget "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.gz" \
31+
# TODO(byk): Replace the keyserver below w/ something owned by Sentry
32+
gpg --batch --keyserver hkps://mattrobenolt-keyserver.global.ssl.fastly.net:443 --recv-keys "$key"; \
33+
done
34+
35+
# grab gosu for easy step-down from root
36+
ENV GOSU_VERSION 1.11
37+
RUN set -x \
38+
&& wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \
39+
&& wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \
40+
&& gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \
41+
&& rm -r /usr/local/bin/gosu.asc \
42+
&& chmod +x /usr/local/bin/gosu
43+
44+
# grab tini for signal processing and zombie killing
45+
ENV TINI_VERSION 0.18.0
46+
RUN set -x \
47+
&& wget -O /usr/local/bin/tini "https://github.com/krallin/tini/releases/download/v$TINI_VERSION/tini" \
48+
&& wget -O /usr/local/bin/tini.asc "https://github.com/krallin/tini/releases/download/v$TINI_VERSION/tini.asc" \
49+
&& gpg --batch --verify /usr/local/bin/tini.asc /usr/local/bin/tini \
50+
&& rm /usr/local/bin/tini.asc \
51+
&& chmod +x /usr/local/bin/tini
52+
53+
# Get and set up Node for front-end asset building
54+
ENV NODE_VERSION 10.16.3
55+
RUN wget "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.gz" \
12556
&& wget "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \
12657
&& gpg --batch --verify SHASUMS256.txt.asc \
127-
&& gpgconf --kill all \
12858
&& grep " node-v$NODE_VERSION-linux-x64.tar.gz\$" SHASUMS256.txt.asc | sha256sum -c - \
129-
&& tar -xzf "node-v$NODE_VERSION-linux-x64.tar.gz" -C /usr/local/node --strip-components=1 \
130-
&& rm -r "$GNUPGHOME" "node-v$NODE_VERSION-linux-x64.tar.gz" SHASUMS256.txt.asc \
131-
\
59+
&& tar -xzf "node-v$NODE_VERSION-linux-x64.tar.gz" -C /usr/local --strip-components=1 \
60+
&& rm -r "node-v$NODE_VERSION-linux-x64.tar.gz" SHASUMS256.txt.asc
61+
62+
ARG SENTRY_BUILD=master
63+
ENV SENTRY_BUILD $SENTRY_BUILD
64+
RUN [ "$SENTRY_BUILD" != '' ] \
13265
&& mkdir -p /usr/src/sentry \
13366
&& cd /usr/src/sentry \
13467
&& wget -qO - "https://github.com/getsentry/sentry/archive/${SENTRY_BUILD}.tar.gz" | tar -xzf - --strip-components=1 \
68+
&& export YARN_CACHE_FOLDER="$(mktemp -d)" \
13569
&& python setup.py bdist_wheel \
136-
\
137-
# Now remove node since it's not needed anymore in the final container
13870
&& rm -r "$YARN_CACHE_FOLDER" \
139-
&& rm -rf /usr/local/node \
140-
\
141-
&& pip install dist/*.whl \
142-
\
143-
&& apt-get purge -y --auto-remove $buildDeps \
71+
&& mv /usr/src/sentry/dist /dist \
14472
&& rm -rf /usr/src/sentry
14573

146-
ENV SENTRY_CONF=/etc/sentry \
147-
SENTRY_FILESTORE_DIR=/var/lib/sentry/files
14874

149-
RUN mkdir -p $SENTRY_CONF && mkdir -p $SENTRY_FILESTORE_DIR
75+
# This is the image to be run
76+
FROM python:2.7.16-slim-buster
77+
78+
# add our user and group first to make sure their IDs get assigned consistently
79+
RUN groupadd -r sentry && useradd -r -m -g sentry sentry
80+
81+
COPY --from=sdist /usr/local/bin/gosu /usr/local/bin/tini /usr/local/bin/
82+
83+
# Sane defaults for pip
84+
ENV PIP_NO_CACHE_DIR=off \
85+
PIP_DISABLE_PIP_VERSION_CHECK=1 \
86+
PIP_USE_PEP517=off \
87+
# Sentry config params
88+
SENTRY_CONF=/etc/sentry \
89+
SENTRY_FILESTORE_DIR=/var/lib/sentry/files \
90+
# Disable some unused uWSGI features, saving dependencies
91+
# Thank to https://stackoverflow.com/a/25260588/90297
92+
UWSGI_PROFILE_OVERRIDE=ssl=false;xml=false;routing=false
15093

151-
COPY sentry.conf.py /etc/sentry/
152-
COPY config.yml /etc/sentry/
94+
COPY --from=sdist /dist/*.whl /tmp/dist/
95+
RUN set -x \
96+
&& buildDeps="" \
97+
# uwsgi
98+
&& buildDeps="$buildDeps \
99+
gcc \
100+
g++ \
101+
" \
102+
# maxminddb
103+
&& buildDeps="$buildDeps \
104+
libmaxminddb-dev \
105+
"\
106+
# librabbitmq
107+
&& buildDeps="$buildDeps \
108+
make \
109+
" \
110+
&& apt-get update \
111+
&& apt-get install -y --no-install-recommends $buildDeps \
112+
&& pip install /tmp/dist/*.whl \
113+
# Separate these due to https://git.io/fjyz6
114+
# Otherwise librabbitmq will install the latest amqp version,
115+
# violating kombu's amqp<2.0 constraint.
116+
&& pip install librabbitmq==1.6.1 maxminddb==1.4.1 \
117+
&& rm -rf /tmp/dist \
118+
&& apt-get purge -y --auto-remove $buildDeps \
119+
# We install run-time dependencies strictly after
120+
# build dependencies to prevent accidental collusion.
121+
# These are also installed last as they are needed
122+
# during container run and can have the same deps w/
123+
# build deps such as maxminddb.
124+
&& apt-get install -y --no-install-recommends \
125+
# pillow
126+
libjpeg-dev \
127+
# rust bindings
128+
libffi-dev \
129+
# maxminddb bindings
130+
libmaxminddb-dev \
131+
# SAML needs these run-time
132+
libxmlsec1-dev \
133+
libxslt-dev \
134+
# pyyaml needs this run-time
135+
libyaml-dev \
136+
# other
137+
pkg-config \
138+
\
139+
&& apt-get clean \
140+
&& rm -rf /var/lib/apt/lists/* \
141+
&& python -c 'import librabbitmq' \
142+
# Fully verify that the C extension is correctly installed, it unfortunately
143+
# requires a full check into maxminddb.extension.Reader
144+
&& python -c 'import maxminddb.extension; maxminddb.extension.Reader' \
145+
&& mkdir -p $SENTRY_CONF && mkdir -p $SENTRY_FILESTORE_DIR
153146

154-
COPY docker-entrypoint.sh /entrypoint.sh
147+
COPY docker-entrypoint.sh sentry.conf.py config.yml $SENTRY_CONF/
155148

156149
EXPOSE 9000
157150
VOLUME /var/lib/sentry/files
158151

159-
ENTRYPOINT ["/entrypoint.sh"]
152+
ENTRYPOINT exec $SENTRY_CONF/docker-entrypoint.sh $0 $@
160153
CMD ["run", "web"]

sdist.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/env bash
2+
set -e
3+
4+
SDIST_IMAGE_NAME=getsentry/sentry:git-sdist
5+
6+
docker build git --target=sdist -t $SDIST_IMAGE_NAME
7+
id=$(docker create $SDIST_IMAGE_NAME)
8+
docker cp $id:/dist ./dist
9+
docker rm -v $id

0 commit comments

Comments
 (0)