Django Python uygulamanızı hızlı bir şekilde oluşturmanıza yardımcı olabilecek, üst düzey, açık kaynaklı bir Python web çerçevesidir. Model-şablon-görünüm (model–template–views) mimari modelini takip ederek hızlı geliştirmeyi ve temiz, pragmatik tasarımı teşvik eder. Çerçeve, kutudan çıktığı haliyle, kullanıcı kimlik doğrulaması, önbelleğe alma çerçevesi, nesne-ilişkisel eşleştirici, URL Yönlendirici, şablon sistemi ve özelleştirilebilir yönetim arayüzü gibi gerekli modern uygulama bileşenleriyle birlikte gelir.
Gunicorn ‘Green Unicorn’, UNIX sistemleri için bir Python WSGI HTTP Sunucusudur. Gunicorn sunucusu çeşitli web çerçeveleriyle uyumludur, harika bir performans sunar ve sunucu kaynaklarını yormaz. Docker uygulama geliştirmeyi hızlı, verimli ve öngörülebilir hale getiren, bir süredir var olan açık kaynaklı bir konteyner platformudur.
Bu öğreticide, ölçeklenebilir, konteynerleştirilmiş Django web uygulamaları geliştirme ve dağıtma konusunda beceriler kazanacaksınız. Django başlangıç kılavuzlarını takip ederek oluşturulan bir Django Polls uygulamasını kullanacağız. Bu öğreticiyi yazarken, Django 3.2 sürümünü temel aldık ve bu sürüm, Python 3.6 veya sonraki sürümler tarafından desteklenmektedir. Uygulamayı Docker ile bir konteyner olarak dağıtacağız ve Gunicorn sunucusu ile sunacağız. Elbette, Django uygulamasını bir konteynerde dağıtmadan önce, standart çıktı akışlarına günlük kaydı (logging) yapılması ve ortam değişkenleriyle çalışılması gibi durumları yönetmek için proje kodunda bazı değişiklikler yapmanız gerekecektir. CSS ve JavaScript görselleri gibi statik dosyalar, çoklu konteyner ortamında dosyaların tek bir konumdan kolayca yönetilmesini sağlamak için nesne depolama servislerine aktarılabilir.
Ölçeklenebilir web uygulamaları oluşturmak için iyi bir şekilde ana hatları belirlenmiş olan twelve-factor metodolojisine dayanarak bu değişiklikleri nasıl uygulayacağınızı göstereceğiz. Değişiklikleri tamamladıktan sonra, uygulamanın bir Docker imajını oluşturacak ve konteynerleştirilmiş uygulamayı Docker ile dağıtacaksınız. Öğreticiyi tam olarak anlamak için burada belirtilen adımları takip etmenizi öneririz.
Önkoşullar
Bu uygulamalı bir öğretici olduğundan, takip etmenizi kolaylaştırmak için aşağıdaki kuruluma sahip olmanızı öneririz:
-
Bir Ubuntu 20.04 sunucusu. CloudSigma üzerinde Ubuntu sunucunuzu kurmanıza yardımcı olması için bu adım adım Ubuntu sunucusu kurulum öğreticisinin 1 ila 4. adımlarını takip edebilirsiniz.
-
Yukarıdaki öğreticide belirtilen komutları çalıştırmak için kullanacağımız her iki düğümde de bir sudo yetkilerine sahip kullanıcı tanımladığınızdan emin olun.
-
Sunucuya Docker yükleyin. Docker'ı kurma ve çalıştırma konusundaki öğreticimizin 1, 2 ve 3. adımlarını takip edebilirsiniz. Yukarıda oluşturulan sudo kullanıcısını Docker grubuna eklemeyi unutmayın.
-
Uyumlu bir nesne depolama alanı. Django, django-storages belgelerinde listelenen birkaç depolama servisini destekler. Tercih ettiğiniz birini seçebilir ve kurmak için belgeleri takip edebilirsiniz. Bu öğretici için, MinIO adındaki S3 uyumlu bir bulut depolama servisini kullanacağız.
-
Bir SQL veritabanı örneği. Django, seçmekte özgür olduğunuz birkaç SQL veritabanını destekler. Bu öğretici için PostgreSQL kullanacağız. PostgreSQL veritabanı bir konteyner içinde dağıtılmayacaktır. Çoklu konteyner kurulumumuzu ve veri kalıcılığını sağlamak için PostgreSQL örneğini barındıracak ayrı bir Ubuntu sunucusu kuracağız. Başka bir Ubuntu 20.04 oluşturabilir ve Ubuntu üzerinde bir PostgreSQL veritabanı örneği kurmak için bu öğreticiyi takip edebilirsiniz: Ubuntu üzerinde PostgreSQL veritabanı örneği kurulumu. Adımlarda açıklandığı gibi PostgreSQL veritabanında sudo kullanıcınız için bir rol eklemeyi unutmayın: 2 ve 3. Bu rol, konteynerlerinizi barındıran diğer sunuculardan Veritabanına bağlanmanıza olanak tanıyacaktır.
Bu önkoşullara göre, iki Ubuntu sunucu örneğiniz olmalıdır. Bir örnek Docker konteynerinizi çalıştıracak, diğer örnek ise PostgreSQL örneğini çalıştıracaktır. Başlayalım!
Adım 1: PostgreSQL Veritabanı Örneğini Yapılandırma
Bu bölümde, Postgres örneğini çalıştıran Ubuntu sunucusundaki Postgres yapılandırmalarını değiştireceğiz. Bu, harici bir IP adresinden bağlantılara izin verecektir. Bağlantı kurulduktan sonra, dağıtımını yaptığımız Django Polls uygulamasına özel bir veritabanı ve kullanıcı rolü oluşturabiliriz.
İlk olarak, ortamınızı Prerequisites bölümüne göre kurduysanız, PostgreSQL veritabanınızda sudo kullanıcınız için bir rol bulunmalıdır. Ardından, bu rol için bir şifre belirlememiz gerekiyor. PostgreSQL çalıştıran sunucudayken, aşağıdaki komutla Postgres terminaline giriş yapın:
|
1 |
sudo -u postgres psql |
Postgres terminaline girdikten sonra, bir kullanıcının şifresini değiştirmek için \password komutunu çalıştırın. \password komutunun sözdizimi şu şekildedir: \password <username>. Bizim durumumuzda komut şöyledir:
|
1 |
\password cloudsigma |
Şifreyi girin ve onaylayın. Daha sonra diğer Ubuntu sunucusundan kimlik doğrulaması yapmak için kullanacağınızdan bu şifreyi güvenli bir yere kaydedin. Bundan sonra, Postgres terminalinden çıkmak için exit yazıp Enter tuşuna basın.
PostgreSQL sunucu örneğinde güvenlik duvarını (ufw) etkinleştirdiyseniz, Postgres varsayılan portuna giden trafiğe izin vermeniz gerekecektir: 5432. Trafiği, yalnızca Docker konteynerini çalıştıracak olan diğer Ubuntu sunucunuzun belirli bir IP adresinden gelecek şekilde sınırlandırabilirsiniz. Vurgulanan yere kendi IP adresinizi yazarak ufw kuralını eklemek için aşağıdaki komutu yürütün:
|
1 |
sudo ufw allow from ubuntu_server_ip_address to any port 5432 |
Bu, yalnızca sunucunuzun PostgreSQL örneğine bağlanabilmesini sağlayacaktır. Bu işlem güvenlik duvarından trafiğe izin verirken, uzak IP adresinden bağlantıya izin vermek için PostgreSQL yapılandırma dosyalarını da değiştirmeniz gerekir. Varsayılan olarak yapılandırma yalnızca localhost'tan bağlantıya izin verir. PostgreSQL yapılandırma dosyaları /etc/postgresql/12/main dizininde bulunur. 12, bu durumda, bu eğitim için yüklediğimiz PostgreSQL sürümüdür. Farklı bir sürüm yüklemiş olabilirsiniz. Bu nedenle, /etc/postgresql/ dizinine geçebilir ve yüklediğiniz PostgreSQL'in sürüm numarasını bulmak için içerikleri listeleyebilirsiniz.
Yapılandırma dosyasını düzenlemek için nano kullanın:
|
1 |
sudo nano /etc/postgresql/12/main/postgresql.conf |
Aşağıdaki satırı bulun, başındaki yorum işaretini kaldırın ve tüm IP'lerden gelen bağlantılara izin verecek şekilde ayarlayın:
|
1 |
listen_addresses = '*' |
Dosyayı kaydedip kapatın. Ardından, pg_hba.conf dosyasını da düzenlemeniz gerekir; bu dosya postgresql.conf ile aynı dizindedir. pg_hba.conf dosyası, PostgreSQL örneğine hangi bilgisayarlardan bağlanabileceğinizi ve kimlik doğrulama yöntemini tanımlamanıza olanak tanır. Dosyayı nano ile açın:
|
1 |
sudo nano /etc/postgresql/12/main/pg_hba.conf |
Anahtar kelimeleri anlamak için lütfen bu dosyadaki yorumları okuyun. Aradığımız bölüm şudur:

