33#########################
44ARG BASE_IMAGE
55
6+ ####################
7+ # rpm-base #
8+ ####################
9+ # e.g., registry.access.redhat.com/ubi9/python-312:latest
10+ FROM ${BASE_IMAGE} AS rpm-base
11+
12+ USER root
13+ WORKDIR /root
14+
15+ ENV HOME=/root
16+
17+ ARG CODESERVER_SOURCE_CODE=codeserver/ubi9-python-3.12
18+
19+ ARG NODE_VERSION=20
20+
21+ ARG CODESERVER_VERSION=v4.98.0
22+
23+ COPY ${CODESERVER_SOURCE_CODE}/get_code_server_rpm.sh .
24+
25+ # create dummy file to ensure this stage is awaited before installing rpm
26+ RUN ./get_code_server_rpm.sh && touch /tmp/control
27+
28+ #######################
29+ # wheel caching stage #
30+ #######################
31+ FROM registry.access.redhat.com/ubi9/python-312:latest AS whl-cache
32+
33+ USER root
34+ WORKDIR /root
35+
36+ ENV HOME=/root
37+
38+ ARG CODESERVER_SOURCE_CODE=codeserver/ubi9-python-3.12
39+
40+ # copy requirements and scripts
41+ COPY ${CODESERVER_SOURCE_CODE}/pylock.toml ./
42+ COPY ${CODESERVER_SOURCE_CODE}/devel_env_setup.sh ./
43+
44+ # This stage installs (builds) all the packages needed and caches it in uv-cache
45+ # Important: Since HOME & USER for the python-312 has been changed,
46+ # we need to ensure the same cache directory is mounted in
47+ # the final stage with the necessary permissions to consume from cache
48+ RUN --mount=type=cache,target=/root/.cache/uv \
49+ pip install --no-cache uv && \
50+ # the devel script is ppc64le specific - sets up build-time dependencies
51+ source ./devel_env_setup.sh && \
52+ # This may have to download and compile some dependencies, and as we don't lock requirements from `build-system.requires`,
53+ # we often don't know the correct hashes and `--require-hashes` would therefore fail on non amd64, where building is common.
54+ uv pip install --strict --no-deps --refresh --no-config --no-progress --verify-hashes --compile-bytecode --index-strategy=unsafe-best-match --requirements=./pylock.toml
55+
56+ # dummy file to make image build wait for this stage
57+ RUN touch /tmp/control
58+
659####################
760# cpu-base #
861####################
@@ -21,6 +74,15 @@ RUN dnf -y upgrade --refresh --best --nodocs --noplugins --setopt=install_weak_d
2174# Install useful OS packages
2275RUN dnf install -y mesa-libGL skopeo && dnf clean all && rm -rf /var/cache/yum
2376
77+ # (ARCH-ppc64le): since wheels are compiled from source, we need shared libs available at runtime
78+ RUN --mount=type=cache,from=whl-cache,source=/root/OpenBLAS,target=/OpenBlas,rw \
79+ bash -c ' \
80+ if [[ $(uname -m) == "ppc64le" ]]; then \
81+ dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm; \
82+ dnf install -y lcms2 libraqm libimagequant openjpeg2; \
83+ PREFIX=/usr/ make install -C /OpenBlas; \
84+ fi '
85+
2486# Other apps and tools installed as default user
2587USER 1001
2688
@@ -62,8 +124,13 @@ WORKDIR /opt/app-root/bin
62124# Install useful OS packages
63125RUN dnf install -y jq git-lfs libsndfile && dnf clean all && rm -rf /var/cache/yum
64126
127+ # wait for rpm-base stage (rpm builds for ppc64le)
128+ COPY --from=rpm-base /tmp/control /dev/null
129+
65130# Install code-server
66- RUN dnf install -y "https://github.com/coder/code-server/releases/download/${CODESERVER_VERSION}/code-server-${CODESERVER_VERSION/v/}-${TARGETARCH}.rpm" && \
131+ # Note: Use cache mounts, bind mounts fail on konflux
132+ RUN --mount=type=cache,from=rpm-base,source=/tmp/,target=/code-server-rpm/,rw \
133+ dnf install -y "/code-server-rpm/code-server-${CODESERVER_VERSION/v/}-${TARGETARCH}.rpm" && \
67134 dnf -y clean all --enablerepo='*'
68135
69136COPY --chown=1001:0 ${CODESERVER_SOURCE_CODE}/utils utils/
@@ -142,18 +209,28 @@ ENV SHELL=/bin/bash
142209
143210ENV PYTHONPATH=/opt/app-root/bin/python3
144211
145- USER 1001
146-
147212# Install useful packages from requirements.txt
148213COPY ${CODESERVER_SOURCE_CODE}/pylock.toml ./
149214
215+ # wait for whl-cache stage (builds uv cache)
216+ COPY --from=whl-cache /tmp/control /dev/null
217+
150218# Install packages and cleanup
151- RUN echo "Installing softwares and packages" && \
152- # This may have to download and compile some dependencies, and as we don't lock requirements from `build-system.requires`,
153- # we often don't know the correct hashes and `--require-hashes` would therefore fail on non amd64, where building is common.
154- uv pip install --strict --no-deps --no-cache --no-config --no-progress --verify-hashes --compile-bytecode --index-strategy=unsafe-best-match --requirements=./pylock.toml && \
155- # Fix permissions to support pip in Openshift environments \
156- chmod -R g+w /opt/app-root/lib/python3.12/site-packages && \
219+ # install packages as USER 0 (this will allow us to consume uv cache)
220+ RUN --mount=type=cache,target=/root/.cache/uv \
221+ echo "Installing softwares and packages" && \
222+ # we can ensure wheels are consumed from the cache only by restricting internet access for uv install with '--offline' flag
223+ uv pip install --offline --cache-dir /root/.cache/uv --requirements=./pylock.toml && \
224+ # Note: debugpy wheel availabe on pypi (in uv cache) is none-any but bundles amd64.so files
225+ # Build debugpy from source instead
226+ uv pip install --no-cache git+https://github.com/microsoft/debugpy.git@v$(grep -A1 '\"debugpy\"' ./pylock.toml | grep -Eo '\b[0-9\.]+\b') && \
227+ # change ownership to default user (all packages were installed as root and has root:root ownership \
228+ chown -R 1001:0 /opt/app-root/lib
229+
230+ USER 1001
231+
232+ # Fix permissions to support pip in Openshift environments
233+ RUN chmod -R g+w /opt/app-root/lib/python3.12/site-packages && \
157234 fix-permissions /opt/app-root -P
158235
159236WORKDIR /opt/app-root/src
0 commit comments