Preskoči na glavni sadržaj
Python alati2026-11-01 · 11 min čitanja

Docker za Python u 2026.: Moderni UV + Vodič za izgradnju u više faza

Otvorite bilo koji vodič "Dockerize your Python app" star pet godina i pronaći ćete ista četiri retka: FROM python:3.11-slim, COPY requirements.txt ., RUN pip install -r requirements.txt, COPY . .. Djeluje. Također isporučuje sliku od više od 200 MB, obnavlja se sporo jer je svaka instalacija ovisnosti puna predmemorija koja propušta trenutak promjene jedne linije koda aplikacije i tiho uvlači C kompajler i datoteke zaglavlja koje vaš pokrenuti spremnik više nikada neće dodirnuti nakon završetka izgradnje.

Ništa od toga više nije potrebno. Između uv (upravitelj paketa temeljen na Rustu i instalacijski program iz Astrala), BuildKit predmemorija za montiranje i osnovne slike bez distribucije, zadana vrijednost 2026 za produkcijski Python spremnik je višestupanjska izrada koja isporučuje samo Python interpreter, vaše virtualno okruženje i vaš kod, ništa drugo. Ovaj vodič prolazi kroz stari obrazac, novi obrazac i Dockerfile koji možete kopirati u pravi projekt danas.

Stari obrazac i zašto je skup

DOCKERFILE
FROM python:3.13-slim WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["python", "app.py"]