Odağımız ikinci satırda olacak, yorum işaretini kaldırdıktan sonra aşağıdaki satır gibi görünmesini isteyeceksiniz:
|
1 |
host all all your_ubuntu_server_ip/24 md5 |
PostgreSQL örneğine bağlanmasına izin vermek için lütfen vurgulanan kısmı Ubuntu sunucunuzun IP adresiyle değiştirin. Hazır olduğunuzda dosyayı kaydedin. Değişikliklerin geçerli olması için PostgreSQL veritabanını yeniden başlatın:
|
1 |
sudo service postgresql restart |
Belirtilen IP adresine sahip diğer Ubuntu sunucumuz Postgres Örneğine bağlanabilmelidir.
Adım 2: PostgreSQL Sunucu Örneğine Bağlanma ve Veritabanı ile Kullanıcı Oluşturma
Bu adımda, Docker konteynerimize hizmet veren Ubuntu örneğinin diğer sunucuda çalışan PostgreSQL örneğine bağlanabildiğinden emin olmaya çalışacağız. Docker yüklü olan Ubuntu örneğine giriş yapın ve Ubuntu ana makinesinin içine (henüz konteynerin içine değil) postgresql-client paketini yükleyin.
Genel bir kural olarak, önce apt paketini güncelleyin ve ardından aşağıdaki komutlarla paketi yükleyin:
|
1 |
sudo apt update |
|
1 |
sudo apt install postgresql-client |
Yukarıda yüklenen paket, uygulamanız için bir veritabanı ve kullanıcı oluşturmanıza yardımcı olacaktır. Ardından, PostgreSQL istemcisine bağlantı parametreleri göndererek PostgreSQL örneğine bağlanmamız gerekiyor.
Bağlantı parametreleri şu sözdizimini takip eder:
|
1 |
psql -U username -h host -p port -d database --set=sslmode=require |
Bu komutta, username PostgreSQL veritabanınıza eklediğiniz kullanıcı/roldür. host PostgreSQL veritabanınızı çalıştıran Ubuntu örneğinin IP adresidir. port Postgres'in gelen bağlantıları dinlediği varsayılan porttur, yani 5432. database yerine, PostgreSQL kurulumuyla birlikte gelen postgres adlı varsayılan veritabanını kullanacağız. Vurgulanan kısımlardaki değerlerinizi uygun şekilde değiştirin ve Enter tuşuna basın. İstendiğinde, belirlediğiniz şifreyi girin. Bu, veritabanını yönetebileceğiniz Postgres komut satırına giriş yapmanızı sağlar.
PostgreSQL örneğine başarıyla bağlandınız. Artık Django polls uygulaması için bir veritabanı oluşturabilirsiniz. Buna django_polls:
|
1 |
CREATE DATABASE django_polls; |
Hatalarla karşılaşmamak için ifadenizin noktalı virgülle bittiğinden emin olun. Ardından, şu komutla django_polls veritabanına geçiş yapın:
|
1 |
\c django_polls; |
Ardından, bu projeye özel bir veritabanı kullanıcısı oluşturun. Kullanıcıyı django_user:
|
1 |
CREATE USER django_user WITH PASSWORD 'password'; |
Kullanıcınız için güvenli bir şifre seçin. İşlem tamamlandıktan sonra, yeni oluşturduğumuz kullanıcının bağlantı parametrelerini değiştirmemiz gerekir. Bu, her bağlantı kurulduğunda doğru değerlerin sorgulanmamasını ve ayarlanmamasını sağlayarak veritabanı işlemlerini hızlandırmaya yardımcı olur.
Django'nun beklediği varsayılan kodlamayı UTF-8 olarak ayarlayın:
|
1 |
ALTER ROLE django_user SET client_encoding TO 'utf8'; |
Ardından, varsayılan işlem yalıtım şemasını, işlenmemiş işlemlerden okumaları engelleyen “ read committed” olarak ayarlayın:
|
1 |
ALTER ROLE django_user SET default_transaction_isolation TO 'read committed'; |
Saat diliminizi ayarlayın. Eğitimin evrensel kalması için UTC:
|
1 |
ALTER ROLE django_user SET timezone TO 'UTC'; |
Son olarak, yeni kullanıcıya veritabanının yönetim yetkilerini verin:
|
1 |
GRANT ALL PRIVILEGES ON DATABASE django_polls TO django_user; |
Hazır olduğunuzda PostgreSQL komut satırından çıkın:
|
1 |
\q |
Bu adım için hepsi bu kadar. Django uygulamanızı düzgün bir şekilde yapılandırdıktan sonra, veritabanınızı yönetebilmelidir.
Adım 3: Uygulamayı Bir Git Deposundan Çekme ve Bağımlılıkları Tanımlama
Bu adımda, Django-polls uygulama deposunu klonlayacağız. Bu depo, Django’s ilk Django uygulamanızı yazma eğitimi.
Docker çalıştıran Ubuntu sunucusunda oturum açın, django_project adında bir dizin oluşturun ve içine gidin:
|
1 2 |
mkdir django_project cd django_project |
Ardından, aşağıdaki komutla depoyu dizine klonlayın:
|
1 |
git clone https://github.com/jaymoh/django-polls.git |
Dizine gidin ve içeriği listeleyin:
|
1 |
cd django-polls |
Dizinin içeriğini listeleyin:
|
1 |
ls |

