7 poin oleh GN⁺ 2025-06-25 | 2 komentar | Bagikan ke WhatsApp
  • Beralih ke uv membuat kecepatan instalasi dependensi Python menjadi sekitar 10 kali lebih cepat dibandingkan pip, dan aplikasi juga dapat berjalan sebagai pengguna non-root tanpa venv terpisah
  • Dengan basis pyproject.toml, cukup deklarasikan dependensi tingkat atas dan uv akan mengelola file lock secara otomatis, sehingga pohon dependensi dan pengelolaan versi yang presisi lebih baik daripada pip freeze
  • Di Dockerfile, diperlukan perubahan bertahap seperti menyalin biner uv dan uvx, menggunakan file pyproject.toml/uv.lock, serta mengatur environment variable
  • Melalui perintah seperti uv sync/add/remove, uv:outdated, Anda dapat dengan mudah menambah, menghapus, memperbarui dependensi, dan memeriksa versi terbaru paket
  • Pengelolaan file lock dan pembaruan dependensi secara rutin menjadi lebih mudah, sehingga memberi keuntungan dalam menjaga konsistensi pada lingkungan kolaborasi dan deployment

Instalasi dependensi 10x lebih cepat, tanpa venv, dan konfigurasi lingkungan non-root

  • uv adalah alat yang secara signifikan meningkatkan kecepatan instalasi dependensi proyek Python dibandingkan pip
  • Dengan mengadopsi uv, berbagai proyek seperti Flask/Django dapat merasakan kecepatan instalasi sekitar 10 kali lebih cepat dibandingkan pip
  • Bahkan tanpa virtual environment (venv) terpisah, aplikasi tetap dapat berjalan dengan aman sebagai pengguna non-root di dalam container

pyproject.toml vs requirements.txt

  • Alih-alih requirements.txt, cukup tuliskan dependensi tingkat atas di file pyproject.toml dan uv akan otomatis membuat file uv.lock
    • Tambahkan entri [project] dependencies di pyproject.toml
    • Hapus requirements.txt yang lama
  • File lock milik uv mirip dengan hasil pip freeze, tetapi memiliki pohon dependensi dan informasi versi yang akurat

