- Beim Umstieg auf uv ist die Installation von Python-Abhängigkeiten im Vergleich zu pip etwa 10-mal schneller, und die Ausführung ist auch ohne separates venv als Nicht-Root-Benutzer möglich
- Auf Basis von pyproject.toml müssen nur die Top-Level-Abhängigkeiten angegeben werden; uv verwaltet die Lock-Datei automatisch und bietet einen präzisen Abhängigkeitsbaum sowie exakte Versionsverwaltung, die
pip freeze überlegen ist
- Im Dockerfile sind schrittweise Änderungen nötig, etwa das Kopieren der Binärdateien uv und uvx, die Nutzung von pyproject.toml-/uv.lock-Dateien sowie das Setzen von Umgebungsvariablen
- Mit Befehlen wie uv sync/add/remove, uv:outdated lassen sich Abhängigkeiten einfach hinzufügen, entfernen, aktualisieren und auf neue Paketversionen prüfen
- Durch regelmäßige Pflege der Lock-Datei und Updates von Abhängigkeiten werden Konsistenzvorteile für Zusammenarbeit und Deployment-Umgebungen erreicht
10-mal schnellere Abhängigkeitsinstallation, kein venv, Nicht-Root-Umgebung
- uv ist ein Tool, das die Installationsgeschwindigkeit von Abhängigkeiten in Python-Projekten gegenüber pip deutlich verbessert
- Mit der Einführung von uv lässt sich in verschiedenen Projekten wie Flask oder Django gegenüber pip eine etwa 10-mal schnellere Installationsgeschwindigkeit erreichen
- Auch ohne separate virtuelle Umgebung (venv) kann der Container sicher als Nicht-Root-Benutzer ausgeführt werden
pyproject.toml vs requirements.txt
- Statt der bisherigen requirements.txt-Datei werden in pyproject.toml nur die Top-Level-Abhängigkeiten angegeben; uv erzeugt dann automatisch die Datei uv.lock
- In
pyproject.toml den Eintrag [project] dependencies ergänzen
- Die bisherige
requirements.txt löschen
- Die Lock-Datei von uv ähnelt dem Ergebnis von
pip freeze, enthält jedoch einen präzisen Abhängigkeitsbaum und genaue Versionsinformationen
Änderungen am Dockerfile
- Die Binärdateien uv und uvx werden zur Nutzung in den Container kopiert (statisch kompilierte Rust-Binärdateien)
- Statt der bisherigen
requirements*.txt werden pyproject.tomlunduv.lock*` kopiert
- Zusätzliche Umgebungsvariablen:
UV_COMPILE_BYTECODE=1: Kompiliert im Build-Schritt vorab zu Bytecode
UV_PROJECT_ENVIRONMENT="/home/python/.local": Installiert Pakete in einem bestimmten Pfad, ohne ein separates venv zu erzeugen
- Auch der Befehl zur Installation von Abhängigkeiten wird von
pip3-install auf uv-install umgestellt
- Beispiel:
RUN chmod 0755 bin/* && bin/uv-install
Abhängigkeiten hinzufügen, entfernen, aktualisieren und verwalten
- Über ein separates Run-Skript können uv-Befehle im Container ausgeführt werden
./run deps:install: Installiert nach dem Image-Build und exportiert dabei die Lock-Datei auf den Host
./run deps:install --no-build: Aktualisiert nur die Lock-Datei ohne neuen Build
./run uv add mypackage --no-sync: Aktualisiert nur pyproject.toml und die Lock-Datei, die eigentliche Installation erfolgt separat
./run uv remove mypackage --no-sync: Entfernt ein Paket
./run uv:outdated: Prüft die aktuellsten Versionen der derzeitigen Abhängigkeiten
Video- und Praxisleitfaden verfügbar
- Es werden reale Demos und git-diff-Beispiele zu uv-Einführung, Erstellung von
pyproject.toml, Änderungen am Dockerfile, Lock-/Sync-Befehlen, Hinzufügen/Entfernen von Abhängigkeiten und Versionsprüfung bereitgestellt
- Zusätzlich sind die Migrations-Diffs für Flask- und Django-Projekte als Referenz verfügbar
2 Kommentare
Ich wollte ohnehin von einer mit Poetry bereitgestellten Umgebung migrieren, und das wirkt stabil und einfach^^
Hacker-News-Kommentare
Es ist wichtig zu beachten, dass uv einen Workflow unterstützt, der
pyenv,virtualenvundpipdirekt ersetzt. Es ist nicht auf eine durch Lockfile oderpyproject.tomlerzwungene Arbeitsweise beschränkt. Mit dem Befehluv python pin <version>wird im aktuellen Verzeichnis eine.python-version-Datei erstellt, mituv virtualenvwird wie bei pyenv die entsprechende Python-Version heruntergeladen und eine.venv-Umgebung erzeugt, mituv pip install -r requirements.txtwerden die Pakete ausrequirements.txtinstalliert, und mituv run <command>kann ein Befehl einschließlich der Umgebungsvariablen aus der.env-Datei ausgeführt werden. Man sollte jedoch auf Probleme bei der Priorität von Umgebungsvariablen achten (zugehöriges Issue)uv piplangsam ist, und ich weiß nicht warum; vielleicht liegt es an der Netzwerkumgebung in unserem Unternehmenpyproject.tomlgespeichert, daher frage ich mich, ob eine.python-version-Datei wirklich nötig istSo ein Ansatz entwertet den Sinn eines Lockfiles. Wenn die Datei fehlt oder ungültig ist, liegt ein ernsthaftes Problem mit dem Lockfile vor, und idealerweise sollte sich jemand darum kümmern, der mit dem betreffenden Projekt vertraut ist. Andernfalls gibt es keinen Grund, überhaupt ein Lockfile zu haben. In CI kann es zu Verwirrung führen, wenn das Lockfile automatisch ersetzt wird
uv lockschlägt mit einer hilfreichen Meldung fehl, und durcherrexitim Shell-Skript wird sofort abgebrochen. Die Fehlerumleitung beiuv lock --checkdient nur dazu, zu verhindern, dass derselbe Fehler zweimal ausgegeben wird. Wenn man das Lockfile absichtlich kaputt macht und dann das Skript ausführt, stoppt der Build mit einer konkreten Fehlermeldung. Das Skript wurde zur besseren Verständlichkeit aufif-elseumgestellt. Wenn kein Lockfile vorhanden ist, ist es der richtige Ablauf, ein neues zu erzeugen. Dann erstellt man es und committet esuv sync --lockedabgedeckt. Wenn das Lockfile fehlt oder veraltet ist, schlägt es eindeutig fehl. Ich würde vorschlagen, Builds immer mit der Option--lockedauszuführen--frozensollte das Lockfile eigentlich nicht aktualisiert werden, in der Praxis verhält es sich aber umgekehrt. Ich stimme zu, dass bei fehlendem oder nicht passendem Lockfile ein Mensch eingreifen sollteIch bin grundsätzlich dagegen, dass Python-Tools in einer anderen Sprache als Python entwickelt werden. Es gibt bereits C, und CPython ist standardisiert, daher braucht es nicht noch eine neue Sprache wie Rust. Das Paket Pendulum hat die Unterstützung für 3.13 mehr als sieben Monate verspätet ausgeliefert, und ich vermute, dass das daran lag, dass wegen des nativen Rust-Anteils zu wenige Leute wussten, wie man das Problem behebt. Wäre es C gewesen, hätte ich es selbst repariert. (zugehöriges Issue) Im Idealfall sollte man, wenn man ein schnelles
datetimein einer externen Sprache wie Rust bauen will, es per FFI in einer Form bereitstellen, die von mehreren Sprachen genutzt werden kann. Auf Rust basierende Lösungen sagen mir noch nicht wirklich zu, und ich verstehe inzwischen auch, warum die Linux-Community dem skeptisch gegenüberstehtWenn man statt pip uv verwendet, sollte man vorsichtig sein. Standardmäßig werden keine
.pyc-Dateien erzeugt, weshalb der Start eines Dienstes langsamer sein kann (Hinweis)Wenn man uv in einem Flask-Container verwendet, ist der Unterschied bei der Build-Zeit nicht nur groß genug, um langweilig zu wirken, sondern der Installationsprozess wird auch sehr vorhersehbar. Mit pip gibt es nicht mehr diese frustrierenden Versionsänderungen bei Abhängigkeiten. Man nutzt
pyproject.toml, führtuv lockaus, und das war’s. In Docker kopiert man nurpyproject.tomlunduv.lock(HOT COPY) und führtuv sync --frozen --no-install-projectaus; dadurch wird der App-Code übersprungen und die Installationsschicht kann gecacht werden. Wer den Schmerz kennt, wenn schon bei der Änderung nur eines Pakets die gesamte Schicht neu gebaut werden muss, versteht, warum das wichtig ist. Wenn man mit der UmgebungsvariablenUV_PROJECT_ENVIRONMENT=/home/python/.localdas Basis-Image ohne venv vorwärmt, lassen sich Builds gemeinsam nutzen und Infrastrukturkosten sparen. Mit der OptionUV_COMPILE_BYTECODE=1werden beim Build.pyc-Dateien erzeugt. Veränderliche Umgebungen verschwinden und Reproduzierbarkeit wird erzwungen; wenn der Build jetzt fehlschlägt, ist dank des Lockfiles die Ursache eindeutigAuch im Jahr 2025 bleiben Python-Paketierung und Abhängigkeitsverwaltung weiterhin chaotisch
requirements.txtundvenvreichen völlig ausMich würde ein Vergleich der Sicherheit von Python-Paketmanagern wie uv, pip und conda interessieren. Geschwindigkeit ist gut, aber die Sicherheit eines Paketmanagers ist viel wichtiger
Da ich selbst Pakete auf PyPI veröffentliche, würde ich uv wegen seiner Geschwindigkeit zwar gern verwenden, aber wenn es keine Garantie gibt, dass es sich exakt wie pip verhält, kann ich nicht so leicht umsteigen. Wenn Nutzer bei
pip install xxxeinen Fehler erleben, muss ich ihn in derselben Umgebung reproduzieren und debuggen könnenIch denke, uv ist eine der positivsten Veränderungen im neueren Python-Packaging: einfach ausführen und man bekommt gute Ergebnisse
Es wird auch eine hervorragende Anleitung zur Verwendung von uv für Produktionscontainer empfohlen (Guide ansehen)