-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile.downstream
More file actions
248 lines (225 loc) · 9.77 KB
/
Copy pathDockerfile.downstream
File metadata and controls
248 lines (225 loc) · 9.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
FROM registry.access.redhat.com/ubi9/ubi-minimal:9.7 AS base
# Only set variables or install packages that need to end up in the
# final container here.
USER root
ENV PATH=/opt/app-root/bin:/app/bin/:$PATH \
PYTHON_VERSION=3.12 \
PYTHONUNBUFFERED=1 \
PYTHONIOENCODING=UTF-8 \
LC_ALL=en_US.UTF-8 \
LANG=en_US.UTF-8 \
PIP_NO_CACHE_DIR=off
ENV PYTHONUSERBASE=/app
ENV TZ=UTC
RUN set -ex\
; microdnf -y module enable nginx:1.24 \
; microdnf -y --setopt=tsflags=nodocs install \
python3.12 \
python3.12-pip \
python-unversioned-command \
glibc-langpack-en \
dnsmasq \
memcached \
nginx \
libpq-devel \
libjpeg-turbo \
openldap \
openssl \
python3-gpg \
python3-six \
skopeo \
findutils \
; microdnf -y clean all && rm -rf /var/cache/yum \
; ln -sf /usr/bin/python3.12 /usr/bin/python \
; ln -sf /usr/bin/python3.12 /usr/bin/python3 \
; mkdir -p /opt/app-root/lib/python3.12/site-packages /opt/app-root/lib64/python3.12/site-packages /opt/app-root/bin /app/bin \
; chown -R 1001:0 /opt/app-root /app \
; chmod -R g=u /opt/app-root /app
# Build-python installs the requirements for the python code.
FROM base AS build-python
ENV PYTHONDONTWRITEBYTECODE=1
RUN set -ex\
; microdnf -y --setopt=tsflags=nodocs install \
gcc-c++ \
git \
cmake \
ninja-build \
openldap-devel \
python3.12-devel \
libffi-devel \
openssl-devel \
diffutils \
file \
make \
libjpeg-turbo \
libjpeg-turbo-devel \
wget \
rust-toolset \
libxml2-devel \
libxslt-devel \
freetype-devel \
; microdnf -y clean all
WORKDIR /build
RUN python3.12 -m ensurepip --upgrade
COPY requirements.txt .
# pyroscope-io build requires setuptools>=82 which removes pkg_resources
# needed by pbr, keystoneclient, etc. Pyroscope is optional profiling.
RUN sed -i '/^pyroscope-io/d' requirements.txt
# Note that it installs into /opt/app-root because of the '--prefix' flag.
# When cross-compiling the container, cargo uncontrollably consumes memory and
# gets killed by the OOM Killer when it fetches dependencies. The workaround is
# to use the git executable.
# See https://github.com/rust-lang/cargo/issues/10583 for details.
ENV CARGO_NET_GIT_FETCH_WITH_CLI=true
# grpcio has no pre-built wheels for s390x/ppc64le, so we must build from source on those.
# ARM64 and x86_64 have wheels available - use them to avoid slow QEMU compilation.
ENV GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1
USER 1001
# TARGETARCH is provided by BuildKit (amd64, arm64, ppc64le, s390x)
ARG TARGETARCH
RUN set -ex \
; NO_BINARY_OPTS="" \
; if [ "$TARGETARCH" = "ppc64le" ] || [ "$TARGETARCH" = "s390x" ]; then \
NO_BINARY_OPTS="--no-binary grpcio"; \
fi \
; python3.12 -m pip install --no-cache-dir --progress-bar off --prefix=/opt/app-root $NO_BINARY_OPTS $(grep -e '^pip=' -e '^wheel=' -e '^setuptools=' ./requirements.txt) \
; python3.12 -m pip install --no-cache-dir --progress-bar off --prefix=/opt/app-root $NO_BINARY_OPTS --requirement requirements.txt \
;
RUN set -ex\
# Doing this is explicitly against the purpose and use of certifi.
; for dir in\
$(find "/opt/app-root/lib/python3.12/site-packages" -type d -name certifi)\
; do chgrp -R 0 "$dir" && chmod -R g=u "$dir" ; done\
;
# Build dumb-init here since we have gcc, then copy binary to final stage
RUN python3.12 -m pip install --no-cache-dir --progress-bar off --prefix=/opt/app-root dumb-init
# Build-static downloads the static javascript.
FROM registry.access.redhat.com/ubi9/nodejs-22-minimal AS build-static
WORKDIR /opt/app-root/src
# This below line is a workaround because in UBI 9, the OpenSSL version does not support MD4 anymore which is required by the combination of webpack and terser-webpack-plugin.
ENV NODE_OPTIONS=--openssl-legacy-provider
COPY --chown=1001:0 package.json package-lock.json ./
RUN npm clean-install
COPY --chown=1001:0 static/ ./static/
COPY --chown=1001:0 *.json *.js ./
RUN npm run --quiet build
# Build React UI
FROM registry.access.redhat.com/ubi9/nodejs-22-minimal:latest AS build-ui
WORKDIR /opt/app-root
COPY --chown=1001:0 web/package.json web/package-lock.json ./
# web/.npmrc is intentionally excluded: it contains pnpm-specific options (node-linker=hoisted)
# that are incompatible with npm.
# --ignore-scripts is intentionally omitted: npm 10.9.7 crashes with "Exit handler never called!"
# when --ignore-scripts is combined with file: URLs that hermeto injects into package-lock.json.
# Lifecycle script risk is mitigated by cachi2/hermeto cryptographic prefetch verification.
RUN npm clean-install --legacy-peer-deps
COPY --chown=1001:0 web .
RUN npm run --quiet build
# Pushgateway grabs pushgateway.
FROM registry.access.redhat.com/ubi9/ubi-minimal:latest AS pushgateway
ENV OS=linux
ARG PUSHGATEWAY_VERSION=1.11.1
RUN set -ex\
; microdnf -y --setopt=tsflags=nodocs install tar gzip \
; ARCH=$(uname -m) ; echo $ARCH \
; if [ "$ARCH" == "x86_64" ] ; then ARCH="amd64" ; elif [ "$ARCH" == "aarch64" ] ; then ARCH="arm64" ; fi \
; TARBALL="pushgateway-${PUSHGATEWAY_VERSION}.${OS}-${ARCH}.tar.gz" \
; URL="https://github.com/prometheus/pushgateway/releases/download/v${PUSHGATEWAY_VERSION}/${TARBALL}" \
; curl -sSL ${URL} | tar xz "pushgateway-${PUSHGATEWAY_VERSION}.${OS}-${ARCH}/pushgateway" \
|| tar -xzf /cachi2/output/deps/generic/${TARBALL} "pushgateway-${PUSHGATEWAY_VERSION}.${OS}-${ARCH}/pushgateway"\
; install "pushgateway-${PUSHGATEWAY_VERSION}.${OS}-${ARCH}/pushgateway" /usr/local/bin/pushgateway\
;
# Config-tool builds the go binary in the configtool.
FROM registry.access.redhat.com/ubi9/go-toolset AS config-tool
WORKDIR /opt/app-root/src
COPY config-tool/ ./
RUN GOPATH=/opt/app-root/src/go go install -tags=fips ./cmd/config-tool
FROM registry.access.redhat.com/ubi9/ubi-minimal AS build-quaydir
WORKDIR /quaydir
COPY --from=build-static /opt/app-root/src/static /quaydir/static
COPY --from=build-ui /opt/app-root/dist /quaydir/static/patternfly
COPY --chown=0:0 . .
RUN chmod -R g=u ./conf
# Final is the end container, where all the work from the other
# containers are copied in.
FROM base AS final
LABEL com.redhat.component="quay-registry-container"
LABEL name="quay/quay-rhel9"
LABEL io.k8s.display-name="Red Hat Quay"
LABEL io.k8s.description="Red Hat Quay"
LABEL io.openshift.tags="quay"
LABEL summary="Red Hat Quay"
LABEL description="Red Hat Quay"
LABEL vendor="Red Hat, Inc."
LABEL maintainer="support@redhat.com"
LABEL io.containers.capabilities="NET_BIND_SERVICE" \
io.k8s.security.capabilities.drop="ALL" \
io.k8s.security.capabilities.add="NET_BIND_SERVICE" \
io.k8s.security.allow-privilege-escalation="false" \
io.k8s.security.run-as-non-root="true"
ENV QUAYDIR=/quay-registry
ENV QUAYCONF=/quay-registry/conf
ENV QUAYRUN=/quay-registry/conf
ENV QUAYPATH=$QUAYDIR
ENV PYTHONPATH=/opt/app-root/lib64/python3.12/site-packages:/opt/app-root/lib/python3.12/site-packages:$QUAYPATH
ENV RED_HAT_QUAY=true
# All of these chgrp+chmod commands are an Openshift-ism.
#
# Openshift runs a container as a random UID and GID 0, so anything
# that's in the base image and needs to be modified at runtime needs
# to make sure it's group-writable.
RUN set -ex\
; setperms() { for d in "$@"; do chgrp -R 0 "$d" && chmod -R g=u "$d" && ls -ld "$d"; done; }\
; newdir() { for d in "$@"; do mkdir -m 775 "$d" && ls -ld "$d"; done; }\
# Allow TLS certs to be created and installed as non-root user.
# See also update-ca-trust(8).
; setperms /etc/pki/ca-trust/extracted /etc/pki/ca-trust/source/anchors\
# Allow for nginx to run unprivledged.
; setperms /etc/nginx\
; ln -sf /dev/stdout /var/log/nginx/access.log\
; ln -sf /dev/stdout /var/log/nginx/error.log\
# The code doesn't agree on where the configuration lives, so create a
# symlink.
; ln -s $QUAYCONF /conf\
# Make a grip of runtime directories.
; newdir /certificates "$QUAYDIR" "$QUAYDIR/conf" "$QUAYDIR/conf/stack" /datastorage /var/lib/quay\
# Another Openshift-ism: it doesn't bother picking a uid that means
# anything to the OS inside the container, so the process needs
# permissions to modify the user database.
# Harden /etc/passwd – no group write.
; chown root:root /etc/passwd \
; chmod 0644 /etc/passwd \
; chown -R 1001:0 /etc/pki/ \
; chown -R 1001:0 /etc/ssl/ \
; chown -R 1001:0 /quay-registry \
; chmod ug+w /etc/pki/ca-trust \
; chmod ug+w -R /etc/pki/ca-trust/extracted /etc/pki/ca-trust/source/anchors \
; chmod ug+w -R /etc/ssl/certs
WORKDIR $QUAYDIR
# Ordered from least changing to most changing.
COPY --from=pushgateway /usr/local/bin/pushgateway /usr/local/bin/pushgateway
COPY --from=build-python /opt/app-root/lib/python3.12/site-packages /opt/app-root/lib/python3.12/site-packages
COPY --from=build-python /opt/app-root/lib64/python3.12/site-packages /opt/app-root/lib64/python3.12/site-packages
COPY --from=build-python /opt/app-root/bin /opt/app-root/bin
# dumb-init is built in build-python stage (which has gcc) and copied here
COPY --from=build-python /opt/app-root/bin/dumb-init /usr/local/bin/dumb-init
COPY --from=config-tool /opt/app-root/src/go/bin/config-tool /bin
COPY --from=build-quaydir /quaydir $QUAYDIR
RUN set -ex \
; chgrp -R 0 "$QUAYCONF" && chmod -R g=u "$QUAYCONF" \
;
# Strip setuid/setgid bits — with allowPrivilegeEscalation: false these are
# inert at runtime; removing them reduces scanner noise and attack surface.
RUN find / -xdev -perm /6000 -type f -exec chmod a-s {} + 2>/dev/null || true
ARG BUILD_TIMESTAMP
RUN date -u +%Y%m%d%H%M > $QUAYDIR/BUILD_DATE
EXPOSE 8080 8443 7443 9091 55443
# Don't expose /var/log as a volume, because we just configured it
# correctly above.
# It's probably unwise to mount /tmp as a volume but if someone must,
# make sure it's mode 1777 like /tmp should be.
VOLUME ["/datastorage", "/tmp", "/conf/stack"]
# In non-Openshift environments, drop privilege.
USER 1001
ENTRYPOINT ["dumb-init", "--", "/quay-registry/quay-entrypoint.sh"]
CMD ["registry"]