pip install oracledb takes ~9 minutes on Alpine (musl) because no musllinux wheel, how to avoid building from source in Docker?

4 days ago 11
ARTICLE AD BOX

I'm building a Django app inside a Docker image based on python:3.13-alpine3.23 as part of a GitLab CI pipeline. After replacing cx-Oracle==8.3.0 with oracledb==3.4.2 in requirements.txt, the pip install -r requirements.txt layer in my Dockerfile went from ~48 seconds to ~614 seconds, and the whole pipeline job went from 5 min 37 s to 14 min 23 s.

Drilling into the BuildKit log, ~557 of those extra seconds are a single wheel build:

#12 21.32 Building wheels for collected packages: pymongo, oracledb #12 32.37 Building wheel for oracledb (pyproject.toml): started #12 220.6 Building wheel for oracledb (pyproject.toml): still running... #12 479.1 Building wheel for oracledb (pyproject.toml): still running... #12 565.2 Building wheel for oracledb (pyproject.toml): still running... #12 589.1 Building wheel for oracledb (pyproject.toml): finished with status 'done'

So pip is compiling oracledb from the sdist (oracledb-3.4.2.tar.gz, 855 kB) on every build.

What I've checked

On PyPI, oracledb ships manylinux wheels (glibc) and macOS/Windows wheels, but I don't see a musllinux_* wheel for it, which is why pip falls back to source on Alpine. The base image is python:3.13-alpine3.23 (musl libc). The builder stage already has gcc, g++, musl-dev, libffi-dev, openssl-dev, cargo, python3-dev, etc. installed, so the source build does succeed — it's just slow. With the old cx-Oracle, this was a non-issue because it was installed in its own dedicated RUN pip install --no-build-isolation cx-Oracle==8.3.0 layer that Docker BuildKit cached separately, so it only rebuilt when its version changed. Now oracledb is mixed into the general pip install -r requirements.txt layer, so any change to requirements.txt re-triggers the 9-minute compile.

Question

What's the best way to avoid this 9-minute source build on every CI run?

Read Entire Article