Aşağıdaki öğelere dikkat edin:
-
manage.py: bu dosya, Django'nun uygulamanızı yönetmek için sağladığı komut satırı aracına giriştir.
-
mysite: Django proje kapsamı ve kod ayarlarını içeren bir dizin.
-
polls: polls uygulama kodunu içeren bir dizin.
-
templates: yönetim sayfaları için özel şablon dosyalarını içerir.
Projeyi gerçekte nasıl oluşturduğumuz hakkında daha fazla bilgi edinmek için lütfen resmi belgelerdeki Writing your first Django app bölümüne bakın. django-polls dizininde, Python bağımlılıklarımızın bir metin dosyasında tanımlanmasını istiyoruz. Buna requirements.txt adını vereceğiz. Dosyayı tercih ettiğiniz düzenleyiciyle açın:
|
1 |
nano requirements.txt |
Bağımlılıkları bildirmek için dosyanın içine aşağıdaki satırları yapıştırın:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Django==3.2.9 gunicorn==20.1.0 docutils==0.18.1 sqlparse==0.4.2 jmespath==0.10.0 psycopg2==2.9.2 python-dateutil==2.8.2 pytz==2021.3 six==1.16.0 urllib3==1.26.7 django-storages==1.12.2 minio==7.1.6 django-minio-backend==3.3.2 django-dotenv==1.4.2 boto3==1.21.38 |
Bu dosyada, uygulamayı derlediğinizde yüklenmesi gereken Python bağımlılıklarını tam sürümleriyle tanımladık. Bunlardan bazıları şunlardır: Django, django-storages nesne depolama bölmeleriyle etkileşim kurmak için psycopg2 PostgreSQL adaptörü, gunicorn WSGI sunucusu ve diğer ek bağımlılıklar. Bitirdiğinizde dosyayı kaydedip kapatın.
Adım 4: Bir Django Uygulaması için Ortam Değişkenlerini Yapılandırma
The twelve-factor app metodolojisi, sabit kodlanmış yapılandırmaları uygulamanızın kod tabanından çıkarmanızı önerir. Bunu yaparak, kod tabanına dokunmadan ortam değişkenlerini değiştirerek uygulamanın çalışma zamanındaki davranışını değiştirme özgürlüğünü elde edersiniz. Docker bu kurulumla çalışır, bu nedenle ayarlar dosyasını ortam değişkenleriyle çalışacak şekilde değiştireceğiz. Kubernetes da bu yapılandırma kurulumuyla çalışır. Kubernetes ile dağıtım yapma konusundaki başka bir kılavuzu CloudSigma blog.
The settings.py bir Django projesinin ana ayarlar dosyasıdır. Uygulamayı yapılandırmak için yerel veri yapılarını kullanan bir Python modülüdür. Uygulamamız için dosya şu konumdadır: django-polls/mysite/settings.py. Değerlerinin çoğu sabit kodlanmıştır. Bu durum, uygulama davranışını değiştirmeniz halinde kod tabanındaki yapılandırma dosyasını değiştirmenizi gerektirecektir. Bunu değiştirmek istiyoruz. Neyse ki Python, getenv fonksiyonunu os modülünde sunar. Django'yu yapılandırma parametrelerini bunun yerine yerel ortam değişkenlerinden okuyacak şekilde yapılandırmak için bunu kullanabiliriz.
Değişkenlerin sabit kodlanmış değerlerini değiştirmek için django-polls/mysite/settings.py dosyasını değiştirerek devam edelim. Çalışma zamanında bir os.getenv çağrısıyla güncellemek isteyebiliriz. Bu fonksiyon, sağlanan ortam değişkeni adında ayarlanan değeri okur. İsteğe bağlı olarak, ortam değişkeni ayarlanmamışsa kullanılacak varsayılan bir değer olan ikinci bir parametre sağlayabilirsiniz.
İşte bir örnek:
|
1 |
SECRET_KEY = os.getenv('DJANGO_SECRET_KEY') |
Yukarıdaki satırda, Django'ya gizli anahtarı (secret key) ortam değişkeninden almasını söylüyoruz. Anahtarı harici olarak sağlayacağımız için yedek bir değer sağlamıyoruz. Eğer mevcut değilse, uygulamanın başlatılması başarısız olmalıdır. Gizli anahtarı harici olarak sağlarken, uygulamanın tüm konteynerleştirilmiş kopyalarının çeşitli sunucularda aynı anahtarı kullandığından da emin olmak istiyoruz. Bu, uygulamanın çeşitli kopyalarının farklı anahtarlar kullanması durumunda ortaya çıkabilecek olası sorunları önler.
İşte varsayılan seçeneğe sahip başka bir örnek:
|
1 |
DEBUG = os.getenv('DEBUG', False) |
Bu satırda, okunması gereken bir DEBUG ortam değişkeni tanımlıyoruz. Ancak ayarlanmamışsa, DEBUG ayar değişkenine aktarılacak ikinci bir parametre sağladık. DEBUG değişkeni, False olarak ayarlanmıştır; böylece uygulamada bir sorun olması durumunda hassas bilgilerin ön uca iletilmemesi sağlanır. Ancak geliştirme modundaysak, hataları düzeltmemizi kolaylaştırmak amacıyla hata bilgilerini görebilmemiz için bunun True olarak ayarlanmasını isteriz; böylece hataları düzeltmemizi kolaylaştıracak hata bilgilerini görebiliriz.
Artık ortam değişkenlerinin önemini bildiğinize göre, düzenleyicinizde django_project/django-polls/settings.py dosyasını açın. İlk olarak, os modülünü, settings.py dosyasının en üstüne şu satırı ekleyerek içe aktarın:
|
1 |
import os |
Ardından, bu değişkenleri bulun ve aşağıdaki gibi güncelleyin:
|
1 2 3 |
SECRET_KEY = os.getenv('DJANGO_SECRET_KEY') DEBUG = os.getenv('DEBUG', False) ALLOWED_HOSTS = os.getenv('DJANGO_ALLOWED_HOSTS', '127.0.0.1').split(',') |
In the ALLOWED_HOSTS ayarında, değerin DJANGO_ALLOWED_HOSTS ortam değişkeninden alınacağını ve bir Python listesine ayırıcı olarak virgül ( ,) kullanılarak bölüneceğini belirtiyoruz. Değişken eksikse, ALLOWED_HOSTS değeri olarak ayarlanır.127.0.0.1.
Ardından, dosyayı kaydırın ve DATABASES bölümünü bulun, bunu da ortam değişkenlerinden okuyacak şekilde yapılandırın:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.{}'.format( os.getenv('DB_ENGINE', 'sqlite3') ), 'NAME': os.getenv('DB_DATABASE', 'django_polls'), 'USER': os.getenv('DB_USERNAME', 'your_db_username'), 'PASSWORD': os.getenv('DB_PASSWORD', 'your_secure_default_password'), 'HOST': os.getenv('DB_HOST', '127.0.0.1'), 'PORT': os.getenv('DB_PORT', 5432), 'OPTIONS': json.loads( os.getenv('DB_OPTIONS', '{}') ), } } |
Fark ettiyseniz, json.loads modülünü ekledik. Bu modülün içe aktarımını (import) settings.py dosyasının en üstüne de eklemelisiniz:
|
1 |
import json |
The json.loads işlevi, DATABASES['default']['OPTIONS'] kısmına DB_OPTIONS ortam değişkeninden aktarılan bir JSON nesnesini serileştirmeden çıkarır (deserializes). Bu seçeneğin belirtilmesi, veritabanı yapılandırmasını tanımlamak için rastgele bir veri yapısı geçirmemize olanak tanır. Bir veritabanı motoru, kendisi için geçerli olan bir dizi seçenek içerir. JSON seçeneği, o sırada kullandığımız veritabanı motoru için uygun parametrelerle bir JSON nesnesini kodlama esnekliği sağlar.
The DATABASES['default']['NAME'] ayarı, kurduğumuz ilişkisel veritabanı yönetim sistemindeki veritabanı adını belirtir. SQLite veritabanı kullanılması durumunda, veritabanı dosyasının yolunu belirtmelisiniz.
Python'ın harici ortam değişkenlerini okumak için birkaç yöntem sunduğunu unutmayın. Biz bunlardan yalnızca birini kullandık. Diğer yöntemleri araştırıp kullanmakta özgürsünüz. Bu adımda, harici ortam değişkenleriyle nasıl çalışacağınızı öğrendiniz. Bu size değişkenleri değiştirme ve konteynerlerde çalışan uygulamanın davranışını değiştirme esnekliği sağlar. Bir sonraki adımda, nesne depolama servisleriyle nasıl çalışacağınızı öğreneceksiniz.
Adım 5: Harici Nesne Depolama Servisleriyle Çalışma
Uygulamanızı konteynerleştirmenin en büyük avantajı, trafik arttığında uygulamanın birden fazla kopyasının kolayca dağıtılabilmesi için taşınabilir hale getirmektir. Böylece ölçeklendirmeye olanak tanır. Ancak bu durum, statik dosyaların ve varlıkların sürümlerinin çeşitli konteynerler arasında korunması sorununu da beraberinde getirir. Bulut teknolojisindeki gelişmeler sayesinde, bu paylaşılan statik öğeleri harici depolamaya aktarabilirsiniz. Ardından, dosyaları bir ağ üzerinden çalışan tüm konteynerleriniz için erişilebilir hale getirebilirsiniz. Dosyaları çalışan çeşitli konteynerler arasında senkronize etmeye çalışmak yerine, bunları yönetmek için tek bir merkezi yere sahip olursunuz.
Yukarıda açıklamaya çalıştığımız kavram, bulut nesne depolama servislerinin veya Basit Depolama Servislerinin (S3) kullanılmasıdır. Django'nun şu isimde bir paketi vardır: django-storages uzak depolama arka uçlarıyla çalışmanıza olanak tanır. Django-storages FTP, SFTP, Amazon’s AWS S3, Google Cloud Storage, Dropbox ve Azure Storage gibi diğerlerinin yanı sıra çoğu S3 uyumlu nesne depolama hizmetiyle çalışır. Bu eğitimde, MinIO kullanacağız. Diğer herhangi bir S3 uyumlu nesne depolama hizmetini kullanmaktan çekinmeyin. MinIO yüksek performanslı, S3 uyumlu nesne depolama sunar. MinIO ile herhangi bir bulut üzerinde S3 uyumlu veri altyapısı oluşturabilirsiniz.
CloudSigma platformunda bir MinIO depolama hizmetini nasıl kuracağınızı göstereceğiz. Lütfen şu adımları takip edin:
-
Şununla başlayın: CloudSigma üzerinde bir Hesap oluşturarak. MinIO depolamasını oluştururken herhangi bir sorunla karşılaşırsanız lütfen CloudSigma’ın ücretsiz 7/24 canlı sohbet desteği ile iletişime geçin, size yardımcı olacaklardır.
-
Fatura Bilgilerinizi ekleyin.
-
Ardından, herkese açık erişilebilir klasörünüzü (bucket) buradan talep edin: https://blog.cloudsigma.com/xxxx. Hesap erişim kimlik bilgilerinizi almak için Canlı Sohbet desteğiyle iletişime geçmeniz gerekecektir.
-
MinIO nesne depolama ortamınız oluşturulduktan sonra, size erişim kimlik bilgileri ve buna erişmek için diğer talimatlar sağlanacaktır. Kimlik bilgileri şunları içermelidir: MINI_ACCESS_KEY, MINIO_SECRET_KEY, ve MINIO_URL. Bu anahtarları aşağıdaki talimatlarda kullanacaksınız.
Önceki adımda değiştirmekte olduğumuz mysite/settings.py dosyasında bazı değişiklikler daha yapalım. Dosyada, storages uygulamasını Django'nun INSTALLED_APPS:

