Skip to content

Commit f738fa7

Browse files
authored
NO-JIRA: refactor(jupyter/datascience/Dockerfile.cpu): wrap multiple RUN commands with bash for consistency, readability, and improved error handling (#2647)
1 parent 7c7e9a7 commit f738fa7

File tree

1 file changed

+131
-113
lines changed

1 file changed

+131
-113
lines changed

jupyter/datascience/ubi9-python-3.12/Dockerfile.cpu

Lines changed: 131 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,22 @@ ARG TARGETARCH
1919

2020
# Keep s390x special-case from original (create dummy binary) but
2121
# include explicit curl/unzip steps from the delta for non-s390x.
22-
RUN arch="${TARGETARCH:-$(uname -m)}" && \
23-
arch=$(echo "$arch" | cut -d- -f1) && \
24-
if [ "$arch" = "s390x" ]; then \
25-
echo "Skipping mongocli build for ${arch}, creating dummy binary"; \
26-
mkdir -p /tmp && printf '#!/bin/sh\necho "mongocli not supported on s390x"\n' > /tmp/mongocli && \
27-
chmod +x /tmp/mongocli; \
28-
else \
29-
echo "Building mongocli for ${arch}"; \
30-
curl -Lo mongodb-cli-mongocli-v${MONGOCLI_VERSION}.zip https://github.com/mongodb/mongodb-cli/archive/refs/tags/mongocli/v${MONGOCLI_VERSION}.zip && \
31-
unzip ./mongodb-cli-mongocli-v${MONGOCLI_VERSION}.zip && \
32-
cd ./mongodb-cli-mongocli-v${MONGOCLI_VERSION}/ && \
33-
CGO_ENABLED=1 GOOS=linux GOARCH=${arch} GO111MODULE=on go build -a -tags strictfipsruntime -o /tmp/mongocli ./cmd/mongocli/; \
34-
fi
22+
RUN /bin/bash <<'EOF'
23+
set -Eeuxo pipefail
24+
arch="${TARGETARCH:-$(uname -m)}"
25+
arch=$(echo "$arch" | cut -d- -f1)
26+
if [ "$arch" = "s390x" ]; then
27+
echo "Skipping mongocli build for ${arch}, creating dummy binary"
28+
mkdir -p /tmp && printf '#!/bin/sh\necho "mongocli not supported on s390x"\n' > /tmp/mongocli
29+
chmod +x /tmp/mongocli
30+
else
31+
echo "Building mongocli for ${arch}"
32+
curl -Lo mongodb-cli-mongocli-v${MONGOCLI_VERSION}.zip https://github.com/mongodb/mongodb-cli/archive/refs/tags/mongocli/v${MONGOCLI_VERSION}.zip
33+
unzip ./mongodb-cli-mongocli-v${MONGOCLI_VERSION}.zip
34+
cd ./mongodb-cli-mongocli-v${MONGOCLI_VERSION}/
35+
CGO_ENABLED=1 GOOS=linux GOARCH=${arch} GO111MODULE=on go build -a -tags strictfipsruntime -o /tmp/mongocli ./cmd/mongocli/
36+
fi
37+
EOF
3538

3639
####################
3740
# cpu-base #
@@ -62,16 +65,19 @@ EOF
6265
# upgrade first to avoid fixable vulnerabilities end
6366

6467
# Install useful OS packages
65-
RUN --mount=type=cache,target=/var/cache/dnf \
66-
echo "Building for architecture: ${TARGETARCH}" && \
67-
if [ "$TARGETARCH" = "s390x" ]; then \
68-
PACKAGES="perl mesa-libGL skopeo gcc gcc-c++ make openssl-devel autoconf automake libtool cmake python3-devel pybind11-devel openblas-devel unixODBC-devel"; \
69-
else \
70-
PACKAGES="perl mesa-libGL skopeo"; \
71-
fi && \
72-
echo "Installing: $PACKAGES" && \
73-
dnf install -y $PACKAGES && \
74-
dnf clean all && rm -rf /var/cache/yum
68+
RUN --mount=type=cache,target=/var/cache/dnf /bin/bash <<'EOF'
69+
set -Eeuxo pipefail
70+
echo "Building for architecture: ${TARGETARCH}"
71+
if [ "$TARGETARCH" = "s390x" ]; then
72+
PACKAGES="perl mesa-libGL skopeo gcc gcc-c++ make openssl-devel autoconf automake libtool cmake python3-devel pybind11-devel openblas-devel unixODBC-devel"
73+
else
74+
PACKAGES="perl mesa-libGL skopeo"
75+
fi
76+
echo "Installing: $PACKAGES"
77+
dnf install -y $PACKAGES
78+
dnf clean all
79+
rm -rf /var/cache/yum
80+
EOF
7581

7682
RUN /bin/bash <<'EOF'
7783
set -Eeuxo pipefail
@@ -134,55 +140,57 @@ WORKDIR /tmp/build-wheels
134140

135141
# Build pyarrow on ppc64le and s390x
136142
RUN --mount=type=cache,target=/root/.cache/pip \
137-
--mount=type=cache,target=/root/.cache/dnf \
138-
if [ "$TARGETARCH" = "ppc64le" ] || [ "$TARGETARCH" = "s390x" ]; then \
139-
# Install build dependencies (shared for pyarrow and onnx)
140-
dnf install -y cmake make gcc-c++ pybind11-devel wget && \
141-
dnf clean all && \
142-
# Build and collect pyarrow wheel
143-
git clone --depth 1 --branch "apache-arrow-17.0.0" https://github.com/apache/arrow.git && \
144-
cd arrow/cpp && \
145-
mkdir release && cd release && \
146-
ARROW_S3_FLAG="" && \
147-
if [ "$TARGETARCH" != "s390x" ]; then ARROW_S3_FLAG="-DARROW_S3=ON"; fi && \
148-
cmake -DCMAKE_BUILD_TYPE=Release \
149-
-DCMAKE_INSTALL_PREFIX=/usr/local \
150-
-DARROW_PYTHON=ON \
151-
-DARROW_PARQUET=ON \
152-
-DARROW_ORC=ON \
153-
-DARROW_FILESYSTEM=ON \
154-
-DARROW_JSON=ON \
155-
-DARROW_CSV=ON \
156-
-DARROW_DATASET=ON \
157-
-DARROW_DEPENDENCY_SOURCE=BUNDLED \
158-
-DARROW_WITH_LZ4=OFF \
159-
-DARROW_WITH_ZSTD=OFF \
160-
-DARROW_WITH_SNAPPY=OFF \
161-
${ARROW_S3_FLAG} \
162-
-DARROW_SUBSTRAIT=ON \
163-
-DARROW_BUILD_TESTS=OFF \
164-
-DARROW_BUILD_BENCHMARKS=OFF \
165-
.. && \
166-
make -j$(nproc) VERBOSE=1 && \
167-
make install -j$(nproc) && \
168-
cd ../../python && \
169-
pip install --no-cache-dir -r requirements-build.txt && \
170-
PYARROW_WITH_PARQUET=1 \
171-
PYARROW_WITH_DATASET=1 \
172-
PYARROW_WITH_FILESYSTEM=1 \
173-
PYARROW_WITH_JSON=1 \
174-
PYARROW_WITH_CSV=1 \
175-
PYARROW_PARALLEL=$(nproc) \
176-
python setup.py build_ext --build-type=release --bundle-arrow-cpp bdist_wheel && \
177-
mkdir -p /tmp/wheels && \
178-
cp dist/pyarrow-*.whl /tmp/wheels/ && \
179-
chmod -R 777 /tmp/wheels && \
180-
# Ensure wheels directory exists and has content
181-
ls -la /tmp/wheels/; \
182-
else \
183-
# Create empty wheels directory for non-s390x
184-
mkdir -p /tmp/wheels; \
185-
fi
143+
--mount=type=cache,target=/root/.cache/dnf /bin/bash <<'EOF'
144+
set -Eeuxo pipefail
145+
if [ "$TARGETARCH" = "ppc64le" ] || [ "$TARGETARCH" = "s390x" ]; then
146+
# Install build dependencies (shared for pyarrow and onnx)
147+
dnf install -y cmake make gcc-c++ pybind11-devel wget
148+
dnf clean all
149+
# Build and collect pyarrow wheel
150+
git clone --depth 1 --branch "apache-arrow-17.0.0" https://github.com/apache/arrow.git
151+
cd arrow/cpp
152+
mkdir release && cd release
153+
ARROW_S3_FLAG=""
154+
if [ "$TARGETARCH" != "s390x" ]; then ARROW_S3_FLAG="-DARROW_S3=ON"; fi
155+
cmake -DCMAKE_BUILD_TYPE=Release \
156+
-DCMAKE_INSTALL_PREFIX=/usr/local \
157+
-DARROW_PYTHON=ON \
158+
-DARROW_PARQUET=ON \
159+
-DARROW_ORC=ON \
160+
-DARROW_FILESYSTEM=ON \
161+
-DARROW_JSON=ON \
162+
-DARROW_CSV=ON \
163+
-DARROW_DATASET=ON \
164+
-DARROW_DEPENDENCY_SOURCE=BUNDLED \
165+
-DARROW_WITH_LZ4=OFF \
166+
-DARROW_WITH_ZSTD=OFF \
167+
-DARROW_WITH_SNAPPY=OFF \
168+
${ARROW_S3_FLAG} \
169+
-DARROW_SUBSTRAIT=ON \
170+
-DARROW_BUILD_TESTS=OFF \
171+
-DARROW_BUILD_BENCHMARKS=OFF \
172+
..
173+
make -j$(nproc) VERBOSE=1
174+
make install -j$(nproc)
175+
cd ../../python
176+
pip install --no-cache-dir -r requirements-build.txt
177+
PYARROW_WITH_PARQUET=1 \
178+
PYARROW_WITH_DATASET=1 \
179+
PYARROW_WITH_FILESYSTEM=1 \
180+
PYARROW_WITH_JSON=1 \
181+
PYARROW_WITH_CSV=1 \
182+
PYARROW_PARALLEL=$(nproc) \
183+
python setup.py build_ext --build-type=release --bundle-arrow-cpp bdist_wheel
184+
mkdir -p /tmp/wheels
185+
cp dist/pyarrow-*.whl /tmp/wheels/
186+
chmod -R 777 /tmp/wheels
187+
# Ensure wheels directory exists and has content
188+
ls -la /tmp/wheels/
189+
else
190+
# Create empty wheels directory for non-s390x
191+
mkdir -p /tmp/wheels
192+
fi
193+
EOF
186194

187195
#######################################################
188196
# common-builder (for Power-only)
@@ -264,6 +272,7 @@ USER 0
264272
# Dependencies for PDF export begin
265273
RUN ./utils/install_pdf_deps.sh
266274
ENV PATH="/usr/local/texlive/bin/linux:/usr/local/pandoc/bin:$PATH"
275+
267276
# Dependencies for PDF export end
268277

269278
USER 1001
@@ -299,8 +308,12 @@ WORKDIR /opt/app-root/bin
299308
USER root
300309

301310
# Install useful OS packages
302-
RUN dnf install -y jq unixODBC unixODBC-devel postgresql git-lfs libsndfile libxcrypt-compat && \
303-
dnf clean all && rm -rf /var/cache/yum
311+
RUN /bin/bash <<'EOF'
312+
set -Eeuxo pipefail
313+
dnf install -y jq unixODBC unixODBC-devel postgresql git-lfs libsndfile libxcrypt-compat
314+
dnf clean all
315+
rm -rf /var/cache/yum
316+
EOF
304317

305318
# Copy dynamically-linked mongocli built in earlier build stage
306319
COPY --from=mongocli-builder /tmp/mongocli /opt/app-root/bin/
@@ -312,11 +325,14 @@ ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/
312325

313326
# Copy wheels from build stage (ppc64le and s390x only)
314327
COPY --from=pyarrow-builder /tmp/wheels /tmp/wheels
315-
RUN if [ "$TARGETARCH" = "ppc64le" ] || [ "$TARGETARCH" = "s390x" ]; then \
316-
pip install --no-cache-dir /tmp/wheels/*.whl; \
317-
else \
318-
echo "Skipping wheel install for $TARGETARCH"; \
328+
RUN /bin/bash <<'EOF'
329+
set -Eeuxo pipefail
330+
if [ "$TARGETARCH" = "ppc64le" ] || [ "$TARGETARCH" = "s390x" ]; then
331+
pip install --no-cache-dir /tmp/wheels/*.whl
332+
else
333+
echo "Skipping wheel install for $TARGETARCH"
319334
fi
335+
EOF
320336

321337
# Copy OpenBLAS,ONNX wheels for Power
322338
COPY --from=openblas-builder /root/OpenBLAS-${OPENBLAS_VERSION} /openblas
@@ -359,41 +375,43 @@ COPY ${DATASCIENCE_SOURCE_CODE}/pylock.toml ./
359375
# Copy Elyra setup to utils so that it's sourced at startup
360376
COPY ${DATASCIENCE_SOURCE_CODE}/setup-elyra.sh ${DATASCIENCE_SOURCE_CODE}/utils ./utils/
361377

362-
RUN --mount=type=cache,target=/root/.cache/pip \
363-
echo "Installing software and packages" && \
378+
RUN --mount=type=cache,target=/root/.cache/pip /bin/bash <<'EOF'
379+
set -Eeuxo pipefail
380+
echo "Installing software and packages"
381+
# This may have to download and compile some dependencies, and as we don't lock requirements from `build-system.requires`,
382+
# we often don't know the correct hashes and `--require-hashes` would therefore fail on non amd64, where building is common.
383+
if [ "$TARGETARCH" = "ppc64le" ] || [ "$TARGETARCH" = "s390x" ]; then
384+
# We need special flags and environment variables when building packages
385+
GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1 \
386+
CFLAGS="-O3" CXXFLAGS="-O3" \
387+
uv pip install --strict --no-deps --no-cache --no-config --no-progress \
388+
--verify-hashes --compile-bytecode --index-strategy=unsafe-best-match \
389+
--requirements=./pylock.toml
390+
else
364391
# This may have to download and compile some dependencies, and as we don't lock requirements from `build-system.requires`,
365-
# we often don't know the correct hashes and `--require-hashes` would therefore fail on non amd64, where building is common.
366-
if [ "$TARGETARCH" = "ppc64le" ] || [ "$TARGETARCH" = "s390x" ]; then \
367-
# We need special flags and environment variables when building packages
368-
GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1 \
369-
CFLAGS="-O3" CXXFLAGS="-O3" \
370-
uv pip install --strict --no-deps --no-cache --no-config --no-progress \
371-
--verify-hashes --compile-bytecode --index-strategy=unsafe-best-match \
372-
--requirements=./pylock.toml; \
373-
else \
374-
# This may have to download and compile some dependencies, and as we don't lock requirements from `build-system.requires`,
375-
# we often don't know the correct hashes and `--require-hashes` would therefore fail on non amd64, where building is common.
376-
uv pip install --strict --no-deps --no-cache --no-config --no-progress \
377-
--verify-hashes --compile-bytecode --index-strategy=unsafe-best-match \
378-
--requirements=./pylock.toml; \
379-
fi && \
380-
# setup path for runtime configuration
381-
mkdir /opt/app-root/runtimes && \
382-
mkdir /opt/app-root/pipeline-runtimes && \
383-
# Remove default Elyra runtime-images \
384-
rm /opt/app-root/share/jupyter/metadata/runtime-images/*.json && \
385-
# Replace Notebook's launcher, "(ipykernel)" with Python's version 3.x.y \
386-
sed -i -e "s/Python.*/$(python --version | cut -d '.' -f-2)\",/" \
387-
/opt/app-root/share/jupyter/kernels/python3/kernel.json && \
388-
# copy jupyter configuration
389-
install -D -m 0644 /opt/app-root/bin/utils/jupyter_server_config.py \
390-
/opt/app-root/etc/jupyter/jupyter_server_config.py && \
391-
# Disable announcement plugin of jupyterlab \
392-
jupyter labextension disable "@jupyterlab/apputils-extension:announcements" && \
393-
# Apply JupyterLab addons \
394-
/opt/app-root/bin/utils/addons/apply.sh && \
395-
# Fix permissions to support pip in Openshift environments \
396-
chmod -R g+w /opt/app-root/lib/python3.12/site-packages && \
397-
fix-permissions /opt/app-root -P
392+
# we often don't know the correct hashes and `--require-hashes` would therefore fail on non amd64, where building is common.
393+
uv pip install --strict --no-deps --no-cache --no-config --no-progress \
394+
--verify-hashes --compile-bytecode --index-strategy=unsafe-best-match \
395+
--requirements=./pylock.toml
396+
fi
397+
# setup path for runtime configuration
398+
mkdir /opt/app-root/runtimes
399+
mkdir /opt/app-root/pipeline-runtimes
400+
# Remove default Elyra runtime-images
401+
rm /opt/app-root/share/jupyter/metadata/runtime-images/*.json
402+
# Replace Notebook's launcher, "(ipykernel)" with Python's version 3.x.y
403+
sed -i -e "s/Python.*/$(python --version | cut -d '.' -f-2)\",/" \
404+
/opt/app-root/share/jupyter/kernels/python3/kernel.json
405+
# copy jupyter configuration
406+
install -D -m 0644 /opt/app-root/bin/utils/jupyter_server_config.py \
407+
/opt/app-root/etc/jupyter/jupyter_server_config.py
408+
# Disable announcement plugin of jupyterlab
409+
jupyter labextension disable "@jupyterlab/apputils-extension:announcements"
410+
# Apply JupyterLab addons
411+
/opt/app-root/bin/utils/addons/apply.sh
412+
# Fix permissions to support pip in Openshift environments
413+
chmod -R g+w /opt/app-root/lib/python3.12/site-packages
414+
fix-permissions /opt/app-root -P
415+
EOF
398416

399417
WORKDIR /opt/app-root/src

0 commit comments

Comments
 (0)