Ovaj obrazac ima tri troška koja se povećavaju kako projekt raste. Prvo, python:3.13-slim se već isporučuje s otprilike 150 do 200 MB komprimiranim prije nego što dodate jednu ovisnost, jer "slim" još uvijek nosi punu korisničku zemlju Debiana, apt i C ekstenzije Python standardne biblioteke. Drugo, svaki sloj RUN pip install je predmemoriran Dockerovim hashom sadržaja prethodnih slojeva, tako da se mijenja jedan redak u app.py prije COPY. . ne poništava ništa uzvodno, ali promjena u requirements.txt` poništava cijeli korak instalacije i ponovno preuzima svaki kotačić. Treće, ako bilo koja ovisnost treba nativnu izgradnju (nedostajući kotačić manylinux, neobična verzija paketa), pip tiho uvlači alate za izgradnju koji zatim zauvijek ostaju u konačnoj slici, jer postoji samo jedna faza u koju se može baciti.

Novi obrazac: UV builder faza plus distroless final stage

Popravak je izgradnja u više faza: jedna faza koja ima kompajler, uv i vašu datoteku zaključavanja, a druga, mnogo manja faza koja samo kopira gotovo virtualno okruženje i vaše izvorno stablo. Završna faza nikada ne vidi pip, uv, apt ili C kompajler.

DOCKERFILE
FROM python:3.13-slim AS builder COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy UV_PYTHON_DOWNLOADS=never WORKDIR /app RUN --mount=type=cache,target=/root/.cache/uv \ --mount=type=bind,source=uv.lock,target=uv.lock \ --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ uv sync --frozen --no-install-project --no-dev COPY . /app RUN --mount=type=cache,target=/root/.cache/uv uv sync --frozen --no-dev FROM gcr.io/distroless/python3-debian12 COPY --from=builder /app /app WORKDIR /app ENV PATH="/app/.venv/bin:$PATH" ENTRYPOINT ["/app/.venv/bin/python", "-m", "app"]

gcr.io/distroless/python3-debian12 nema ljusku, nema upravitelja paketima niti pip, što je upravo ono što želite u produkciji: u spremniku nije ostalo ništa što bi napadač koji dobije izvršenje koda mogao upotrijebiti za uvlačenje dodatnih alata. Konačna slika su paketi web-mjesta vašeg virtualnog okruženja plus vaš kod, koji za tipičnu FastAPI uslugu ima ispod 50 MB umjesto više od 200 MB.

Montaže BuildKit predmemorije: nikada ne preuzimajte isti kotač dva puta

Redak --mount=type=cache,target=/root/.cache/uv ovdje radi pravi posao. Bez toga, svaka docker build na novom pokretaču ponovno preuzima svaki kotačić iz PyPI-ja, jer predmemorija slojeva preživljava samo ako su prethodni slojevi, uključujući COPY uv.lock, identični u bajtu. Montaža predmemorije BuildKit je trajni volumen izvan grafikona slojeva: on preživljava među nadogradnjama na istom hostu ili, s pozadinom predmemorije registra, među CI pokretačima, čak i kada se datoteka zaključavanja promijeni. Uparite ga s uv sync --frozen, koji odbija dodirnuti zaključanu datoteku i glasno otkazuje ako pyproject.toml i uv.lock nisu sinkronizirani, umjesto tihog rješavanja različitog stabla ovisnosti od onog protiv kojeg su se izvodili vaši testovi.

Odvajanje koraka uv sync --no-install-project od konačnog uv sync druga je polovica trika: prvi poziv instalira samo ovisnosti treće strane (spremljene u predmemoriju sve dok se uv.lock ne promijeni), a drugi poziv, pokrenite nakon COPY. /app, instalira vaš vlastiti projekt bez ponovnog dodirivanja paketa trećih strana. Promijenite jedan redak koda aplikacije i sloj ovisnosti ostaje predmemoriran.

Izvorne ovisnosti: numpy, pillow i problem s manylinuxom

Paketi kao što su numpy i Pillow isporučuju unaprijed izgrađene kotače za mnoge linux za uobičajene platforme, tako da na linux/amd64 ili linux/arm64 uv sync obično samo preuzima kotačić i nikad ne dodiruje kompajler. Način neuspjeha pojavljuje se kada ste na neuobičajenoj arhitekturi, prikvačite vrlo novo izdanje prije nego što vas kotači sustignu ili ovisite o paketu koji isporučuje samo izvornu distribuciju. U tom slučaju faza izgradnje treba alate za izgradnju, a završna faza nikada ne smije vidjeti:

DOCKERFILE
FROM python:3.13-slim AS builder RUN apt-get update && apt-get install -y --no-install-recommends build-essential \ && rm -rf /var/lib/apt/lists/* # uv + sync steps as in the stage above

build-essential (gcc, make, libc zaglavlja) postoji samo u fazi izgradnje. Završna faza bez distribucije kopira već kompajlirani .venv, a ne kompilator koji ga je napravio. Ako želite vježbati izgradnju i isporuku stvarne kontejnerske usluge od kraja do kraja, tečaj FastAPI prolazi kroz upravo ovu vrstu API-ja, od prve krajnje točke do implementacije u obliku proizvodnje.

Python upravljan uv-om: prestanite ovisiti o interpretatoru koji je osnovna slika poslana

python:3.13-slim daje vam ono izdanje zakrpe koje je Debian odlučio poslati tog tjedna. uv može upravljati samim tumačem umjesto toga: uv python install 3.13.1 preuzima specifičnu, reproducibilnu CPython verziju iz python-build-standalone projekta i pričvršćuje je u .python-version, tako da vaša faza izgradnje i vaše prijenosno računalo pokreću potpuno isti tumač do verzije zakrpe. U kombinaciji s UV_PYTHON_DOWNLOADS=never u Docker datoteci, tako da krivo prikvačena verzija glasno otkazuje izgradnju umjesto da tiho preuzme nešto drugo, ovo zatvara prazninu "radi na mom stroju, ne uspijeva na pokretaču" koju plutajuća oznaka osnovne slike ostavlja otvorenom.

Otklanjanje pogrešaka u spremniku bez ljuske

Jedina stvarna cijena distrolessa: nema ljuske, pa docker exec -it container sh ne radi. Za lokalno otklanjanje pogrešaka, izgradite istu Dockerfile s ciljem koji se zaustavlja u fazi izgradnje (docker build --target=builder -t myapp:debug .), koja još uvijek ima python:3.13-slim puno korisničko područje i ljusku. Držite taj cilj otklanjanja pogrešaka izvan svog cjevovoda za implementaciju; postoji za vaš terminal, ne za proizvodnju.

Predložak s jednom datotekom

DOCKERFILE
FROM python:3.13-slim AS builder COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy UV_PYTHON_DOWNLOADS=never WORKDIR /app RUN --mount=type=cache,target=/root/.cache/uv \ --mount=type=bind,source=uv.lock,target=uv.lock \ --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ uv sync --frozen --no-install-project --no-dev COPY . /app RUN --mount=type=cache,target=/root/.cache/uv uv sync --frozen --no-dev FROM gcr.io/distroless/python3-debian12 COPY --from=builder /app /app WORKDIR /app ENV PATH="/app/.venv/bin:$PATH" ENTRYPOINT ["/app/.venv/bin/python", "-m", "app"]

Kopirajte ovo, promijenite naziv modula ENTRYPOINT kako bi odgovarao vašem izgledu projekta, i dobit ćete međugradnju koja je manja, brža pri ponovljenim verzijama i teža za napad od uzorka pip install -r requirements.txt koji većina tutorijala još uvijek podučava. Jeste li spremni vježbati pozadinu koja se nalazi unutar ovog spremnika? Počni s FastAPI.

FAQ

Trebam li BuildKit biti omogućen da bi montiranje predmemorije radilo?

Da, --mount=type=cache značajka je samo BuildKita. Bio je zadani program za izgradnju u Docker Desktopu i nedavnim izdanjima Docker Enginea, ali na starijim CI runnerima možda ćete morati eksplicitno postaviti DOCKER_BUILDKIT=1 ili docker buildx build umjesto običnog docker build.

Zašto jednostavno ne upotrijebite python:3.13-alpine za manju sliku?

Alpineov musl libc razbija pretpostavku o kotačima mnogih linuxa na koje se oslanjaju numpy, Pillow i većina kompiliranih paketa, tako da gubite unaprijed izgrađene kotače i ili kompajlirate iz izvora ili naiđete na suptilne greške u vremenu izvođenja. distroless-glibc izbjegava tu zamku.

Zamjenjuje li uv u potpunosti pip i Poetry?

Za većinu novih projekata, da. uv rješava i instalira brže, čita isti pyproject.toml i generira zaključanu datoteku, ali ako tim već ovisi o Poetry dodacima ili tijek rada koji uv još ne pokriva, nema hitnosti za migraciju usred projekta. Prvo isprobajte UV na novoj usluzi.

Što ako moja osnovna slika treba sigurnosnu zakrpu nakon što sam već napravio sliku?

Ponovo izgraditi. Prikvačite sažetak, a ne samo oznaku, za python:3.13-slim u fazi izgradnje i ponovna izgradnja prema rasporedu, tjedno je razumno za većinu timova, tako da zakrpana osnovna slika teče u novu verziju umjesto da mjesecima stoji ustajala.

Mogu li koristiti ovaj uzorak za Django projekt umjesto FastAPI-ja?

Da, Dockerfile ne zanima koji okvir pokrećete; mijenja se samo konačna ENTRYPOINT (na primjer gunicorn myproject.wsgi:application). FastAPI tečaj brz je način vježbanja uzorka od početka do kraja ako pokrećete novu uslugu.

Je li spremna za proizvodnju bez distribucije ili je još uvijek eksperimentalna?

Široko se koristi u proizvodnji; Google ga održava i mnogi ga timovi šalju kao svoju zadanu bazu Pythona. Kompromis za prihvaćanje ulaska je nedostatak ljuske, što je namjeran sigurnosni izbor, a ne greška.

Jeste li spremni isprobati?

15 besplatne lekcije nakon besplatne prijave — bez kartice. Isprobajte platformu, a zatim odlučite.

Počni besplatno →

Or unlock every lesson

Pro — $12/mo, unlimited AI, cancel any time. Refund within 14 days worldwide.

See Pro plans →

Get one Python lesson + one career idea every Friday

No spam, no "buy our course now". Three bullets, every Friday. Unsubscribe with one click.