The storages uygulaması, django-storages aracılığıyla yüklenir (bu requirements.txt dosyasında tanımlandığı gibidir). Dosyanın en altına gidin ve STATIC_URL değişkenini aşağıdaki kod parçacığıyla değiştirin:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# Statik dosyalar (CSS, JavaScript, Resimler) # https://docs.djangoproject.com/en/3.2/howto/static-files/ DEFAULT_FILE_STORAGE = os.getenv('STATIC_DEFAULT_FILE_STORAGE', 'storages.backends.s3boto3.S3Boto3Storage') AWS_S3_ENDPOINT_URL = os.getenv('MINIO_URL') AWS_ACCESS_KEY_ID = os.getenv('MINIO_ACCESS_KEY') AWS_SECRET_ACCESS_KEY = os.getenv('MINIO_SECRET_KEY') AWS_STORAGE_BUCKET_NAME = os.getenv('STATIC_MINIO_BUCKET_NAME') AWS_S3_OBJECT_PARAMETERS = { 'CacheControl': 'max-age=86400', } AWS_LOCATION = 'static' AWS_DEFAULT_ACL = 'public-read' STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' STATIC_URL = '{}/{}/'.format(AWS_S3_ENDPOINT_URL, AWS_LOCATION) STATIC_ROOT = "static/" |
Bazı yapılandırma değişkenlerinin sabit kodlanmış (hard-coded) olduğunu fark edeceksiniz:
-
STATICFILES_STORAGE: Django'nun statik dosyaları işlemek için kullanacağı depolama arka ucunu tanımlar. Kılavuzumuzda MinIO depolama kullanıyoruz, ancak Django Storages belgelerinde açıklandığı gibi herhangi bir S3 uyumlu arka ucu kullanabilirsiniz.
-
AWS_S3_OBJECT_PARAMETERS: önbellek kontrol (cache-control) başlıklarını tanımlar.
-
AWS_LOCATION: bunu, tüm statik dosyaların depolanacağı depolama klasörü (bucket) içinde bir dizin ayarlamak için kullanırız. Farklı bir ad seçmekte özgürsünüz.
-
AWS_DEFAULT_ACL: statik dosyalar için erişim kontrol listesini (ACL) ayarlar. Değeri ‘ public-Read’ olarak ayarlamak, dosyaları tüm genel kullanıcılar için erişilebilir hale getirecektir.
-
STATIC_URL: Django, statik dosyalar için URL'ler oluşturmak üzere bu değişkende ayarlanan temel URL'yi kullanır. Bu durumdaki temel URL, uç nokta (endpoint) URL'si ile statik dosyalar alt dizininin birleştirilmesiyle elde edilir.
-
STATIC_ROOT: statik dosyaları uzak nesne depolamasına kopyalamadan önce yerel olarak nerede toplayacağını tanımlar.
Esnekliği ve taşınabilirliği korumak için harici olarak tanımlanmış bazı ortam değişkenlerimiz de var:
-
AWS_STORAGE_BUCKET_NAME: Django'nun varlıkları yükleyeceği depolama klasörünün (bucket) adını tanımlar.
-
AWS_S3_ENDPOINT_URL: nesne depolama servisine erişmek için kullanılan uç nokta (endpoint) URL'sini tanımlar. Bu, MinIO servisinizi barındıran sunucuya eşlenen URL olacaktır.
Düzenlemeyi bitirdiğinizde dosyayı kaydedip kapatın.
Bu ayarları yaptıktan ve beyan edilen Python bağımlılıklarını yükledikten sonra, projenizin statik dosyalarını toplamak ve bunları uzak nesne depolama arka ucuna yüklemek için istediğiniz zaman manage.py collectstatic Django komutunu çalıştırabilirsiniz:
|
1 |
python manage.py collectstatic |
Ancak, henüz env dosyasını yapılandırmalarla ayarlamadık, bu nedenle muhtemelen başarısız olacaktır.
Komutu çalıştırdığınızda, boyutlarına ve internet hızınıza bağlı olarak varlıklarınızın MinIO Bulut Depolama'ya kopyalanması biraz zaman alır.
Bu adım için bu kadar. Django günlüklerini Docker Motoruna göndermeyi nasıl halledebileceğimize bakalım; böylece bir sonraki adımda bunları docker logs komutunu kullanarak görüntüleyebilirsiniz.
Adım 6: Bir Django Uygulamasında Günlük Kaydını (Logging) Ayarlama
Hata ayıklama (Debug) modundayken, DEBUG seçeneği True olarak ayarlandığında, Django bilgileri standart çıktıya ve standart hataya kaydeder. Günlük bilgileri genellikle geliştirme HTTP sunucusunu başlattığınız terminalde görünür.
Üretim (production) ortamındayken, muhtemelen farklı bir HTTP sunucusu kullanıyorsunuzdur ve DEBUG seçeneği False olarak ayarlanmıştır. Django bu durumda farklı bir günlük kaydetme yöntemi kullanacaktır. Django, ERROR veya CRITICAL önceliğindeki günlükleri tanımladığınız bir yönetici e-posta hesabına gönderir. Bu, birçok durum için harika çalışır.
Konteynerleştirilmiş ve Kubernetes kurulumlarında, standart çıktıya ve standart hataya günlük kaydetmek şiddetle tavsiye edilir. Günlük mesajları, Node'un dosya sistemindeki tek bir dizinde toplanır ve kubectl ve docker komutları kullanılarak kolayca erişilebilir. Node'un dosya sistemindeki merkezi bir günlük kaydı noktası sayesinde, operasyon ekibi günlükleri izlemek ve iletmek için her bir node üzerinde kolayca işlemler çalıştırabilir. Bu nedenle, uygulamamızı günlükleri bu standart kuruluma yazacak şekilde yapılandırmalıyız.
Django'nun, Python standart kütüphanesindeki son derece özelleştirilebilir logging modülünden yararlandığını öğrenmekten memnuniyet duyacaksınız. Bu, istenen çıktıları ve biçimlendirmeyi tanımlamak için logging.config.dictConfig işlevine aktarılan bir sözlük tanımlamanıza olanak tanır. İşte Django günlük kaydı tekniklerinde uzmanlaşmanıza yardımcı olabilecek Django Logging, The Right Way üzerine güzel bir makale.
Editörünüzde django-polls/mysite/settings.py dosyasını açın. Dosyanın en üstüne Python logging.config kütüphanesi için bir içe aktarma (import) ekleyin:
|
1 |
import logging.config |
Şimdiye kadar eklediğimiz tüm içe aktarmalarla birlikte, settings.py dosyasındaki içe aktarmalar bölümünüz şu şekilde görünmelidir:

