ciron
ciron

Reputation: 1

Installing the correct arm64 packages when doing a multi-platform cross-compilation Docker build

I built a multi-platform Docker image using Linux and installed numpy via pip requirements.xt file. The image builds fine and the container runs well on Windows/Linux, but when running on an M1 mac laptop, I get the following error:

File "/opt/venv/lib/python3.11/site-packages/streamlit/type_util.py", line 40, in <module>
    import numpy as np
  File "/opt/venv/lib/python3.11/site-packages/numpy/__init__.py", line 139, in <module>
    from . import core
  File "/opt/venv/lib/python3.11/site-packages/numpy/core/__init__.py", line 49, in <module>
    raise ImportError(msg)
ImportError: 

After asking the numpy git about this (https://github.com/numpy/numpy/issues/24114), it seems that the arm64 image/Python isn't correctly pulling the arm64 numpy package.

The below is my Dockerfile. I'm also attempting a multi-stage build. Would anyone have any insight into fixing the import error?

FROM --platform=$BUILDPLATFORM python:3.11-slim-bookworm AS build
ARG TARGETPLATFORM

ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

COPY requirements.txt ./
RUN pip3 install -r requirements.txt

FROM python:3.11-slim-bookworm AS runtime

# setup user and group ids
ARG USER_ID=1000
ENV USER_ID $USER_ID
ARG GROUP_ID=1000
ENV GROUP_ID $GROUP_ID

# add non-root user and give permissions to workdir
RUN groupadd --gid $GROUP_ID user && \
          adduser user --ingroup user --gecos '' --disabled-password --uid $USER_ID && \
          mkdir -p /usr/src/app_dir && \
          chown -R user:user /usr/src/app_dir

# copy from build image
COPY --chown=user:user --from=build /opt/venv /opt/venv

RUN apt-get update && apt-get install --no-install-recommends -y tk \
    && rm -rf /var/lib/apt/lists/* 

# set working directory
WORKDIR /app_dir

# switch to non-root user
USER user

# Path
ENV PATH="/opt/venv/bin:$PATH"

COPY ./app .

EXPOSE 8501
HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
ENTRYPOINT ["streamlit", "run", "Home.py", "--server.fileWatcherType=none", "--server.port=8501", "--server.address=0.0.0.0", "--server.headless=true"]

I've tried switching to just single-stage build, but when the mac pulls the arm64 image, it's still running under qemu (unsure why). Changing the second stage to FROM --platform=$TARGETPLATFORM python:3.11-slim-bookworm AS runtime results in the same initial ImportError.

Upvotes: 0

Views: 715

Answers (1)

victorlin
victorlin

Reputation: 704

You'll want to use FROM --platform=$TARGETPLATFORM on the first stage to get a fully emulated build on other platforms. Note that the build may be significantly slower.

FROM --platform=$BUILDPLATFORM means if you're building on linux/amd64, the commands will install for the build platform (linux/amd64) and can't be run on another platform such as Apple silicon, unless emulation is possible and configured.

Upvotes: 0

Related Questions