1
0
mirror of https://github.com/quay/quay.git synced 2026-10-23 09:49:06 +03:00
Files
quay/Dockerfile.downstream
Li Zhang 55e33d1be5 PROJQUAY-12456: feat(ui): display nightly build info in help dropdown (#6713)
* PROJQUAY-12456: feat(ui): display nightly build info in help dropdown

Add a help (?) dropdown to the masthead toolbar showing Documentation,
API Reference, and the build version string. For Konflux nightly builds,
the version auto-constructs as "v3.18.0-nightly-20260803" by reading a
BUILD_DATE file generated during the Docker image build.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PROJQUAY-12456: fix(lint): apply black formatting to test_version.py

Use parenthesized context managers for multi-line with statements.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PROJQUAY-12456: fix(review): address CodeRabbit review feedback

- Add ARG BUILD_TIMESTAMP to bust Docker layer cache for BUILD_DATE
- Use DOCUMENTATION_ROOT from config instead of hardcoded URL
- Update E2E test to assert Documentation href from config

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PROJQUAY-12456: fix(build): use per-minute timestamp for unique nightly versions

Change BUILD_DATE format from %Y%m%d to %Y%m%d%H%M so multiple builds
on the same day produce distinct version strings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PROJQUAY-12456: fix(test): query anchor inside DropdownItem for href assertion

PatternFly DropdownItem renders data-testid on the <li> wrapper, not
the <a> child. Use locator('a') to reach the element with href.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PROJQUAY-12456: refactor(ui): move docs and version from footer to help dropdown

Remove Documentation link and version display from QuayFooter and
LoginFooter since they are now shown in the masthead help dropdown,
avoiding duplication.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* PROJQUAY-12456: fix(test): skip footer tests when no footer items configured

After moving Documentation and version to the help dropdown, the footer
renders nothing in CI environments without FOOTER_LINKS. Skip footer
visibility tests when no footer items are configured.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-08-05 17:48:45 -05:00

249 lines
9.8 KiB
Docker
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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"]