The logging.config kütüphanesi, Django'nun varsayılan günlük kaydı davranışını geçersiz kılmak için dictConfig işlevi aracılığıyla yeni günlük kaydı yapılandırmasından oluşan bir sözlük alır.
Dosyanın en altına gidin ve aşağıdaki günlük kaydı yapılandırması kod parçacığını ekleyin:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# Günlük Kaydı Yapılandırması # Önceki yapılandırmayı devre dışı bırak LOGGING_CONFIG = None # Ortamdan loglevel değerini al LOGLEVEL = os.getenv('DJANGO_LOGLEVEL', 'info').upper() logging.config.dictConfig({ 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'console': { 'format': '%(asctime)s %(levelname)s [%(name)s:%(lineno)s] %(module)s %(process)d %(thread)d %(message)s', }, }, 'handlers': { 'console': { 'class': 'logging.StreamHandler', 'formatter': 'console', }, }, 'loggers': { '': { 'level': LOGLEVEL, 'handlers': ['console',], }, }, }) |
LOGGING_CONFIG değeri şuna ayarlanır: None Django tarafından tanımlanan varsayılan günlük kaydı yapılandırmalarını devre dışı bırakmak/temizlemek için. LOGLEVEL değeri, DJANGO_LOGLEVEL ortam değişkeni tarafından ayarlanır. Ancak, eğer mevcut değilse, bunun ‘ info’.
En üstte içe aktardığımız logging.config modülü, yeni bir yapılandırma sözlüğü ayarlamak için kullanılan dictConfig fonksiyonunu sağlar. Bu sözlük, formatters anahtarını kullanarak metin biçimlendirmesini tanımlar. Çıktı, handlers anahtarı ile ayarlanır ve son olarak loggers anahtarı hangi mesajın hangi işleyiciye gitmesi gerektiğini tanımlar.
Bu ayarları tanımladıktan sonra, Docker günlükleri docker logs komutu aracılığıyla kullanıma sunacaktır. Benzer şekilde, Kubernetes için yapacağımız başka bir eğitimde, günlükleri kubectl logs komutuyla görüntüleyebilirsiniz. Şimdi bir sonraki adımda konteynerleştirme sürecine başlayalım.
Adım 7: Uygulama Dockerfile Dosyasını Tanımlama
Bu adımda, Guincorn WSGI sunucusu tarafından sunulan Django uygulamasını çalıştıracak konteyner imajını ayağa kaldırmak için gereken yapılandırmayı tanımlıyoruz. Bir konteyner imajı oluşturmak için çalışma zamanı ortamını tanımlayacak, uygulamayı ve bağımlılıklarını yükleyecek ve bazı son yapılandırmaları gerçekleştireceğiz.
-
Bir Django uygulaması için üst imaj
Konteynerinizi hangi temel imaja dayandıracağınıza karar vermek, konteynerleştirilmiş dağıtımlarla uğraşırken vereceğiniz ilk karardır. Elbette, konteyner imajlarınızı SCRATCH'ten, yani boş bir dosya sisteminden oluşturma veya mevcut bir konteyner imajını temel alma seçeneğiniz vardır. Tekerleği yeniden keşfetmek istemediğimiz için imajımızı bir temel imajdan oluşturacağız. Şuradan erişilebilen birçok açık kaynaklı konteyner imajı bulunmaktadır: Docker'ın resmi konteyner imajı deposu. İmajınızı sıfırdan oluşturmadığınız sürece, Docker'ın resmi hub'ındaki bir imajı kullanmanız şiddetle tavsiye edilir. Bunun nedeni, Docker'ın imajların en iyi uygulamaları takip ettiğini doğrulaması ve düzenli güncellemeler ile güvenlik yamalarının uygulanmasını sağlamasıdır.
Django bir Python çerçevesi olduğundan, ihtiyacimiz olan araçların ve kütüphanelerin halihazırda yüklü olduğu standart bir Python ortamına sahip bir imajdan yararlanacağız. Docker Hub'daki resmi Python imajları sayfasından, çeşitli Python sürümleri için Python tabanlı bir imaj bulabilirsiniz.
Çeşitli Docker tabanlı eğitimlerimizden de fark edeceğiniz üzere, Alpine Linux tabanlı imajlar kullanıyoruz. Alpine Linux, konteynerleştirilmiş uygulamaları çalıştırmak için sağlam ancak ince bir işletim sistemi ortamı sunar. Dosya sistemi küçük olsa da genişletilebilirdir ve yeni özellikler ekleme olanağı sunan eksiksiz bir paket yönetim sistemiyle birlikte gelir.
Docker Hub'da bir temel imaj seçerken, her imaj için birden fazla etiketin mevcut olduğunu fark edebilirsiniz. Python için, 3-alpine etiketine sahibiz; bu etiket, en son Alpine sürümünün en son Python 3 sürüm imajına işaret eder. Bu, projenizin daha eski bir imaj sürümüyle çalışması durumunda, Docker imajının bakımını yapanlar bir güncelleme yaptığında projenizin bozulabileceği anlamına gelir. Gelecekte bu tür senaryolardan kaçınmak için, her zaman kullanmak istediğiniz imaj için en spesifik etiketleri seçmeniz önerilir.
Bu eğitimde, 3.8.12-alpine3.15 imajını Django uygulamamız için temel imaj olarak kullanacağız. Bu özel etiket, Dockerfile dosyasında FROM talimatı kullanılarak belirtilecektir. Dockerfile ana proje dizininde yer alacaktır: django_project.
Öncelikle Django-polls dizininden çıkıp tekrar django_project dizinine giderek başlayın:
|
1 |
cd .. |
Dizine girdikten sonra, en sevdiğiniz düzenleyiciyi kullanarak Dockerfile :
|
1 |
nano Dockerfile |
Ardından, imajınızın temelini ayarlamak için aşağıdaki satırı yapıştırın:
|
1 |
FROM python:3.8.12-alpine3.15 |
The FROM anahtar kelimesi, özel bir Docker imajının başlangıç noktasını tanımlar. Bu tanımlandıktan sonra, uygulamaları kurmak için talimatlar eklemeye devam edebiliriz. Bu talimatlar gerekli bağımlılıkları yükleyecek, uygulama dosyalarını kopyalayacak ve çalışma zamanı ortamını kuracaktır.
Dockerfile içine aşağıdaki kod parçacığını ekleyin:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
ADD django-polls/requirements.txt /app/requirements.txt RUN set -ex \ && apk add --no-cache --virtual .build-deps postgresql-dev build-base \ && python -m venv /env \ && /env/bin/pip install --upgrade pip \ && /env/bin/pip install --no-cache-dir -r /app/requirements.txt \ && runDeps="$(scanelf --needed --nobanner --recursive /env \ | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \ | sort -u \ | xargs -r apk info --installed \ | sort -u)" \ && apk add --virtual rundeps $runDeps \ && apk del .build-deps ADD django-polls /app WORKDIR /app ENV VIRTUAL_ENV /env ENV PATH /env/bin:$PATH EXPOSE 8000 |
Bu kod parçacığında, Docker'a requirements.txt dosyasını /app/requirements.txt konumuna kopyalamasını söylüyoruz; böylece uygulamanın bağımlılıklarının imajın dosya sisteminde mevcut olduğundan emin oluyoruz. Gereksinimler, uygulamayı çalıştırmak için gereken tüm Python paketlerini içerir. Docker'ın imaj katmanını önbelleğe alabilmesi için önce bağımlılıklar kopyalanır. Bunun nedeni, Docker'ın Dockerfile'daki her adımı önbelleğe almasıdır. İmajın ilk derlemesi genellikle daha uzun sürer. Docker bağımlılıkları indirecek ve ardından bunları önbelleğe alacaktır. Eğer requirements.txt dosyası değişmezse, Docker önbellekten derleme yapacak ve böylece sonraki derlemeleri daha hızlı hale getirecektir.
Bir sonraki adımda, RUN talimatı bulunur ve bu talimat, Linux && operatörüyle zincirlenmiş bir Linux komutları listesini yürütür. Komutlar şunları yapar:
-
PostgreSQL geliştirme dosyalarını ve temel derleme bağımlılıklarını yüklemek için Alpine'ın apk paket yöneticisi aracını kullanın.
-
Bir Python sanal ortamı oluşturun.
-
Şurada tanımlanan Python bağımlılıklarını yükleyin: requirements.txt dosyasını pip ile.
-
Yüklü Python paketlerinin gereksinimlerini analiz ederek gerekli çalışma zamanı paketlerini derleyin.
-
Artık gerekli olmayan tüm derleme bağımlılıklarını kaldırın.
Komutları RUN adımında zincirleme bağlamanın nedeni imaj katmanlarını azaltmaktır. Docker, her karşılaştığında mevcut dosya sisteminin üzerinde yeni bir imaj katmanı oluşturur: ADD, COPY veya RUN talimatı. Uygun olan yerlerde komutları sıkıştırmak, oluşturulan imaj katmanlarının sayısını en aza indirecektir.
İmaj katmanlarına eklenen öğeler sonraki bir katmanda kaldırılamaz. Bir sonraki talimata geçmeden önce istenmeyen öğeleri silmek için talimatlar bildirmeniz gerekir. Bu, imaj boyutunu azaltmak için gereklidir. Şunu eklediğimizi fark etmiş olmalısınız: apk del komutunu, RUN komutunun sonuna ekledik. Bu, uygulamanın paketlerini derlemek için kullandıktan sonra derleme bağımlılıklarını kaldırmak amacıyla yapıldı.
Sırada, başka bir ADD talimatı var; bunu uygulama kodunu /app dizinine kopyalamak için kullanıyoruz. Ardından, imajın çalışma dizinini WORKDIR talimatını kullanarak /app dizini (artık uygulamanın kodunu barındıran dizin) olarak ayarlayacağız.
Sırada, ENV talimatları var; bunları imajın çalışan konteynerlere sunacağı iki ortam değişkenini ayarlamak için kullanıyoruz. İlk olarak, VIRTUAL_ENV değişkenini /env olarak ayarlıyoruz. İkinci olarak, PATH değişkenini /env/bin dizinini içerecek şekilde ayarlıyoruz. Bu iki satırda, /env/bin/activate betiğini kaynak olarak alıyoruz (source); bu, Linux ortamında sanal bir ortamı nasıl etkinleştireceğimizdir. Şununla çalışma hakkında daha fazla bilgi edinebilirsiniz: diğer işletim sistemlerinde Python'da sanal ortamlar. Son talimat ise, EXPOSE komutudur; bu komut, konteynerin çalışma zamanında dinleyeceği 8000 portunu belirler.
Şu ana kadar Dockerfile'ınız, konteynerleri başlattığınızda çalışacak varsayılan komut dışında neredeyse tamamlandı. Bunu bir sonraki bölümde tanımlayalım.
-
Varsayılan Docker İmaj Komutunu Anlamak
Bir Docker konteynerini başlatırken, yürütülecek bir komut sağlayabilirsiniz. Ancak bir komut sağlamazsanız, Docker imajının varsayılan komutu konteyner başladığında ne olacağını belirleyecektir. Dockerfile içinde varsayılan bir komut tanımlamak için tek başına veya birlikte ENTRYPOINT veya CMD talimatlarını kullanırız.
Hem ENTRYPOINT hem de CMD tanımlamayı seçerseniz, ENTRYPOINT talimatında, konteyner tarafından çalıştırılacak yürütülebilir dosyayı tanımlarsınız. CMD talimatında ise yürütülebilir komut için varsayılan argüman listesini tanımlarsınız. Konteyneri şu biçimde başlatırken komut satırına alternatif argümanlar ekleyerek varsayılan argüman listesini geçersiz kılabilirsiniz:
|
1 |
docker run <image> <arguments> |
Bu biçim, geliştiricilerin ENTRYPOINT komutunu kolayca geçersiz kılmasını engeller. ENTRYPOINT komutu, ortamı kuracak ve sağlanan argüman listesine göre farklı eylemler gerçekleştirecek bir betiği çağırmak üzere tanımlanır.
Konteynerin yürütülebilir dosyasını yapılandırmak için yalnızca ENTRYPOINT talimatını tek başına kullanabilirsiniz. Ancak bu biçim, varsayılan bir argüman listesi tanımlamaya izin vermez. Konteyneri docker run komutuyla çalıştırdığınızda argümanlar sağlayabilirsiniz.
Yalnızca CMD kullanmayı seçerseniz, Docker bunu çalışma zamanında geçersiz kılabileceğiniz varsayılan komut ve argüman listesi olarak yorumlar. Daha fazla bilgiyi şurada bulabilirsiniz: resmi Dockerfile referans belgeleri.
Varsayılan komutlar hakkında öğrendiğiniz bilgileri konteyner örneğimize nasıl uygulayabileceğimizi görelim. Uygulamayı varsayılan olarak gunicorn sunucusunu kullanarak sunmak istiyoruz. gunicorn sunucusuna iletilen argüman listesinin çalışma zamanında yapılandırılabilir olması gerekmezken, hata ayıklama veya yapılandırmaları yönetme (veritabanını başlatma, statik varlıkları toplama vb.) gibi amaçlarla başka komutları çalıştırma esnekliğine sahip olmak istiyoruz. Gördüğünüz gibi, gerektiğinde geçersiz kılmamıza olanak tanıyacak varsayılan bir komut tanımlamak için CMD kullanmak bizim yararımızadır.
İşte CMD komutunu tanımlamak için kullanabileceğiniz bazı sözdizimleri:
- CMD ["command", "argument 1", "argument 2", . . . ,"argument n"]: exec biçimi (önerilen biçim), bir komut ve bir argüman listesi alır. Komutu herhangi bir kabuk (shell) işlemi olmadan doğrudan yürütür.
- CMD command "argument 1" "argument 2" . . . "argüman n": Kabuk (shell) formatı bir komut ve argüman listesi tanımlar. Komut listesini işlenmek üzere kabuğa iletir. Bir komuttaki ortam değişkenlerini değiştirmek istiyorsanız bunu yararlı bulabilirsiniz, ancak tamamen öngörülebilir değildir.
- CMD ["argüman 1", "argüman 2", . . . ,"argüman n"]: Argüman listesi formatı, yalnızca varsayılan argüman listesini tanımlar ve bir ENTRYPOINT talimatı ile birlikte kullanılır.
Son talimatımızı tanımlamak için exec formatını şu dosyada kullanacağız: Dockerfile. Aşağıdaki satırı şunun sonuna ekleyin: Dockerfile:
|
1 |
CMD ["gunicorn", "--bind", ":8000", "--workers", "3", "mysite.wsgi:application"] |
Artık şu dosyayı kaydedip kapatabilirsiniz: Dockerfile.
Bu imajı kullanarak konteynerleri başlattığınızda, gunicorn uygulamasını localhost portuna bağlı olarak, 8000 3 worker ile çalıştıracak ve şu dizindeki application fonksiyonunu, wsgi.py dosyasında çağıracaktır: mysite dizini. Çalışma zamanında varsayılan komutu geçersiz kılmak ve gunicorn yerine farklı bir işlem yürütmek için farklı bir komut sağlamayı seçebilirsiniz. Şunun hakkında daha fazla bilgi edinmek isteyebilirsiniz: Gunicorn worker'ları.
Dockerfile'ınız artık hazır ve uygulama imajını oluşturmak için docker build komutunu kullanabilirsiniz. Konteyneri yerel geliştirme makinenizde başlatmak için docker run komutunu kullanabilirsiniz.
-
Docker İmajını Oluşturma
Varsayılan olarak, docker build komutu, derleme talimatlarını bulmak için geçerli dizinde bir Dockerfile arayacaktır. Ayrıca derleme “bağlamını” (context) Docker daemon'ına gönderir. Bir derleme bağlamı derleme işlemi sırasında kullanılabilir olması gereken bir dosya kümesidir. Varsayılan olarak, şu komutu çalıştırdığınız geçerli dizin: docker build komutu derleme bağlamı olarak ayarlanır.
Dockerfile'ınızı içeren dizindeyken şu komutu çalıştırın: docker build. Bir imaj ve etiket belirtmek için -t bayrağını kullanın ve komutun sonundaki ( .) noktasını kullanarak geçerli dizini derleme bağlamı olarak ayarlayın:
|
1 |
docker build -t django-polls:v1 . |
Bu komutta imajı django-polls ve etiketi v1. Komutun sonundaki noktaya dikkat edin, bunu geçerli dizini derleme bağlamı olarak belirtmek için kullanıyoruz.
Şu işlem tamamlandığında: docker build tamamlandığında, aşağıdakine benzer bir çıktı görmelisiniz:

Docker imajınız artık hazır. Bazı yapılandırmaları harici ortam değişkenlerine kaydırmamış olsaydız, konteynerinizi şu komutla kolayca çalıştırabilirdiniz: docker run komutuyla. Ancak, şu dosyada ayarladığımız harici ortam değişkenlerini yapılandırmadığımız için: settings.py dosyası, çalıştırma başarısız olacaktır. Bir sonraki adımda bunu tamamlayalım.
Adım 8: Çalışma Zamanı Ortamını Ayarlama ve Uygulamayı Test Etme
Bu öğreticinin sonuna yaklaşıyoruz. Bu adımda, şu dosyadaki ortam değişkenlerini yapılandıracağız: env dosyası. Şu dosyadaki: env dosyası değişkenleri yerli yerine oturduğunda, veritabanı şemasını oluşturabilir, statik dosyaları oluşturup harici nesne depolama servisine yükleyebilir ve son olarak uygulamayı test edebiliriz.
Docker, konteynere ortam değişkenleri sağlamak için kullanabileceğiniz birkaç yöntemle birlikte gelir. Bizim durumumuzda, bir dosya aracılığıyla ortam değişkenlerinin bir listesini sağlamak istiyoruz. Bu nedenle, şu yöntemi kullanacağız: --env-file yöntemi.
Tercih ettiğiniz düzenleyiciyi kullanarak, env adında bir dosyayı şu dizinde oluşturun: django_project dizini:
|
1 |
nano env |
Aşağıdaki değişken listesini yapıştırın:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
DJANGO_SECRET_KEY=your_secret_key DEBUG= DJANGO_LOGLEVEL=info DJANGO_ALLOWED_HOSTS=sunucu_IP_adresiniz DB_ENGINE=postgresql_psycopg2 DB_DATABASE=polls_db DB_USERNAME=hackins DB_PASSWORD=veritabanı_şifreniz DB_HOST=veritabanı_sunucunuz DB_PORT=veritabanı_portunuz STATIC_DEFAULT_FILE_STORAGE=storages.backends.s3boto3.S3Boto3Storage STATIC_MINIO_BUCKET_NAME=test-bucket MINIO_ACCESS_KEY=minio_erişim_anahtarınız MINIO_SECRET_KEY=minio_gizli_anahtarınız MINIO_URL=minio_url_adresiniz:minio_portunuz |
Listedeki değişkenler, önceki adımlarda tanımladığınız değişkenlerdir:
-
DJANGO_SECRET_KEY: Şurada açıklandığı gibi benzersiz, tahmin edilemeyen bir değer oluşturun: Django belgeleri. Rastgele bir dize oluşturmak ve bunu değişkene atamak için bu komutu kullanabilirsiniz:
|
1 |
python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())' |
-
DEBUG: Bu değeri şu şekilde ayarladık: True, ancak canlı ortam (production) dağıtımı için bunu şu şekilde ayarlamayı unutmayın: False (boş bırakarak).
-
DJANGO_LOGLEVEL: bunu şu şekilde ayarladık: info, istediğiniz seviyeye göre ayarlayabilirsiniz.
-
DJANGO_ALLOWED_HOSTS: bu değeri Docker konteynerlerinizi çalıştıran Ubuntu sunucusunun IP adresine ayarlayın. İsteğe bağlı olarak, * değerine ayarlayabilirsiniz; bu, geliştirme modundaysanız tüm ana bilgisayarlarla eşleşen bir joker karakterdir.
-
DB_DATABASE: farklı bir veritabanı adı kullandıysanız, buraya uygun şekilde ayarlayın.
-
DB_USERNAME: bunu veritabanınız için seçtiğiniz kullanıcı adına ayarlayın.
-
DB_PASSWORD: bunu veritabanınız için seçtiğiniz şifreye ayarlayın.
-
DB_HOST: bunu, şu adımda kurduğunuz gibi veritabanı örneğinizi çalıştıran ana bilgisayara ayarlayın: Birinci Adım.
-
DB_PORT: bunu veritabanınızın portuna ayarlayın.
-
STATIC_MINIO_BUCKET_NAME: bunu MinIO Bulut Depolama hesabınızda oluşturduğunuz bucket (bölme) adına ayarlayın.
Düzenlemeyi bitirdiğinizde dosyayı kaydedip kapatın.
Ortam yapılandırmaları artık hazır. Varsayılan CMD komutunu geçersiz kılmak için argümanlar ileterek konteyneri çalıştırmamız ve şu komutları kullanarak veritabanı şemasını oluşturmamız gerekiyor: manage.py makemigrations ve manage.py migrate komutları.
İşte komut:
|
1 |
docker run --env-file env django-polls:v1 sh -c "python manage.py makemigrations && python manage.py migrate" |
Bu komutta, django-polls:v1 konteyner imajını çalıştırıyoruz ve –env-file bayrağını kullanarak ortam değişkeni dosyasını içeri aktarıyoruz. Ayrıca varsayılan CMD komutunu şu komutla geçersiz kılıyoruz: sh -c "python manage.py makemigrations && python manage.py migrate" Konteyneri başlatmak için bu komut çalıştırıldığında, uygulama kodunda tanımlandığı gibi veritabanı şemasını oluşturacaktır.
Başarılı olursa, aşağıdakine benzer bir çıktı görmelisiniz:

