Python ile ciddi bir proje geliştiren herkes eninde sonunda aynı duvara toslar: bir projede Django 4.2, diğerinde Django 5.1 gerekir; biri requests kütüphanesinin eski bir sürümüne bağımlıyken diğeri en güncelini ister. Bütün bu paketleri sistemin genel Python'ına kurmaya kalkarsanız, kısa sürede birbiriyle çakışan sürümlerin, "dün çalışıyordu bugün çalışmıyor" hatalarının ve tamiri saatler alan bozuk kurulumların içinde bulursunuz kendinizi. İşte tam bu kaosun panzehiri, Python'ın kendi standart kütüphanesiyle gelen venv modülüdür.
Bu rehberde sanal ortamların neden vazgeçilmez olduğunu, venv ile bir ortamı nasıl oluşturup etkinleştireceğinizi, pip ile paketleri nasıl kurup listeleyeceğinizi ve requirements.txt sayesinde projenizi bir sunucudan diğerine sorunsuz taşıyacağınızı adım adım göreceğiz. Modern dağıtımların getirdiği PEP 668 "externally-managed-environment" uyarısını, komut satırı araçları için pipx yaklaşımını ve nihayetinde bir uygulamayı Gunicorn ile systemd üzerinde yayına almayı da ele alacağız. Komut satırına aşina değilseniz önce Linux temel komutlar yazımıza göz atmanızı öneririz.
Sistem Python'ını Neden Kirletmemelisiniz?#
Ubuntu, Debian, AlmaLinux gibi sunucu dağıtımlarında Python yalnızca sizin projeleriniz için değil, işletim sisteminin kendi araçları için de kritiktir. Paket yöneticisinden ağ yapılandırma araçlarına kadar pek çok sistem bileşeni belirli Python sürümlerine ve belirli kütüphane sürümlerine bağımlıdır. Siz sudo pip install ile sistem Python'ına gelişigüzel paket kurduğunuzda, bu bileşenlerin altındaki zemini kaydırma riski taşırsınız. Yanlış bir sürüm yükseltmesi, sunucunun apt komutunu bile çalıştıramaz hâle gelmesine yol açabilir.
İkinci ve en yaygın sorun bağımlılık çakışmasıdır. Diyelim ki A projeniz flask==2.0, B projeniz flask==3.0 istiyor. Her ikisini de sistem geneline kurmaya çalıştığınızda ikincisi birincisini ezer ve A projeniz sessizce bozulur. Sanal ortam bu sorunu kökünden çözer: her proje kendi izole klasöründe, kendi Python yorumlayıcısına yönelik sembolik bağlantı ve kendi site-packages dizini ile yaşar. Bir ortamdaki paket, diğerini asla göremez.
Modern dağıtımlar bu tehlikeyi o kadar ciddiye alır ki, artık PEP 668 standardıyla sistem Python'ına doğrudan pip install yapmayı varsayılan olarak engeller. Karşınıza şuna benzer bir hata çıkar:
error: externally-managed-environment
× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
python3-xyz. If you wish to install a non-Debian-packaged
Python package, create a virtual environment...
Bu mesaj bir arıza değil, bir korumadır. Size açıkça "sistem geneline kurma, bir sanal ortam oluştur" der. Bazı kaynaklarda bu uyarıyı --break-system-packages bayrağıyla geçmeniz önerilir; ismindeki "break" (kır) kelimesi tesadüf değildir ve bir üretim sunucusunda bundan kaçınmalısınız. Doğru cevap her zaman bir sanal ortamdır.
venv ile Sanal Ortam Oluşturmak#
venv, Python 3.3'ten beri standart kütüphanenin bir parçasıdır; yani ayrı bir şey kurmanıza gerek yoktur. Bazı Debian/Ubuntu sistemlerinde yalnızca ilgili paketin ayrıca yüklenmesi gerekebilir:
# Debian/Ubuntu üzerinde venv desteği
sudo apt update
sudo apt install python3-venv python3-pip
Bir sanal ortam oluşturmak tek satırlık bir iştir. Genellikle projenizin kök dizinine geçip ortamı orada, .venv adıyla oluşturmak yaygın bir konvansiyondur:
# Proje dizinine geç
cd ~/projeler/benim-uygulamam
# .venv adında bir sanal ortam oluştur
python3 -m venv .venv
Bu komut, proje kökünüzde .venv/ adında bir klasör yaratır. İçinde Python yorumlayıcısına bir bağlantı (bin/python), ortama özel bir pip ve bu ortama kurulacak paketlerin gideceği boş bir lib/pythonX.Y/site-packages/ dizini bulunur. Bu klasörün tamamı taşınabilir olmadığından, sürüm kontrolüne dahil edilmemelidir — proje deposunda .gitignore dosyanıza .venv/ satırını eklemeyi unutmayın. Git'e yeni başlıyorsanız Git temelleri rehberimiz bu noktada işinize yarar.
Ortamı etkinleştirmek için işletim sistemine göre değişen bir activate betiği çalıştırılır:
# Linux / macOS
source .venv/bin/activate
# Windows (PowerShell)
.venv\Scripts\Activate.ps1
Etkinleştirdiğinizde komut satırı isteminizin başına (.venv) etiketi eklenir. Bu, artık python ve pip yazdığınızda sistemdekinin değil, ortamınızın içindekinin çalışacağı anlamına gelir. Doğrulamak için şu iki komut altın standarttır:
which python # .../projeler/benim-uygulamam/.venv/bin/python döndürmeli
python --version
İşiniz bittiğinde ortamdan çıkmak için tek kelime yeterlidir:
deactivate
Bir ortamı tamamen silmek istediğinizde ise özel bir kaldırma komutu yoktur; klasörü silmek yeterlidir. Bu, sanal ortamların en zarif yönlerinden biridir — bozulan bir ortamı rm -rf .venv ile yok edip yeniden oluşturmak dakikalar sürer ve sisteme hiçbir iz bırakmaz.
pip ile Paket Kurma ve Yönetme#
Ortamınız etkinken pip, Python paket indeksinden (PyPI) kütüphane kurmanın standart aracıdır. Temel kullanım son derece sezgiseldir:
# Tek paket kurma
pip install requests
# Belirli bir sürümü sabitleme
pip install "django==5.1.4"
# Sürüm aralığı belirtme (5.x ama 6'dan küçük)
pip install "django>=5.0,<6.0"
# Kurulu bir paketi güncelleme
pip install --upgrade requests
# Bir paketi kaldırma
pip uninstall requests
Sürüm sabitlerken tek eşittir (=) değil, çift eşittir (==) kullanıldığına dikkat edin — bu Python'a yeni geçenlerin sık yaptığı bir hatadır. Kurulu paketleri ve bağımlılık ağacını incelemek için de kullanışlı komutlar vardır:
# Ortamda kurulu tüm paketleri listele
pip list
# Belirli bir paketin detaylarını, nereye kurulduğunu ve
# hangi paketlerin ona bağımlı olduğunu gör
pip show django
# Güncellenebilir paketleri listele
pip list --outdated
Aşağıdaki tablo, günlük çalışmada en sık ihtiyaç duyacağınız pip komutlarını bir arada özetliyor:
| Amaç | Komut |
|---|---|
| Paket kur | pip install paket |
| Belirli sürüm kur | pip install "paket==1.2.3" |
| Güncelle | pip install -U paket |
| Kaldır | pip uninstall paket |
| Kurulu paketleri listele | pip list |
| Dosyadan toplu kurulum | pip install -r requirements.txt |
| Kurulu paketleri dosyaya dök | pip freeze > requirements.txt |
Küçük bir ipucu: pip'in kendisi de bir pakettir ve zaman zaman kendini güncellemenizi ister. Yeni bir ortam oluşturduğunuzda ilk iş olarak pip install --upgrade pip çalıştırmak, sonradan çıkabilecek uyumluluk uyarılarının önüne geçer.
requirements.txt ile Taşınabilir Bağımlılıklar#
Projenizi başka bir bilgisayara, bir ekip arkadaşınıza ya da bir üretim sunucusuna taşırken, hangi paketlerin hangi sürümlerle kurulu olduğunu elle hatırlamaya çalışmak sürdürülemez. requirements.txt dosyası tam da bu sorunu çözer: projenizin bağımlılıklarının kesin bir listesini, sürümleriyle birlikte tutan düz metin bir dosyadır.
Mevcut ortamınızın tam bir görüntüsünü almak için pip freeze kullanılır:
# Ortamdaki tüm paketleri sürümleriyle dosyaya yaz
pip freeze > requirements.txt
Oluşan dosyanın içeriği şuna benzer; her satır bir paketi ve tam sürümünü sabitler:
Django==5.1.4
gunicorn==23.0.0
psycopg2-binary==2.9.10
python-dotenv==1.0.1
requests==2.32.3
Başka bir makinede aynı ortamı birebir yeniden kurmak artık tek komuttur. Yeni bir sanal ortam oluşturup etkinleştirdikten sonra:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Bu üç satır, projenizin çalışması için gereken her şeyi eksiksiz kurar. İşte "benim makinemde çalışıyordu" sendromunun ilacı budur: sürümler sabitlendiği için farklı makinelerde farklı davranış riski ortadan kalkar.
Uygulamada requirements.txt yönetiminin iki yaygın yaklaşımı vardır. Bazı ekipler pip freeze çıktısını olduğu gibi kullanır ve her paketin tam sürümünü kilitler. Bazıları ise dosyayı elle sade tutar; yalnızca doğrudan kullandıkları üst düzey paketleri (örneğin Django ve gunicorn) yazar, alt bağımlılıkları pip'in çözmesine bırakır. Geliştirme ile üretim bağımlılıklarını ayırmak için requirements-dev.txt gibi ikinci bir dosya tutmak da yaygın ve temiz bir düzendir:
# Sadece üretim bağımlılıkları
pip install -r requirements.txt
# Test/geliştirme araçlarını da ekle
pip install -r requirements-dev.txt
Hangi yaklaşımı seçerseniz seçin, altın kural değişmez: requirements.txt sürüm kontrolüne eklenir, .venv/ klasörü ise eklenmez. Böylece depoya bakan herkes bağımlılıkları görür ama herkesin kendi izole ortamı olur.
pipx ile Komut Satırı Araçlarını İzole Etmek#
Bazı Python paketleri kütüphane değil, doğrudan komut satırından çalıştırdığınız araçlardır: black (kod biçimlendirici), httpie (HTTP istemcisi), poetry, csvkit gibi. Bunları sisteminizin her yerinden çağırmak istersiniz ama tek bir projeye bağlı bir sanal ortama hapsetmek mantıksızdır. İşte pipx bu senaryo için tasarlanmıştır.
pipx, kurduğu her aracı kendi gizli sanal ortamına yerleştirir, ardından yalnızca çalıştırılabilir komutunu sisteminizin PATH'ine bağlar. Böylece araç izole kalır ama her yerden erişilebilir olur; üstelik PEP 668 uyarısıyla da hiç karşılaşmazsınız:
# pipx kurulumu (Debian/Ubuntu)
sudo apt install pipx
pipx ensurepath
# Bir aracı global olarak kullanılabilir yap
pipx install black
pipx install httpie
# Kurulu araçları listele
pipx list
# Bir aracı güncelle veya kaldır
pipx upgrade black
pipx uninstall black
Kısaca ayrımı şöyle hatırlayın: bir paketi projenizin kodu içinden import ederek kullanacaksanız o proje .venv'ine pip install ile kurun; bir paketi terminalden komut olarak çalıştıracaksanız pipx install ile sistem geneline izole şekilde kurun. Bu iki alışkanlığı ayırdığınızda hem projeleriniz temiz kalır hem de sık kullandığınız araçlar her an elinizin altında olur.
Gunicorn ve systemd ile Sunucuya Dağıtım#
Yerelde python manage.py runserver ya da Flask'ın geliştirme sunucusu iş görür, ancak bunlar üretim için tasarlanmamıştır — tek iş parçacıklıdır ve yük altında güvenli değildir. Üretimde bir WSGI uygulama sunucusu olan Gunicorn devreye girer. Önce Gunicorn'u projenizin sanal ortamına kurup requirements.txt'e ekleyin:
source .venv/bin/activate
pip install gunicorn
pip freeze > requirements.txt
Uygulamanızı elle test etmek için Gunicorn'u doğrudan çalıştırabilirsiniz. Django için WSGI giriş noktası genellikle <projeadi>.wsgi:application biçimindedir:
gunicorn --workers 3 --bind 127.0.0.1:8000 benim_projem.wsgi:application
Sunucuyu yeniden başlattığınızda uygulamanın kendiliğinden ayağa kalkması ve çökerse yeniden başlaması için bu süreci bir systemd servisi hâline getirmek en sağlam yöntemdir. /etc/systemd/system/benim-uygulamam.service dosyasını şu şekilde oluşturun. Dikkat edin: ExecStart satırındaki gunicorn yolu, sistemin genelini değil sanal ortamınızın içindeki ikili dosyayı işaret eder — sanal ortam mantığı üretimde de aynen sürer:
[Unit]
Description=Benim Python Uygulamam (Gunicorn)
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/benim-uygulamam
Environment="PATH=/var/www/benim-uygulamam/.venv/bin"
ExecStart=/var/www/benim-uygulamam/.venv/bin/gunicorn \
--workers 3 \
--bind unix:/run/benim-uygulamam.sock \
benim_projem.wsgi:application
Restart=always
[Install]
WantedBy=multi-user.target
Servisi etkinleştirip başlatmak ve durumunu görmek için:
sudo systemctl daemon-reload
sudo systemctl enable --now benim-uygulamam.service
sudo systemctl status benim-uygulamam.service
Önüne bir de Nginx ters vekil koyduğunuzda, Nginx gelen istekleri yukarıda tanımladığımız Unix soketine iletir ve statik dosyaları doğrudan servis eder. Bu klasik "Nginx + Gunicorn + systemd" üçlüsü, bir Python web uygulamasını VDS sunucu üzerinde yayına almanın en yaygın ve dayanıklı yoludur. Kök erişimi gerektiren bu tür kurulumlar için paylaşımlı hosting yerine tam denetimli bir sunucu tercih etmek gerekir; kurulum ve bakım yükünü üstlenmek istemiyorsanız sunucu yönetimi hizmetimiz devreye girer.
İyi Uygulamalar ve Sık Yapılan Hatalar#
Yıllar içinde biriken tecrübe, sanal ortam yönetiminde birkaç basit kuralı öne çıkarır. Bunları baştan benimsemek, ilerideki pek çok baş ağrısını önler:
- Her projeye bir ortam. İki farklı projeyi tek bir
.venviçinde toplamayın; izolasyonun bütün faydası buradan gelir. .venv/dizinini asla depoya koymayın. Taşınabilir olanrequirements.txt'tir, ortam klasörünün kendisi değil..gitignoredosyanıza mutlaka ekleyin.- Sürümleri sabitleyin. Üretime giden
requirements.txt'te==ile tam sürüm belirtmek, ileride sessizce gelen bir güncellemenin uygulamanızı bozmasını engeller. sudo pip installkullanmayın. Bir paketisudoile kurma ihtiyacı hissediyorsanız, bu neredeyse her zaman yanlış yaptığınızın işaretidir; ya bir.venvya dapipxkullanın.- Ortamı taşımayın, yeniden oluşturun.
.venvklasörü içindeki yollar mutlaktır ve bir makineden diğerine kopyalanamaz. Yeni makinedepython3 -m venv .venv && pip install -r requirements.txther zaman doğru yoldur.
Karşılaşabileceğiniz iki tipik sorun da şunlardır. "command not found: python" hatası genellikle dağıtımın python3 komutunu sunup python sunmamasından kaynaklanır; ortamı etkinleştirdiğinizde .venv içindeki python bağlantısı bu sorunu çözer. "ModuleNotFoundError" hatası ise çoğu zaman ortamı etkinleştirmeyi unuttuğunuz anlamına gelir — istemin başında (.venv) etiketini görüp görmediğinizi kontrol edin. Bu iki refleksi kazandığınızda, Python bağımlılık yönetimi zahmet olmaktan çıkıp arka planda sessizce işleyen bir rutine dönüşür.
Sıkça Sorulan Sorular#
venv ile virtualenv arasındaki fark nedir?#
Aynı işi yapan iki araçtır ve pratikte çoğu kullanıcı için sonuç aynıdır. virtualenv daha eski, üçüncü taraf bir pakettir ve bazı ek özellikler ile daha eski Python sürümleri için destek sunar. venv ise Python 3.3'ten beri standart kütüphanenin parçasıdır, yani ayrıca kurulum gerektirmez. Yeni projeler için venv yeterlidir ve önerilir; yalnızca çok özel ihtiyaçlarınız varsa virtualenv'e yönelmenize gerek kalır.
requirements.txt dosyasını neden sürüm kontrolüne eklemeliyim?#
Çünkü bu dosya, projenizin çalışması için gereken bağımlılıkların tek ve resmi kaydıdır. Depoya eklendiğinde, projeyi indiren herkes tek komutla aynı ortamı yeniden kurabilir ve "benim makinemde çalışıyordu" türü tutarsızlıklar ortadan kalkar. Buna karşın .venv/ klasörü makineye özgü mutlak yollar içerdiği için taşınabilir değildir ve depoya eklenmemelidir; onun yerine requirements.txt'ten her makinede yeniden üretilir.
externally-managed-environment hatasını nasıl çözerim?#
Bu hata, sisteminizin genel Python'ını korumaya alan PEP 668 kuralının devreye girdiğini gösterir ve doğru çözümü bir sanal ortam oluşturmaktır. Projenizin dizininde python3 -m venv .venv çalıştırıp source .venv/bin/activate ile etkinleştirin; artık aynı ortam içinde pip install sorunsuz çalışacaktır. Uyarıyı --break-system-packages bayrağıyla geçmek teknik olarak mümkün olsa da, ismindeki "break" kelimesinin hakkını verip sistem araçlarını bozma riski taşıdığı için üretim sunucularında bundan kaçının.
Sanal ortamı bir sunucudan diğerine kopyalayabilir miyim?#
Hayır, .venv klasörünü olduğu gibi kopyalamak güvenilir değildir çünkü içindeki betikler yorumlayıcıya mutlak dosya yollarıyla bağlıdır ve bu yollar hedef makinede farklı olur. Doğru yöntem, kaynak makinede pip freeze > requirements.txt ile bağımlılıkları dışa aktarmak, hedef makinede yeni bir sanal ortam oluşturup pip install -r requirements.txt ile yeniden kurmaktır. Bu yaklaşım hem daha temizdir hem de her makinede birebir aynı sürümleri garanti eder.
Global bir komut satırı aracını nereye kurmalıyım?#
black, httpie ya da poetry gibi doğrudan terminalden çalıştırdığınız araçları pipx ile kurun. pipx, her aracı kendi izole sanal ortamına yerleştirip yalnızca çalıştırılabilir komutunu PATH'e bağlar; böylece araç her yerden erişilebilir olur ama sisteminizin genel Python'ını kirletmez. Eğer paketi bir projenin kodu içinden import ederek kullanacaksanız, o zaman pipx değil, ilgili projenin .venv ortamına pip install doğru seçimdir.
Her projenin ayrı venv'i çok yer kaplamaz mı?#
Sanal ortamlar sandığınız kadar büyük değildir; çoğu paket, ortama gerçek kopya yerine referanslarla eklenir ve boş bir ortam yalnızca birkaç megabayttır. Diske değil temizliğe öncelik verin: izolasyonun sağladığı çakışmasız, tekrar üretilebilir yapı, birkaç megabaytlık alandan çok daha değerlidir. Yer gerçekten sorun olursa, kullanmadığınız projelerin .venv klasörlerini silebilir, ihtiyaç duyduğunuzda requirements.txt'ten saniyeler içinde yeniden oluşturabilirsiniz.
Kapanış#
Python'da sağlıklı bir geliştirme ve dağıtım disiplininin temeli tek bir alışkanlıkta yatar: her projeye kendi sanal ortamını vermek ve bağımlılıkları requirements.txt ile kayıt altına almak. venv ile izolasyonu, pip ile paket yönetimini, pipx ile global araçları ve Gunicorn + systemd ile üretime geçişi bir arada kullandığınızda, sistem Python'ını hiç riske atmadan her projenizi temiz, taşınabilir ve tekrar üretilebilir tutarsınız.
Bu kurgunun tüm gücünü ortaya koyabilmek için genellikle kök erişimine sahip bir ortama ihtiyaç duyarsınız. Gunicorn, systemd servisleri ve Nginx ters vekil kurulumları için tam denetim sunan VDS ve sanal sunucu çözümlerimizi inceleyebilir, hazır Python tabanlı uygulamaları tek tıkla ayağa kaldırmak için App Center kataloğumuza göz atabilir, kurulum ve bakımı bize bırakmak isterseniz de sunucu yönetimi hizmetimizden yararlanabilirsiniz. Doğru zeminde, Python projeleriniz ilk günkü temizlikle yıllarca sorunsuz çalışır.