Bij het implementeren van Python-toepassingen in een Docker-omgeving, ervaart men vaak dat de buildtijd van de afbeeldingen te lang duurt of dat de build mislukt door afhankelijkheidsproblemen met de compiler, zoals gcc. Een van de meest effectieve oplossingen in dit geval is het gebruik van Python Wheel.

In dit artikel bespreken we het concept en de voordelen van Python Wheel, en hoe we dit in een Dockerfile kunnen gebruiken om het buildproces te optimaliseren.


1. Wat is Python Wheel?



Wheel (.whl) is het binair distributieformaat (Built Distribution) van Python.

Gewoonlijk worden Python-pakketten in twee vormen verspreid.

  1. Bronverspreiding (sdist, .tar.gz): Dit is de vorm van de broncode. Tijdens de installatie is een compilatieproces op de computer van de gebruiker nodig.

  2. Binaire distributie (bdist_wheel, .whl): Dit is de voorgecompileerde binaire vorm. De installatie wordt voltooid door eenvoudigweg de bestanden te kopiëren, zonder verdere compilatie.

Om het eenvoudig te stellen: een bronverspreiding is als 'meubels die in elkaar gezet moeten worden', terwijl Wheel als 'voltooid meubel' is. Met Wheel is er geen tijd en gereedschap (compiler) nodig voor montage.


2. Verschil met reguliere pip install

Wanneer we de pip install <package> opdracht uitvoeren, werkt het intern volgens de volgende prioriteit.

  1. Wanneer een Wheel-bestand aanwezig is: Het bijbehorende binaire bestand wordt gedownload en onmiddellijk geïnstalleerd. (zeer snel)

  2. Wanneer er geen Wheel-bestand is: De bronbestanden (tar.gz) worden gedownload, waarna de compilatie lokaal wordt uitgevoerd. (langzaam, compilatietools zijn nodig)

Samenvatting van de verschillen

Typen Bronverspreiding (sdist) Wheel (whl)
Extensie .tar.gz, .zip .whl
Installatieproces Downloaden -> compileren -> installeren Downloaden -> installeren
Installatiesnelheid Langzaam (compilatietijd vereist) zeer snel
Nodige tools Compilers (gcc, g++, headerbestanden, enz.) Geen (alleen pip is nodig)
OS-afhankelijkheid Afhankelijk van de omgeving op het moment van compilatie Afhankelijk van het gebouwde OS/architectuur

3. Waarom Wheel gebruiken in de Dockerfile (voordelen)



Bij het gebruik van Wheel in een Docker-omgeving, met name in een Multi-stage Build, zijn er duidelijke voordelen:

  1. Exponentiële verbetering van de buildsnelheid: U hoeft zware bibliotheken zoals pandas en numpy, die in C/C++ zijn geschreven, niet telkens te compileren.

  2. Verlaging van de afbeeldingsgrootte: De uiteindelijke uitvoerafbeelding (Runtime Image) hoeft geen zware compilatietools zoals gcc of build-essential te bevatten.

  3. Verhoogde stabiliteit: Dit voorkomt dat de build mislukt door netwerkwijzigingen of tijdelijke storingen in externe opslagplaatsen, en biedt de mogelijkheid om lokaal voorgecompileerde bestanden te gebruiken.


4. Schrijven en gebruiken van de Dockerfile

Een Docker-build met behulp van Wheel verloopt voornamelijk door in de Builder-fase Wheel-bestanden te genereren en deze in de Final-fase te installeren.

Voorbeeld: Dockerfile met Multi-stage Build

Hieronder staat een patroon voor het efficiënt installeren van een pakket met afhankelijkheden van C-bibliotheken.

# [Fase 1] Builder: Maak de Wheel-bestanden
FROM python:3.9-slim as builder

# Vereiste pakketten voor compilatie installeren (niet opgenomen in de uiteindelijke afbeelding)
RUN apt-get update && apt-get install -y \
    build-essential \
    gcc \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app

# Kopieer requirements.txt
COPY requirements.txt .

# Genereer .whl-bestanden in de /wheels-directory met de pip wheel-opdracht
# -w: geef het pad op waar de wheel-bestanden moeten worden opgeslagen
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /app/wheels -r requirements.txt


# [Fase 2] Final: Uitvoerafbeelding
FROM python:3.9-slim

WORKDIR /app

# Kopieer alleen de Wheel-bestanden die in de Builder-fase zijn gemaakt
COPY --from=builder /app/wheels /wheels
COPY --from=builder /app/requirements.txt .

# Paketten installeren met behulp van Wheel-bestanden
# --no-index: negeer de PyPI-index en zoek alleen lokale bestanden
# --find-links: Geef het pad op waar te zoeken naar te installeren pakketten
RUN pip install --no-cache --no-index --find-links=/wheels -r requirements.txt \
    && rm -rf /wheels

# Kopieer de applicatiecode
COPY . .

CMD ["python", "main.py"]

Uitleg van belangrijke opdrachten

  • pip wheel: Genereert de .whl-bestanden die geschikt zijn voor de omgeving zonder de pakketten te installeren.

  • --wheel-dir: De locatie waar de gegenereerde Wheel-bestanden worden opgeslagen.

  • --find-links=/wheels: Geeft aan dat in plaats van pakketten van de PyPI-server (internet) te downloaden, de opdracht alleen naar het opgegeven lokale pad moet zoeken.


Tot slot

Het gebruik van Python Wheel voor Docker-builds is niet zozeer een keuze, maar eerder een essentiële optimalisatietechniek. Vooral in omgevingen met repetitieve builds in de CI/CD-pijplijn kan het verkorten van de buildtijd en het verminderen van de afbeeldingsgrootte aanzienlijke kostenbesparingen opleveren.

Als uw huidige Dockerfile het installatieproces van gcc bevat, overweeg dan om over te schakelen naar een multi-stage build met Wheel.

python-wheel-concept-image