Perubahan konfigurasi Dockerfile

  • Gunakan dengan menyalin biner uv dan uvx ke dalam container (memakai biner Rust yang dikompilasi statis)
  • Alih-alih requirements*.txt, salin file pyproject.toml, uv.lock\*
  • Tambahkan environment variable:
    • UV_COMPILE_BYTECODE=1: melakukan precompile ke bytecode pada tahap build
    • UV_PROJECT_ENVIRONMENT="/home/python/.local": menginstal paket ke path tertentu tanpa membuat venv terpisah
  • Perintah instalasi dependensi juga diubah dari pip3-install menjadi uv-install
    • Contoh: RUN chmod 0755 bin/* && bin/uv-install

Mengelola penambahan, penghapusan, pembaruan dependensi, dan lainnya

  • Perintah uv di dalam container dapat dijalankan melalui skrip run terpisah
    • ./run deps:install: menginstal setelah image dibangun sambil mengekspor file lock ke host
    • ./run deps:install --no-build: hanya memperbarui file lock tanpa build
    • ./run uv add mypackage --no-sync: hanya memperbarui pyproject.toml dan file lock, instalasi aktual dijalankan terpisah
    • ./run uv remove mypackage --no-sync: menghapus paket
    • ./run uv:outdated: memeriksa versi terbaru dari dependensi saat ini

Tersedia video dan panduan praktik

  • Disediakan demo nyata dan contoh git diff untuk adopsi uv, penulisan pyproject.toml, perubahan Dockerfile, perintah lock/sync, penambahan/penghapusan dependensi, serta pengecekan versi terbaru
  • Diff migrasi untuk dua proyek, Flask dan Django, juga dapat dijadikan referensi

2 komentar

 
yangeok 2025-06-26

Kebetulan saya juga sedang ingin memigrasikan deployment yang sebelumnya memakai Poetry, dan ini terlihat stabil serta sederhana ^^

 
GN⁺ 2025-06-25
Komentar Hacker News
  • Perlu dicatat bahwa uv mendukung alur kerja yang langsung menggantikan pyenv, virtualenv, dan pip. Ini bukan pendekatan yang dipaksakan lewat lockfile atau pyproject.toml. Dengan perintah uv python pin <version>, file .python-version dibuat di direktori saat ini; dengan uv virtualenv, Python versi tersebut diunduh seperti pyenv lalu dibuat lingkungan virtual .venv; dengan uv pip install -r requirements.txt, paket dari requirements.txt dipasang; dan dengan uv run <command>, perintah bisa dijalankan sambil memuat variabel lingkungan dari file .env. Namun, perlu hati-hati terhadap masalah prioritas variabel lingkungan (isu terkait)

    • Fleksibilitas uv benar-benar mengagumkan. Pengalaman menyelesaikan pekerjaan yang butuh 10 menit dengan pip hanya dalam 20~30 detik dengan uv
    • Itulah tepatnya alasan mulai memakai uv. Sangat nyaman. Hanya saja kadang uv pip terasa lambat dan belum tahu penyebabnya, mungkin karena lingkungan jaringan kantor
    • Setahu saya informasi versi Python juga disimpan di pyproject.toml, jadi muncul pertanyaan apakah file .python-version benar-benar perlu
  • # Skrip untuk selalu menjamin lock file terbaru
    if ! test -f uv.lock || ! uv lock --check 2>/dev/null; then
      uv lock
    fi
    

    Pendekatan seperti ini membuat makna keberadaan lock file jadi kabur. Jika file tidak ada atau tidak valid, berarti ada masalah serius pada lock file dan sebaiknya ditangani langsung oleh orang yang paham proyek terkait. Jika tidak, tidak ada alasan menyimpan lock file. Di CI, lock file bisa terganti otomatis dan menimbulkan kebingungan

    • (Balasan penulis) Jika lock file tidak valid, ini bukan berarti diam-diam dilewati lalu dibuat file baru. Di uv lock, proses gagal dengan pesan yang jelas, lalu langsung berhenti karena errexit pada shell script. Pengalihan error di uv lock --check hanya untuk mencegah error yang sama tercetak dua kali. Jika lock file sengaja dibuat salah lalu skrip dijalankan, build akan berhenti dengan pesan error yang spesifik. Skrip juga sudah diubah menjadi if-else agar lebih jelas. Jika lock file belum ada, memang alurnya benar untuk membuat yang baru. Setelah itu tinggal dibuat dan di-commit
    • Bagian ini sudah ditangani oleh opsi uv sync --locked. Jika lock file tidak ada atau sudah kedaluwarsa, perintah akan gagal dengan jelas. Disarankan selalu melakukan build dengan opsi --locked
    • Di dunia Python, lock file sering tidak dimasukkan ke version control dan kerap diperlakukan sebagai "tahap aneh" dalam proses instalasi
    • Ada bug serius dalam cara ini. Jika memakai flag --frozen, lock file seharusnya tidak diperbarui, tetapi kenyataannya justru berjalan sebaliknya. Setuju bahwa jika lock file tidak ada atau tidak cocok, manusia harus turun tangan
    • Tetap saja, jika lock file tidak ada, itu berarti ini eksekusi pertama atau nantinya akan tertimpa dari git upstream. Kalau rusak, berarti seseorang melakukan kesalahan saat instalasi, dan menurut saya membuat ulang memang satu-satunya cara yang masuk akal. Ini pengecualian yang jarang, tapi cukup untuk penanganan sederhana
  • Saya sangat tidak setuju dengan alat Python yang dikembangkan dalam bahasa selain Python. C sudah ada dan CPython sudah distandardisasi, jadi tidak perlu bahasa baru lagi seperti Rust. Paket Pendulum terlambat lebih dari 7 bulan dalam mendukung 3.13, dan saya menduga itu karena komponen native Rust membuat orang yang bisa memperbaikinya sangat sedikit. Kalau itu C, saya mungkin akan memperbaikinya sendiri. (isu terkait) Idealnya, jika ingin membuat datetime cepat dengan bahasa eksternal seperti Rust, itu seharusnya dibuat melalui FFI dalam bentuk yang bisa dipakai banyak bahasa. Basis Rust masih terasa kurang meyakinkan, dan saya mulai paham kenapa komunitas Linux enggan terhadapnya

    • Saya menghormati sudut pandang ini, tetapi menurut saya membuat alat seperti uv dengan Rust adalah ide yang bagus. Kalau alat pengelola Python dibuat dengan Python, akan muncul situasi "ayam dulu atau telur dulu". Untuk memakai alat Python, Python sendiri harus sudah terpasang lebih dulu; lalu harus dipikirkan versi Python mana yang dipakai, kemungkinan konflik antara library yang dipakai alat dan aplikasi sebenarnya, pengelolaan variabel lingkungan, sampai debugging, semuanya jadi rumit. Sebaliknya, alat biner yang dibangun dengan Rust atau sejenisnya tinggal diunduh dan langsung dipakai, tanpa perlu memikirkan semua itu. Pengguna juga tidak terlalu peduli alat itu dibuat dengan bahasa apa
    • Saya suka Python, tetapi kemudahan dan kecepatan uv tidak bisa dibandingkan. Saat butuh Python terbaru di server yang sudah EOL, atau hanya ingin cepat memasang dependensi untuk skrip kecil, uv adalah yang terbaik. Ada bagian yang saya setujui juga: dulu saya selalu menulis pure Python, lalu pelan-pelan mulai memakai C extension, dan setelah merasakan batasnya, jadi ingin menulis hampir semuanya dalam C. Karena C sulit, belakangan saya sedang merapikan ulang ke Rust. Kalau kode eksternal sudah lebih banyak daripada kode internal, lebih baik ganti semuanya ke bahasa lain saja
    • Kalau keyakinan bahwa alat harus dibuat hanya dengan Python memang sekuat itu, saya akan pergi jalan-jalan sambil menunggu Pylint yang lambat
    • Dukungan banyak bahasa bukan beban besar bagi pengguna. Yang penting alatnya cepat dan menyelesaikan masalah dengan baik. Faktanya memang jauh lebih cepat. Alat manajemen dibuat untuk pengembang, bukan untuk target penggunaan
    • Bagi saya, tidak masalah alat dibuat dengan bahasa apa asalkan fungsinya berjalan baik. Memang ada nilai tambah karena pengguna Python bisa ikut berkontribusi ke alatnya, tetapi kalau alat itu menjalankan tugasnya dengan baik, bahasanya tidak penting. Malah saat menghadapi masalah lingkungan, alat yang dibuat dengan Python bisa ikut terkena dampaknya
  • Saat memakai uv alih-alih pip, perlu berhati-hati. Secara default uv tidak membuat file pyc, jadi startup service bisa menjadi lebih lambat (referensi)

    • Saat memakai uv di container, dokumen panduannya lebih membantu (panduan Docker)
  • Jika uv dipakai di container Flask, bukan cuma perbedaan build time-nya sangat besar sampai terasa membosankan, tetapi proses instalasinya juga jadi sangat dapat diprediksi. Tidak ada lagi kejengkelan karena versi dependensi berubah saat memakai pip. Cukup pakai pyproject.toml lalu jalankan uv lock, selesai. Di Docker, cukup salin file pyproject.toml dan uv.lock saja (HOT COPY) lalu jalankan uv sync --frozen --no-install-project, maka kode aplikasi dilewati dan layer instalasi bisa di-cache. Kalau pernah merasakan sakitnya membangun ulang seluruh layer hanya karena satu paket berubah, akan terasa kenapa fitur ini penting. Saat memakai variabel lingkungan UV_PROJECT_ENVIRONMENT=/home/python/.local, base image bisa di-pre-warm tanpa venv sehingga build bisa dibagi dan biaya infrastruktur berkurang. Dengan opsi UV_COMPILE_BYTECODE=1, file .pyc dibuat saat build. Lingkungan mutable pun hilang dan reproducibility dipaksakan; sekarang kalau build gagal, penyebabnya jelas ada di lockfile

  • Bahkan di tahun 2025, packaging dan manajemen dependensi Python masih tetap kacau

    • Menurut saya kekacauan ini terus berlanjut karena belum semua orang memakai uv
    • Ini pelajaran bahwa hal seperti ini penting disiapkan dengan benar sejak awal desain bahasa. Jangan menundanya sampai v2.0, pikirkan berkali-kali sebelum memasukkan metadata ke skrip yang dieksekusi, dan pahami bahwa pendekatan yang cocok untuk bahasa lain belum tentu bagus untuk Python
    • Saya belum pernah mengalami masalah dependensi. Cukup pakai requirements.txt dan venv saja
    • Manajemen dependensi masih berantakan, dan sekarang Rust juga ikut ditambahkan
  • Saya penasaran soal perbandingan keamanan pengelola paket Python seperti uv, pip, dan conda. Kecepatan memang bagus, tetapi menurut saya keamanan package manager jauh lebih penting

    • uv lebih aman daripada pip. Ia menganalisis dependensi tanpa eksekusi kode arbitrer, memverifikasi hash paket secara default, dan menghindari berbagai risiko seperti typosquatting. Kecepatan dan reproducibility-nya juga sangat baik (pengantar teknis, dokumen kompatibilitas)
    • Namun pada dasarnya semua package manager akan mengunduh dan menjalankan kode pihak ketiga yang belum diverifikasi. Dibanding perbedaan keamanan implementasi antara uv dan pip, risiko yang lebih penting adalah tidak adanya kebijakan atas kode eksternal sejak awal
  • Sebagai orang yang mengunggah paket ke PyPI, saya pribadi ingin memakai uv karena kecepatannya, tetapi kalau tidak ada jaminan bahwa perilakunya benar-benar sama dengan pip, saya sulit langsung beralih. Jika pengguna mengalami error saat pip install xxx, saya juga harus bisa mereproduksi dan men-debug di lingkungan yang sama

    • Perilakunya memang tidak 100% sama dengan pip. Perbedaan besar dibahas di dokumen kompatibilitas. Sebagiannya adalah perbedaan dalam proses beralih ke standar, dan sebagian lagi merupakan pilihan desain khas uv
  • Menurut saya uv adalah salah satu perubahan paling positif dalam packaging Python belakangan ini, alat yang cukup dijalankan saja lalu memberikan hasil yang baik

  • Juga diperkenalkan dokumen panduan yang sangat bagus untuk membangun container produksi dengan uv (lihat panduan)