Çıktı, veritabanı şemasının başarıyla oluşturulduğunu gösterir.
Bir sonraki adım, Django uygulaması için bir yönetici kullanıcı oluşturmaktır. Konteyneri ayağa kaldıracağız ve aşağıdaki komutla içinde etkileşimli bir kabuk (shell) başlatacağız:
|
1 |
docker run -i -t --env-file env django-polls:v1 sh |
Komut, Python kabuğuyla etkileşim kurmak için kullanabileceğiniz bir kabuk istemiyle konteyneri başlatır. Bir kullanıcı oluşturalım:
|
1 |
python manage.py createsuperuser |
Kullanıcı adı, e-posta adresi, şifre girmek, şifreyi tekrar yazmak ve kullanıcıyı oluşturmak için enter tuşuna basmak üzere istemleri takip edin. Kabuktan çıkın ve şu tuşlara basarak konteyneri sonlandırın: CTRL+D.
Ardından, varsayılan komutu şu Django komutuyla geçersiz kılarak konteyneri tekrar çalıştırmamız gerekiyor: collectstatic Django komutu, uygulama için statik dosyaları oluşturur ve bunları MinIO bulut Depolama hizmetinize yükler:
|
1 |
docker run --env-file env django-polls:v1 sh -c "python manage.py collectstatic --noinput" |
Tamamlandığında, konteynerinizin MinIO depolama hizmetine başarıyla bağlandığını ve statik dosyaları yüklediğini gösteren aşağıdakine benzer bir çıktı görmelisiniz:
![]()
Depolama alanımız (bucket) artık Django'nun oluşturduğu dizinlerle birlikte şu şekilde görünüyor:

Son olarak, artık uygulamayı şu komutla çalıştırabiliriz:
|
1 |
docker run --env-file env -p 80:8000 django-polls:v1 |
İşte çıktı:

Yukarıdaki komutu çalıştırdığınızda, imajınızdaki varsayılan CMD komutunu çalıştırır ve tanımlandığı gibi 8000 portunu dışarı açar. Şimdi, Ubuntu üzerindeki 80 portu, 8000 portuna eşlenir, bu port django-polls:v1 konteynerine aittir.
Artık uygulamayı tarayıcıda test edebiliriz. Tarayıcıda sunucunuzun genel (public) IP adresine gidin: http://your_server_public_ip.
Bir 404 Sayfa Bulunamadı Hatası almayı bekleyin, çünkü Django Eğitimine göre, / yolu için bir rota tanımlamadık:

Elimizde DEBUG değişkeni True olarak ayarlanmış durumda, bu yüzden birçok kritik bilgi içeren bu hata sayfasını görüyoruz. Şimdi DEBUG değişkenini devre dışı bırakalım. İlk olarak, çalışan konteyneri CTRL+C ile durdurmanız gerekecek. Ardından, env dosyasını açın:
|
1 |
nano env |
Ardından, DEBUG değişkenini bulun ve devre dışı bırakın ya da boş bırakın. Boş bırakıyoruz çünkü getenv fonksiyonu False ifadesini bir dize (string) olarak yorumlar ve bu nedenle true değerini döndürür:
|
1 |
DEBUG= |
Dosyayı kaydedin ve konteyneri şu komutla tekrar çalıştırın:
|
1 |
docker run --env-file env -p 80:8000 django-polls:v1 |
Tarayıcınızda bu http://your_server_public_ip adresini ziyaret ederseniz, varsayılan 404 sayfasını görmelisiniz:

Kaynak kodunu değiştirmeden, ortam değişkenlerini kullanarak Django uygulamanızın çalışma zamanı davranışını nasıl değiştirebileceğinizi gördünüz.
Anketler (Polls) ana sayfasını görmek için http://your_server_public_ip/polls adresine gidin:

Uygulamayı henüz yeni dağıttığımız (deploy ettiğimiz) için hiç anketimiz yok.
Yönetici arayüzüne gidin: http://your_server_public_ip/admin yönetici kimlik doğrulama penceresini görüntülemek için:

Giriş yapmak için createsuperuser komutuyla belirlediğiniz kimlik bilgilerini girin. Artık Yönetim sayfası arayüzünde olmalısınız:

Tüm statik dosyaların kurduğumuz harici depolama servisinden sunulduğunu unutmayın. Tarayıcı pencerenizde Sağ Tıklayabilir ve Sayfa Kaynağını Görüntüle seçeneğini seçebilirsiniz.:

Bazı sorular ve seçenekler ekleyebilir ve uygulamanın genel performansını test edebilirsiniz:

Anketler dizinine geri dönün http://your_server_public_ip/polls ve soruyu oylamayı deneyin:

Her şeyin beklendiği gibi çalıştığını test edip onayladıktan sonra konteyneri sonlandırabilirsiniz.
Sonuç
Bir Django web uygulamasını konteyner tabanlı bir ortamda sorunsuz çalışacak şekilde başarıyla yapılandırdınız. Bu süreç, uygulamanın harici ortam değişkenleriyle çalışacak şekilde uyarlanmasını, statik dosyalar için bir bulut depolama servisi kullanacak şekilde ayarlanmasını ve konteyner imajı için bir Dockerfile oluşturulmasını içeriyordu. Uygulamayı Dockerize etmek için yaptığımız değişiklikleri django-polls-docker dalında (branch) görüntüleyebilirsiniz. Bu dal, django-polls GitHub deposunda yer almaktadır.
Buradan sonrası tamamen hayal gücünüze kalmış. İstemciler ile Gunicorn sunucusu arasında yer alacak bir Nginx ters proxy (reverse proxy) kurabilirsiniz. Nginx sunucunuzu güvenli hale getirmek amacıyla TLS sertifikaları almak için Certbot da ekleyebilirsiniz. Yavaş istemcileri arabelleğe almak ve Gunicorn sunucunuzu hizmet reddi (denial of service) saldırılarından korumak için bir HTTP proxy eklemenizi öneririz.
Dockerfile'ın başlangıç komutunda 3 worker tanımlamış olsak da, sunucunuzdaki mevcut kaynaklara bağlı olarak tercih ettiğiniz sayıyı belirleyebilirsiniz. Daha fazla bilgiyi resmi Gunicorn tasarım belgelerinde bulabilirsiniz. Dilerseniz oluşturduğunuz Docker imajını Dockerhub'a yükleyebilir ve Docker kurulu olan çeşitli ortamlarda dağıtmayı deneyebilirsiniz. Daha fazlasını öğrenmek isterseniz, Eğitim blogumuzu takip etmeye devam edin; zira Django uygulamasını Nginx ve Let's Encrypt ile güvenli hale getirmek için bir takip eğitimi hazırlayacağız.
Son olarak, Docker'ı kullanmanıza yardımcı olacak diğer kaynaklar şunlardır:
- Ubuntu 20.04 üzerinde GitLab Self-Managed Instance ile Docker İmaj Deposu Barındırma ve Docker İmajları Oluşturma
- Ubuntu 20.04 üzerinde Docker Veri Birimleri (Data Volumes) ile Çalışma
- Ubuntu 20.04 üzerinde Docker ile Flask Uygulaması Oluşturma ve Dağıtma
- Ubuntu 20.04 üzerinde Docker Konteynerleri ile WordPress Nasıl Dağıtılır
Keyifli Çalışmalar!
Yorumlar
Henüz yorum yapılmamış. İlk siz olun.