{"id":31726,"date":"2025-10-13T08:41:17","date_gmt":"2025-10-13T05:41:17","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=31726"},"modified":"2025-10-13T08:41:17","modified_gmt":"2025-10-13T05:41:17","slug":"django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/","title":{"rendered":"Django Uygulamas\u0131n\u0131 Docker, Nginx ve Let&#8217;s Encrypt ile \u00d6l\u00e7eklendirme ve G\u00fcvenli\u011fini Sa\u011flama"},"content":{"rendered":"<p><body><\/p>\n<h2>Django Uygulamas\u0131n\u0131 Docker, Nginx ve Let&#8217;s Encrypt ile \u00d6l\u00e7eklendirme ve G\u00fcvenli\u011fini Sa\u011flama<\/h2>\n<h2>Giri\u015f<\/h2>\n<p>Modern web uygulamalar\u0131, kullan\u0131c\u0131 beklentilerinin ve i\u015f gereksinimlerinin s\u00fcrekli artmas\u0131yla birlikte, y\u00fcksek performans, \u00f6l\u00e7eklenebilirlik, g\u00fcvenlik ve h\u0131zl\u0131 da\u011f\u0131t\u0131m gibi temel \u00f6zelliklere sahip olmak zorundad\u0131r. Python tabanl\u0131 pop\u00fcler web \u00e7er\u00e7evesi Django, h\u0131zl\u0131 geli\u015ftirme yetenekleriyle \u00f6ne \u00e7\u0131ksa da, \u00fcretim ortam\u0131nda bu beklentileri kar\u015f\u0131lamak i\u00e7in do\u011fru mimari ve teknoloji y\u0131\u011f\u0131n\u0131na ihtiya\u00e7 duyar. Bu makale, bir Django uygulamas\u0131n\u0131 Docker ile konteynerize ederek, Nginx&#8217;i ters proxy ve statik dosya sunucusu olarak kullanarak ve Let&#8217;s Encrypt ile \u00fccretsiz SSL\/TLS g\u00fcvenli\u011fi sa\u011flayarak nas\u0131l \u00f6l\u00e7eklenebilir ve g\u00fcvenli hale getirebilece\u011fimizi detayl\u0131 bir \u015fekilde ele alacakt\u0131r. Bu entegre yakla\u015f\u0131m, uygulaman\u0131z\u0131n da\u011f\u0131t\u0131m\u0131n\u0131 kolayla\u015ft\u0131rmakla kalmayacak, ayn\u0131 zamanda y\u00fcksek trafik y\u00fcklerini y\u00f6netme ve hassas verileri koruma yetene\u011fini de \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131racakt\u0131r.<\/p>\n<h2>Temel Bile\u015fenler<\/h2>\n<p>Ba\u015far\u0131l\u0131 bir da\u011f\u0131t\u0131m ve \u00f6l\u00e7eklendirme stratejisi i\u00e7in kullanaca\u011f\u0131m\u0131z temel teknolojileri ve rollerini tan\u0131yal\u0131m:<\/p>\n<h3>Docker<\/h3>\n<p>Docker, uygulamalar\u0131 ve ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 izole edilmi\u015f, hafif ve ta\u015f\u0131nabilir &#8220;konteynerler&#8221; i\u00e7inde paketlemeyi sa\u011flayan bir platformdur. Bu, &#8220;benim makinemde \u00e7al\u0131\u015f\u0131yordu&#8221; sorununu ortadan kald\u0131r\u0131r ve geli\u015ftirme, test ve \u00fcretim ortamlar\u0131 aras\u0131nda tutarl\u0131l\u0131k sa\u011flar. <code>Dockerfile<\/code> ile konteyner imajlar\u0131 olu\u015fturulur, <code>docker-compose<\/code> ile birden fazla servisi (uygulama, veritaban\u0131, Nginx vb.) tan\u0131mlay\u0131p y\u00f6netmek kolayla\u015f\u0131r.<\/p>\n<h3>Django<\/h3>\n<p>Django, &#8220;The web framework for perfectionists with deadlines&#8221; slogan\u0131yla bilinen, Python ile yaz\u0131lm\u0131\u015f y\u00fcksek seviyeli bir web \u00e7er\u00e7evesidir. H\u0131zl\u0131 geli\u015ftirme, g\u00fcvenlik ve \u00f6l\u00e7eklenebilirlik i\u00e7in bir\u00e7ok yerle\u015fik \u00f6zellik sunar.<\/p>\n<h3>Gunicorn \/ uWSGI<\/h3>\n<p>Gunicorn (Green Unicorn) veya uWSGI, Python WSGI (Web Server Gateway Interface) uygulamalar\u0131 i\u00e7in bir HTTP sunucusudur. Django gibi Python web uygulamalar\u0131n\u0131n web sunucular\u0131 (Nginx gibi) ile ileti\u015fim kurmas\u0131n\u0131 sa\u011flar. Nginx gelen istekleri Gunicorn&#8217;a iletir, Gunicorn Django uygulamas\u0131n\u0131 \u00e7al\u0131\u015ft\u0131r\u0131r ve yan\u0131t\u0131 Nginx&#8217;e geri g\u00f6nderir.<\/p>\n<h3>Nginx<\/h3>\n<p>Nginx (Engine-X), y\u00fcksek performansl\u0131, a\u00e7\u0131k kaynakl\u0131 bir web sunucusu, ters proxy, y\u00fck dengeleyici ve HTTP \u00f6nbelle\u011fidir. Django uygulamam\u0131z\u0131n \u00f6n\u00fcnde yer alarak gelen t\u00fcm istekleri kar\u015f\u0131lar. Statik dosyalar\u0131 (CSS, JS, resimler) do\u011frudan sunar, dinamik istekleri Gunicorn&#8217;a y\u00f6nlendirir ve SSL\/TLS sonland\u0131rmas\u0131n\u0131 y\u00f6netir.<\/p>\n<h3>Let&#8217;s Encrypt &#038; Certbot<\/h3>\n<p>Let&#8217;s Encrypt, \u00fccretsiz, otomatik ve a\u00e7\u0131k bir sertifika yetkilisidir (CA). Web siteleri i\u00e7in SSL\/TLS sertifikalar\u0131 sa\u011flayarak HTTPS&#8217;i yayg\u0131nla\u015ft\u0131rmay\u0131 hedefler. Certbot ise Let&#8217;s Encrypt sertifikalar\u0131n\u0131 almak ve y\u00f6netmek i\u00e7in kullan\u0131lan bir yaz\u0131l\u0131m istemcisidir. Kolay kurulum ve otomatik yenileme \u00f6zellikleri sunar.<\/p>\n<h3>PostgreSQL<\/h3>\n<p>PostgreSQL, g\u00fc\u00e7l\u00fc, a\u00e7\u0131k kaynakl\u0131, ili\u015fkisel bir veritaban\u0131 y\u00f6netim sistemidir. Django uygulamalar\u0131 i\u00e7in pop\u00fcler ve g\u00fcvenilir bir se\u00e7imdir. Docker ile konteynerize edilerek kolayca da\u011f\u0131t\u0131labilir ve y\u00f6netilebilir.<\/p>\n<h3>Redis<\/h3>\n<p>Redis, bellek i\u00e7i bir veri yap\u0131s\u0131 deposudur. \u00d6nbellekleme, oturum y\u00f6netimi, mesaj kuyruklar\u0131 (Celery ile birlikte) ve ger\u00e7ek zamanl\u0131 veri depolama gibi \u00e7e\u015fitli ama\u00e7lar i\u00e7in kullan\u0131labilir. Uygulaman\u0131n performans\u0131n\u0131 art\u0131rmak i\u00e7in kritik bir bile\u015fendir.<\/p>\n<h2>Docker ile Django Uygulamas\u0131n\u0131 Konteynerize Etme<\/h2>\n<p>Uygulamam\u0131z\u0131 Docker ile konteynerize etmek, t\u00fcm ba\u011f\u0131ml\u0131l\u0131klar\u0131 tek bir pakette toplayarak da\u011f\u0131t\u0131m\u0131 ve y\u00f6netimi basitle\u015ftirir.<\/p>\n<h3>Dockerfile Olu\u015fturma<\/h3>\n<p><code>Dockerfile<\/code>, Docker imaj\u0131m\u0131z\u0131 olu\u015fturmak i\u00e7in ad\u0131m ad\u0131m talimatlar\u0131 i\u00e7eren bir metin dosyas\u0131d\u0131r. Django uygulamam\u0131z i\u00e7in temel bir <code>Dockerfile<\/code> \u015f\u00f6yle g\u00f6r\u00fcnebilir:<\/p>\n<pre><code class=\"language-dockerfile\"># Temel imaj olarak Python 3.9'un slim versiyonunu kullan\nFROM python:3.9-slim-buster\n\n<h2>Ortam de\u011fi\u015fkenlerini ayarla<\/h2>\nENV PYTHONDONTWRITEBYTECODE 1\nENV PYTHONUNBUFFERED 1\n\n<h2>\u00c7al\u0131\u015fma dizinini ayarla<\/h2>\nWORKDIR \/app\n\n<h2>Ba\u011f\u0131ml\u0131l\u0131klar\u0131 kopyala ve y\u00fckle<\/h2>\nCOPY requirements.txt \/app\/\nRUN pip install --no-cache-dir -r requirements.txt\n\n<h2>Django proje dosyalar\u0131n\u0131 kopyala<\/h2>\nCOPY . \/app\/\n\n<h2>Statik dosyalar\u0131 topla (Gunicorn'dan \u00f6nce)<\/h2>\n<h2>Bu ad\u0131m, Django'nun statik dosyalar\u0131 STATIC_ROOT'a kopyalamas\u0131n\u0131 sa\u011flar<\/h2>\nRUN python manage.py collectstatic --noinput\n\n<h2>Uygulama portunu a\u00e7\u0131\u011fa \u00e7\u0131kar<\/h2>\nEXPOSE 8000\n\n<h2>Gunicorn ile Django uygulamas\u0131n\u0131 ba\u015flat<\/h2>\n<h2>manage.py'nin bulundu\u011fu dizinde olmal\u0131 ve projenizin ad\u0131 mysite ise mysite.wsgi:application olmal\u0131<\/h2>\nCMD [\"gunicorn\", \"--bind\", \"0.0.0.0:8000\", \"--workers\", \"3\", \"mysite.wsgi:application\"]<\/code><\/pre>\n<p><strong>A\u00e7\u0131klamalar:<\/strong><br \/>\n*   <code>FROM python:3.9-slim-buster<\/code>: K\u00fc\u00e7\u00fck boyutlu ve gerekli k\u00fct\u00fcphaneleri i\u00e7eren bir Python imaj\u0131 se\u00e7iyoruz.<br \/>\n*   <code>ENV PYTHONDONTWRITEBYTECODE 1<\/code> ve <code>ENV PYTHONUNBUFFERED 1<\/code>: Python&#8217;\u0131n <code>.pyc<\/code> dosyalar\u0131 olu\u015fturmas\u0131n\u0131 engeller ve \u00e7\u0131kt\u0131lar\u0131n arabelle\u011fe al\u0131nmamas\u0131n\u0131 sa\u011flar, bu da g\u00fcnl\u00fckleri an\u0131nda g\u00f6rmemizi sa\u011flar.<br \/>\n*   <code>WORKDIR \/app<\/code>: Konteyner i\u00e7inde \u00e7al\u0131\u015fma dizinini <code>\/app<\/code> olarak ayarlar.<br \/>\n*   <code>COPY requirements.txt \/app\/<\/code> ve <code>RUN pip install --no-cache-dir -r requirements.txt<\/code>: \u00d6nce ba\u011f\u0131ml\u0131l\u0131k dosyas\u0131n\u0131 kopyalay\u0131p kurar\u0131z. Bu, <code>requirements.txt<\/code> de\u011fi\u015fmedi\u011fi s\u00fcrece <code>pip install<\/code> ad\u0131m\u0131n\u0131n Docker katman \u00f6nbelle\u011finden yararlanmas\u0131n\u0131 sa\u011flar.<br \/>\n*   <code>COPY . \/app\/<\/code>: Projenin geri kalan\u0131n\u0131 \u00e7al\u0131\u015fma dizinine kopyalar.<br \/>\n*   <code>RUN python manage.py collectstatic --noinput<\/code>: Django&#8217;nun statik dosyalar\u0131n\u0131 (<code>STATIC_ROOT<\/code> ayar\u0131nda belirtilen dizine) toplar. Bu, Nginx&#8217;in bu dosyalara kolayca eri\u015fmesini sa\u011flar. <code>--noinput<\/code> kullan\u0131c\u0131 etkile\u015fimini engeller.<br \/>\n*   <code>EXPOSE 8000<\/code>: Konteynerin 8000 numaral\u0131 portu dinleyece\u011fini belirtir.<br \/>\n*   <code>CMD [\"gunicorn\", ...]<\/code>: Konteyner ba\u015flat\u0131ld\u0131\u011f\u0131nda \u00e7al\u0131\u015ft\u0131r\u0131lacak varsay\u0131lan komutu tan\u0131mlar. Gunicorn&#8217;u <code>0.0.0.0:8000<\/code> adresinde 3 worker ile <code>mysite.wsgi:application<\/code> uygulamas\u0131n\u0131 \u00e7al\u0131\u015ft\u0131rmak \u00fczere yap\u0131land\u0131r\u0131r\u0131z.<\/p>\n<h3>docker-compose.yml ile Servisleri Tan\u0131mlama<\/h3>\n<p><code>docker-compose.yml<\/code> dosyas\u0131, uygulaman\u0131n t\u00fcm servislerini (Django, PostgreSQL, Nginx, Redis, Certbot) tek bir dosya i\u00e7inde tan\u0131mlamam\u0131z\u0131 sa\u011flar. Bu, \u00e7oklu konteynerli uygulamalar\u0131 y\u00f6netmek i\u00e7in idealdir.<\/p>\n<pre><code class=\"language-yaml\">version: '3.8'\n\nservices:\n  web:\n    build: .\n    command: gunicorn mysite.wsgi:application --bind 0.0.0.0:8000 --workers 3\n    volumes:\n      - .:\/app\n      - static_volume:\/app\/staticfiles\n      - media_volume:\/app\/mediafiles\n    expose:\n      - 8000\n    env_file:\n      - .env\n    depends_on:\n      - db\n      - redis\n    networks:\n      - app_network\n\n  nginx:\n    image: nginx:latest\n    ports:\n      - \"80:80\"\n      - \"443:443\"\n    volumes:\n      - .\/nginx\/nginx.conf:\/etc\/nginx\/conf.d\/default.conf\n      - static_volume:\/app\/staticfiles\n      - media_volume:\/app\/mediafiles\n      - certbot_conf:\/etc\/letsencrypt\n      - certbot_www:\/var\/www\/certbot\n    depends_on:\n      - web\n    networks:\n      - app_network\n\n  db:\n    image: postgres:13\n    environment:\n      POSTGRES_DB: ${DB_NAME}\n      POSTGRES_USER: ${DB_USER}\n      POSTGRES_PASSWORD: ${DB_PASSWORD}\n    volumes:\n      - postgres_data:\/var\/lib\/postgresql\/data\/\n    networks:\n      - app_network\n\n  redis:\n    image: redis:6\n    networks:\n      - app_network\n\n  certbot:\n    image: certbot\/certbot\n    volumes:\n      - certbot_conf:\/etc\/letsencrypt\n      - certbot_www:\/var\/www\/certbot\n    # Certbot'u sadece manuel olarak \u00e7al\u0131\u015ft\u0131rmak i\u00e7in, otomatik ba\u015flatmay\u0131 engeller\n    entrypoint: \"\/bin\/sh -c 'trap exit TERM; while :; do sleep 1d & wait $!; done;'\"\n    networks:\n      - app_network\n\nvolumes:\n  postgres_data:\n  static_volume:\n  media_volume:\n  certbot_conf:\n  certbot_www:\n\nnetworks:\n  app_network:\n    driver: bridge<\/code><\/pre>\n<p><strong>A\u00e7\u0131klamalar:<\/strong><br \/>\n*   <code>web<\/code>: Django uygulamam\u0131z\u0131 i\u00e7eren servis. <code>build: .<\/code> ile mevcut dizindeki <code>Dockerfile<\/code>&#8216;\u0131 kullan\u0131r. <code>volumes<\/code> ile kodumuzu, statik ve medya dosyalar\u0131n\u0131 konteyner ile e\u015fle\u015ftiririz. <code>expose<\/code> ile 8000 portunu di\u011fer servislere a\u00e7ar\u0131z. <code>.env<\/code> dosyas\u0131ndan ortam de\u011fi\u015fkenlerini y\u00fckleriz. <code>db<\/code> ve <code>redis<\/code> servislerine ba\u011f\u0131ml\u0131d\u0131r.<br \/>\n*   <code>nginx<\/code>: Nginx web sunucusu. 80 ve 443 portlar\u0131n\u0131 host makineye a\u00e7ar. Nginx yap\u0131land\u0131rma dosyam\u0131z\u0131, statik\/medya dosyalar\u0131n\u0131 ve Let&#8217;s Encrypt sertifikalar\u0131n\u0131 konteynere ba\u011flar. <code>web<\/code> servisine ba\u011f\u0131ml\u0131d\u0131r.<br \/>\n*   <code>db<\/code>: PostgreSQL veritaban\u0131. Ortam de\u011fi\u015fkenleri ile veritaban\u0131 ad\u0131, kullan\u0131c\u0131 ve \u015fifre ayarlan\u0131r. <code>postgres_data<\/code> volume&#8217;u ile veritaban\u0131 verilerinin kal\u0131c\u0131l\u0131\u011f\u0131 sa\u011flan\u0131r.<br \/>\n*   <code>redis<\/code>: Redis \u00f6nbellek\/mesaj kuyru\u011fu servisi.<br \/>\n*   <code>certbot<\/code>: Let&#8217;s Encrypt sertifikalar\u0131n\u0131 almak i\u00e7in kullan\u0131lan Certbot istemcisi. <code>certbot_conf<\/code> ve <code>certbot_www<\/code> volume&#8217;lar\u0131 ile sertifikalar\u0131n ve ge\u00e7ici do\u011frulama dosyalar\u0131n\u0131n kal\u0131c\u0131l\u0131\u011f\u0131 sa\u011flan\u0131r. <code>entrypoint<\/code> komutu, Certbot&#8217;un otomatik olarak \u00e7al\u0131\u015fmas\u0131n\u0131 engeller, b\u00f6ylece manuel olarak veya cron job ile kontrol edebiliriz.<br \/>\n*   <code>volumes<\/code>: Verilerin konteynerler aras\u0131nda ve host makinede kal\u0131c\u0131 olmas\u0131n\u0131 sa\u011flar.<br \/>\n*   <code>networks<\/code>: Servislerin birbirleriyle g\u00fcvenli bir \u015fekilde ileti\u015fim kurmas\u0131n\u0131 sa\u011flar. <code>app_network<\/code> ad\u0131nda \u00f6zel bir a\u011f tan\u0131mlar\u0131z.<\/p>\n<h2>Veritaban\u0131 ve \u00d6nbellek Y\u00f6netimi<\/h2>\n<h3>PostgreSQL Konfig\u00fcrasyonu<\/h3>\n<p><code>docker-compose.yml<\/code> dosyas\u0131nda <code>db<\/code> servisi ile PostgreSQL&#8217;i kolayca kurduk. Django uygulamas\u0131n\u0131n bu veritaban\u0131na ba\u011flanmas\u0131 i\u00e7in <code>settings.py<\/code> dosyas\u0131nda a\u015fa\u011f\u0131daki gibi bir yap\u0131land\u0131rma yapmal\u0131y\u0131z:<\/p>\n<pre><code class=\"language-python\"># mysite\/settings.py\nimport os\n\nDATABASES = {\n    'default': {\n        'ENGINE': 'django.db.backends.postgresql',\n        'NAME': os.environ.get('DB_NAME'),\n        'USER': os.environ.get('DB_USER'),\n        'PASSWORD': os.environ.get('DB_PASSWORD'),\n        'HOST': 'db',  # docker-compose.yml'deki servis ad\u0131\n        'PORT': '5432',\n    }\n}<\/code><\/pre>\n<p><code>HOST: 'db'<\/code> k\u0131sm\u0131 \u00f6nemlidir; Docker a\u011f\u0131nda servisler birbirlerini servis adlar\u0131yla g\u00f6rebilirler. Veritaban\u0131 kimlik bilgileri <code>.env<\/code> dosyas\u0131ndan ortam de\u011fi\u015fkenleri olarak al\u0131n\u0131r.<\/p>\n<h3>Redis Konfig\u00fcrasyonu<\/h3>\n<p>Redis, Django&#8217;da \u00f6nbellekleme, oturum y\u00f6netimi veya Celery gibi g\u00f6rev kuyruklar\u0131 i\u00e7in kullan\u0131labilir. Django&#8217;da Redis&#8217;i \u00f6nbellek olarak kullanmak i\u00e7in <code>django-redis<\/code> k\u00fct\u00fcphanesini kurup <code>settings.py<\/code>&#8216;de yap\u0131land\u0131rman\u0131z gerekir:<\/p>\n<pre><code class=\"language-python\"># requirements.txt\ndjango-redis<\/code><\/pre>\n<pre><code class=\"language-python\"># mysite\/settings.py\nCACHES = {\n    \"default\": {\n        \"BACKEND\": \"django_redis.cache.RedisCache\",\n        \"LOCATION\": \"redis:\/\/redis:6379\/1\", # docker-compose.yml'deki servis ad\u0131\n        \"OPTIONS\": {\n            \"CLIENT_CLASS\": \"django_redis.client.DefaultClient\",\n        }\n    }\n}\n\n<h2>Oturumlar\u0131 Redis'te saklamak isterseniz:<\/h2>\n<h2>SESSION_ENGINE = \"django.contrib.sessions.backends.cache\"<\/h2>\n<h2>SESSION_CACHE_ALIAS = \"default\"<\/code><\/pre>\n<\/h2>\n<p>Burada <code>LOCATION: \"redis:\/\/redis:6379\/1\"<\/code> ifadesi, Redis servisinin ad\u0131n\u0131n <code>redis<\/code> oldu\u011funu belirtir.<\/p>\n<h2>Gunicorn ile Django Uygulamas\u0131n\u0131 Sunma<\/h2>\n<p>Gunicorn, Django uygulaman\u0131z ile Nginx aras\u0131nda bir aray\u00fcz g\u00f6revi g\u00f6r\u00fcr. Nginx&#8217;ten gelen istekleri al\u0131r, Django&#8217;ya iletir, Django&#8217;dan gelen yan\u0131tlar\u0131 Nginx&#8217;e geri g\u00f6nderir.<\/p>\n<h3>Gunicorn&#8217;un Rol\u00fc<\/h3>\n<p>Gunicorn, tek bir s\u00fcreci birden fazla worker s\u00fcrecine b\u00f6lerek e\u015fzamanl\u0131 istekleri i\u015fleyebilir. Bu, uygulaman\u0131z\u0131n daha fazla kullan\u0131c\u0131ya hizmet vermesini sa\u011flar. Nginx, statik dosyalar\u0131 do\u011frudan sunarak Gunicorn&#8217;un yaln\u0131zca dinamik isteklerle ilgilenmesini sa\u011flar, bu da Gunicorn&#8217;un verimlili\u011fini art\u0131r\u0131r.<\/p>\n<h3>Gunicorn Yap\u0131land\u0131rmas\u0131<\/h3>\n<p><code>Dockerfile<\/code> ve <code>docker-compose.yml<\/code> i\u00e7inde Gunicorn&#8217;u nas\u0131l ba\u015flatt\u0131\u011f\u0131m\u0131z\u0131 g\u00f6rd\u00fck. <code>--workers<\/code> parametresi, Gunicorn&#8217;un ka\u00e7 worker s\u00fcreci \u00e7al\u0131\u015ft\u0131raca\u011f\u0131n\u0131 belirler. Genellikle <code>(2 * CPU_\u00e7ekirdek_say\u0131s\u0131) + 1<\/code> form\u00fcl\u00fc \u00f6nerilir. \u00d6rne\u011fin, 2 \u00e7ekirdekli bir sunucuda 5 worker uygun olabilir.<br \/>\n<code>--bind 0.0.0.0:8000<\/code> komutu, Gunicorn&#8217;un t\u00fcm a\u011f aray\u00fczlerinde 8000 portunu dinlemesini sa\u011flar. Bu, Nginx&#8217;in ayn\u0131 Docker a\u011f\u0131nda Gunicorn&#8217;a eri\u015febilmesi i\u00e7in gereklidir.<\/p>\n<h2>Nginx ile Ters Proxy ve Statik Dosya Sunumu<\/h2>\n<p>Nginx, uygulaman\u0131z\u0131n d\u0131\u015f d\u00fcnyaya a\u00e7\u0131lan kap\u0131s\u0131d\u0131r. Gelen t\u00fcm web isteklerini kar\u015f\u0131lar ve bunlar\u0131 uygun servislere y\u00f6nlendirir.<\/p>\n<h3>Nginx&#8217;in Rol\u00fc<\/h3>\n<p>*   <strong>Ters Proxy:<\/strong> \u0130stemcilerden gelen dinamik istekleri Django&#8217;nun Gunicorn servisine iletir ve yan\u0131tlar\u0131 geri g\u00f6nderir.<br \/>\n*   <strong>Statik Dosya Sunumu:<\/strong> CSS, JavaScript, resimler gibi statik dosyalar\u0131 do\u011frudan kendi \u00fczerinden sunar. Bu, Gunicorn ve Django&#8217;nun bu y\u00fckten kurtulmas\u0131n\u0131 sa\u011flar ve performans\u0131 art\u0131r\u0131r.<br \/>\n*   <strong>SSL Sonland\u0131rma:<\/strong> Let&#8217;s Encrypt sertifikalar\u0131n\u0131 kullanarak HTTPS trafi\u011fini \u015fifreler ve \u015fifresini \u00e7\u00f6zer.<br \/>\n*   <strong>Y\u00fck Dengeleme:<\/strong> Birden fazla Django uygulama konteyneri varsa, gelen istekleri bunlar aras\u0131nda da\u011f\u0131tabilir.<\/p>\n<h3>Nginx Yap\u0131land\u0131rmas\u0131 (<code>nginx\/nginx.conf<\/code>)<\/h3>\n<p>Nginx yap\u0131land\u0131rmas\u0131, <code>docker-compose.yml<\/code> dosyas\u0131nda <code>nginx<\/code> servisine ba\u011flad\u0131\u011f\u0131m\u0131z <code>nginx\/nginx.conf<\/code> dosyas\u0131nda yap\u0131l\u0131r.<\/p>\n<pre><code class=\"language-nginx\"># nginx\/nginx.conf\nupstream django {\n    server web:8000; # docker-compose.yml'deki web servisinin ad\u0131 ve portu\n}\n\nserver {\n    listen 80;\n    server_name your_domain.com www.your_domain.com; # Kendi alan ad\u0131n\u0131z\u0131 buraya yaz\u0131n\n\n    location \/.well-known\/acme-challenge\/ {\n        root \/var\/www\/certbot;\n    }\n\n    location \/ {\n        return 301 https:\/\/$host$request_uri; # HTTP'den HTTPS'ye y\u00f6nlendirme\n    }\n}\n\nserver {\n    listen 443 ssl;\n    server_name your_domain.com www.your_domain.com; # Kendi alan ad\u0131n\u0131z\u0131 buraya yaz\u0131n\n\n    ssl_certificate \/etc\/letsencrypt\/live\/your_domain.com\/fullchain.pem;\n    ssl_certificate_key \/etc\/letsencrypt\/live\/your_domain.com\/privkey.pem;\n\n    include \/etc\/letsencrypt\/options-ssl-nginx.conf;\n    ssl_dhparam \/etc\/letsencrypt\/ssl-dhparams.pem;\n\n    location \/static\/ {\n        alias \/app\/staticfiles\/; # Django'nun collectstatic ile toplad\u0131\u011f\u0131 dosyalar\n    }\n\n    location \/media\/ {\n        alias \/app\/mediafiles\/; # Kullan\u0131c\u0131 taraf\u0131ndan y\u00fcklenen medya dosyalar\u0131\n    }\n\n    location \/ {\n        proxy_pass http:\/\/django;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header Host $host;\n        proxy_redirect off;\n    }\n}<\/code><\/pre>\n<p><strong>A\u00e7\u0131klamalar:<\/strong><br \/>\n*   <code>upstream django<\/code>: Nginx&#8217;in istekleri iletece\u011fi Django uygulamas\u0131n\u0131n adresini tan\u0131mlar. <code>web:8000<\/code>, Docker a\u011f\u0131nda <code>web<\/code> servisinin 8000 portunu ifade eder.<br \/>\n*   \u0130lk <code>server<\/code> blo\u011fu (port 80):<br \/>\n    *   <code>listen 80<\/code>: Gelen HTTP isteklerini dinler.<br \/>\n    *   <code>server_name<\/code>: Alan adlar\u0131n\u0131z\u0131 belirtin.<br \/>\n    *   <code>location \/.well-known\/acme-challenge\/<\/code>: Certbot&#8217;un alan ad\u0131 do\u011frulamas\u0131 i\u00e7in kulland\u0131\u011f\u0131 \u00f6zel yolu tan\u0131mlar. Bu yol, Certbot&#8217;un ge\u00e7ici dosyalar\u0131n\u0131 bulabilmesi i\u00e7in <code>certbot_www<\/code> volume&#8217;una ba\u011flan\u0131r.<br \/>\n    *   <code>return 301 https:\/\/$host$request_uri;<\/code>: T\u00fcm HTTP isteklerini HTTPS&#8217;ye y\u00f6nlendirir.<br \/>\n*   \u0130kinci <code>server<\/code> blo\u011fu (port 443):<br \/>\n    *   <code>listen 443 ssl<\/code>: Gelen HTTPS isteklerini dinler.<br \/>\n    *   <code>ssl_certificate<\/code> ve <code>ssl_certificate_key<\/code>: Let&#8217;s Encrypt taraf\u0131ndan sa\u011flanan SSL sertifika ve anahtar dosyalar\u0131n\u0131n yollar\u0131n\u0131 belirtir.<br \/>\n    *   <code>include \/etc\/letsencrypt\/options-ssl-nginx.conf;<\/code> ve <code>ssl_dhparam \/etc\/letsencrypt\/ssl-dhparams.pem;<\/code>: Certbot&#8217;un g\u00fcvenli SSL yap\u0131land\u0131rma ayarlar\u0131n\u0131 i\u00e7erir.<br \/>\n    *   <code>location \/static\/<\/code> ve <code>location \/media\/<\/code>: Statik ve medya dosyalar\u0131n\u0131 do\u011frudan Nginx \u00fczerinden sunar. <code>alias<\/code> y\u00f6nergesi, bu yollar\u0131n ger\u00e7ek dosya sistemindeki kar\u015f\u0131l\u0131klar\u0131n\u0131 belirtir.<br \/>\n    *   <code>location \/<\/code>: Di\u011fer t\u00fcm istekleri <code>django<\/code> upstream&#8217;ine (yani Gunicorn&#8217;a) <code>proxy_pass<\/code> ile iletir. <code>proxy_set_header<\/code> y\u00f6nergeleri, orijinal istemci bilgilerini (IP adresi, host ad\u0131) Gunicorn&#8217;a iletmek i\u00e7in \u00f6nemlidir.<\/p>\n<h2>Let&#8217;s Encrypt ile SSL\/TLS G\u00fcvenli\u011fi<\/h2>\n<p>HTTPS, modern web uygulamalar\u0131 i\u00e7in bir zorunluluktur. Let&#8217;s Encrypt, bu g\u00fcvenli\u011fi \u00fccretsiz ve kolayca sa\u011flaman\u0131n en pop\u00fcler yoludur.<\/p>\n<h3>Neden SSL\/TLS?<\/h3>\n<p>*   <strong>Veri \u015eifrelemesi:<\/strong> Kullan\u0131c\u0131 ile sunucu aras\u0131ndaki t\u00fcm ileti\u015fimi \u015fifreleyerek hassas verilerin (\u015fifreler, kredi kart\u0131 bilgileri) g\u00fcvenli\u011fini sa\u011flar.<br \/>\n*   <strong>Kimlik Do\u011frulama:<\/strong> Web sitesinin ger\u00e7ekten iddia etti\u011fi site oldu\u011funu do\u011frular, man-in-the-middle sald\u0131r\u0131lar\u0131n\u0131 \u00f6nler.<br \/>\n*   <strong>SEO Faydalar\u0131:<\/strong> Google, HTTPS kullanan siteleri arama sonu\u00e7lar\u0131nda daha \u00fcst s\u0131ralara \u00e7\u0131kar\u0131r.<br \/>\n*   <strong>Taray\u0131c\u0131 G\u00fcvenli\u011fi:<\/strong> Modern taray\u0131c\u0131lar, HTTPS kullanmayan siteleri &#8220;G\u00fcvenli De\u011fil&#8221; olarak i\u015faretler.<\/p>\n<h3>Certbot ile Sertifika Alma<\/h3>\n<p>Sertifika almak i\u00e7in <code>docker-compose.yml<\/code> dosyas\u0131ndaki <code>certbot<\/code> servisini kullanaca\u011f\u0131z. \u0130lk sertifika alma i\u015flemi, Nginx&#8217;in 80 portunu kullanarak Certbot&#8217;un alan ad\u0131 sahipli\u011fini do\u011frulamas\u0131na izin vermelidir.<\/p>\n<p><strong>Ad\u0131m 1: Nginx&#8217;i sadece 80 portunu dinleyecek \u015fekilde ba\u015flat\u0131n (ge\u00e7ici olarak HTTPS y\u00f6nlendirmesi olmadan).<\/strong><br \/>\nYukar\u0131daki <code>nginx.conf<\/code> dosyas\u0131nda 80 portu i\u00e7in <code>location \/.well-known\/acme-challenge\/<\/code> blo\u011fu ve <code>return 301 https:\/\/...<\/code> y\u00f6nlendirmesi zaten mevcut. Bu, Certbot&#8217;un do\u011frulama yaparken HTTP&#8217;den HTTPS&#8217;ye y\u00f6nlendirilmesini engeller.<\/p>\n<p><strong>Ad\u0131m 2: Certbot ile sertifika al\u0131n.<\/strong><br \/>\n\u0130lk sertifikay\u0131 almak i\u00e7in <code>docker-compose.yml<\/code> dosyas\u0131ndaki <code>certbot<\/code> servisini kullan\u0131n:<\/p>\n<pre><code class=\"language-bash\">docker-compose run --rm certbot certonly --webroot --webroot-path \/var\/www\/certbot -d your_domain.com -d www.your_domain.com<\/code><\/pre>\n<p>*   <code>--rm<\/code>: Komut bittikten sonra konteyneri kald\u0131r\u0131r.<br \/>\n*   <code>certonly<\/code>: Sadece sertifika al\u0131r, Nginx yap\u0131land\u0131rmas\u0131n\u0131 otomatik de\u011fi\u015ftirmez.<br \/>\n*   <code>--webroot<\/code>: Webroot do\u011frulama y\u00f6ntemini kullan\u0131r.<br \/>\n*   <code>--webroot-path \/var\/www\/certbot<\/code>: Certbot&#8217;un do\u011frulama dosyalar\u0131n\u0131 yerle\u015ftirece\u011fi dizini belirtir. Bu dizin <code>nginx<\/code> servisi ile de payla\u015f\u0131l\u0131r.<br \/>\n*   <code>-d your_domain.com -d www.your_domain.com<\/code>: Sertifika almak istedi\u011finiz alan adlar\u0131n\u0131 belirtin.<\/p>\n<p>Bu komutu \u00e7al\u0131\u015ft\u0131rd\u0131ktan sonra e-posta adresinizi girmeniz ve hizmet \u015fartlar\u0131n\u0131 kabul etmeniz istenecektir. Sertifikalar <code>\/etc\/letsencrypt\/live\/your_domain.com\/<\/code> dizinine kaydedilecektir.<\/p>\n<p><strong>Ad\u0131m 3: Nginx&#8217;i sertifikalarla birlikte yeniden ba\u015flat\u0131n.<\/strong><br \/>\nSertifikalar al\u0131nd\u0131ktan sonra, <code>nginx.conf<\/code> dosyan\u0131zdaki SSL ayarlar\u0131n\u0131n do\u011fru oldu\u011fundan emin olun ve t\u00fcm servisleri yeniden ba\u015flat\u0131n:<\/p>\n<pre><code class=\"language-bash\">docker-compose down\ndocker-compose up -d<\/code><\/pre>\n<p>Art\u0131k siteniz HTTPS \u00fczerinden eri\u015filebilir olmal\u0131d\u0131r.<\/p>\n<h3>Otomatik Yenileme<\/h3>\n<p>Let&#8217;s Encrypt sertifikalar\u0131 90 g\u00fcn ge\u00e7erlidir. Otomatik yenileme, sertifikalar\u0131n\u0131z\u0131n s\u00fcresi dolmadan \u00f6nce g\u00fcncellenmesini sa\u011flar. Bunu bir <code>cron<\/code> i\u015fi veya <code>docker-compose<\/code> komutu ile yapabiliriz.<\/p>\n<p><code>docker-compose.yml<\/code> dosyas\u0131nda <code>certbot<\/code> servisi i\u00e7in <code>entrypoint<\/code> komutunu de\u011fi\u015ftirerek Certbot&#8217;un otomatik olarak yenileme yapmas\u0131n\u0131 sa\u011flayabiliriz:<\/p>\n<pre><code class=\"language-yaml\">certbot:\n    image: certbot\/certbot\n    volumes:\n      - certbot_conf:\/etc\/letsencrypt\n      - certbot_www:\/var\/www\/certbot\n    entrypoint: \"\/bin\/sh -c 'trap exit TERM; while :; do certbot renew --webroot -w \/var\/www\/certbot --post-hook \\\"nginx -s reload\\\"; sleep 12h & wait $!; done;'\"\n    networks:\n      - app_network<\/code><\/pre>\n<p>Bu <code>entrypoint<\/code> komutu, her 12 saatte bir <code>certbot renew<\/code> komutunu \u00e7al\u0131\u015ft\u0131r\u0131r. <code>renew<\/code> komutu sadece sertifikalar\u0131n s\u00fcresi dolmak \u00fczereyse yenileme yapar. <code>--post-hook \"nginx -s reload\"<\/code> komutu ise yenileme ba\u015far\u0131l\u0131 oldu\u011funda Nginx&#8217;i yeniden y\u00fckleyerek yeni sertifikalar\u0131n devreye girmesini sa\u011flar.<\/p>\n<h2>\u00d6l\u00e7eklendirme Stratejileri<\/h2>\n<p>Uygulaman\u0131z b\u00fcy\u00fcd\u00fck\u00e7e, daha fazla iste\u011fi i\u015flemek i\u00e7in \u00f6l\u00e7eklendirmeye ihtiya\u00e7 duyacaks\u0131n\u0131z. Docker ve Nginx bu konuda \u00f6nemli avantajlar sunar.<\/p>\n<h3>Django Uygulamas\u0131n\u0131 \u00d6l\u00e7eklendirme<\/h3>\n<p><code>docker-compose<\/code> ile Django uygulama konteynerlerini kolayca \u00f6l\u00e7eklendirebilirsiniz:<\/p>\n<pre><code class=\"language-bash\">docker-compose up -d --scale web=3<\/code><\/pre>\n<p>Bu komut, <code>web<\/code> servisi i\u00e7in 3 adet konteyner \u00f6rne\u011fi ba\u015flat\u0131r. Nginx&#8217;in <code>upstream<\/code> yap\u0131land\u0131rmas\u0131, varsay\u0131lan olarak bu birden fazla <code>web<\/code> servisi \u00f6rne\u011fi aras\u0131nda y\u00fck dengeleme yapacakt\u0131r. Ancak daha geli\u015fmi\u015f y\u00fck dengeleme stratejileri i\u00e7in Nginx yap\u0131land\u0131rmas\u0131nda <code>least_conn<\/code> veya <code>ip_hash<\/code> gibi y\u00f6ntemler kullan\u0131labilir.<\/p>\n<p>Uygulaman\u0131z\u0131n birden fazla \u00f6rne\u011finin sorunsuz \u00e7al\u0131\u015fmas\u0131 i\u00e7in &#8220;stateless&#8221; (durumsuz) olmas\u0131 \u00f6nemlidir. Oturum verilerini, \u00f6nbellekleri ve di\u011fer durum bilgilerini uygulama konteynerinde de\u011fil, veritaban\u0131 veya Redis gibi harici, payla\u015f\u0131ml\u0131 bir depolama sisteminde tutmal\u0131s\u0131n\u0131z.<\/p>\n<h3>Veritaban\u0131 \u00d6l\u00e7eklendirme<\/h3>\n<p>PostgreSQL gibi ili\u015fkisel veritabanlar\u0131 dikey olarak (daha g\u00fc\u00e7l\u00fc bir sunucuya ge\u00e7erek) veya yatay olarak \u00f6l\u00e7eklenebilir. Yatay \u00f6l\u00e7eklendirme genellikle \u015funlar\u0131 i\u00e7erir:<br \/>\n*   <strong>Okuma Replikalar\u0131 (Read Replicas):<\/strong> Okuma yo\u011fun uygulamalar i\u00e7in ana veritaban\u0131n\u0131n kopyalar\u0131n\u0131 olu\u015fturarak okuma isteklerini bu replikalara y\u00f6nlendirmek.<br \/>\n*   <strong>Sharding:<\/strong> Veritaban\u0131n\u0131 daha k\u00fc\u00e7\u00fck, ba\u011f\u0131ms\u0131z par\u00e7alara b\u00f6lmek ve her par\u00e7ay\u0131 ayr\u0131 bir sunucuda bar\u0131nd\u0131rmak. Bu, daha karma\u015f\u0131k bir \u00e7\u00f6z\u00fcmd\u00fcr ve uygulaman\u0131n mimarisinde de\u011fi\u015fiklikler gerektirebilir.<\/p>\n<h3>\u00d6nbellek \u00d6l\u00e7eklendirme<\/h3>\n<p>Redis, zaten bellek i\u00e7i ve h\u0131zl\u0131 bir \u00e7\u00f6z\u00fcmd\u00fcr. Tek bir Redis konteyneri genellikle \u00e7o\u011fu uygulama i\u00e7in yeterlidir. Ancak \u00e7ok y\u00fcksek trafikli senaryolarda Redis Cluster gibi da\u011f\u0131t\u0131k \u00e7\u00f6z\u00fcmler d\u00fc\u015f\u00fcn\u00fclebilir.<\/p>\n<h2>G\u00fcvenlik En \u0130yi Uygulamalar\u0131<\/h2>\n<p>\u00d6l\u00e7eklenebilirlik kadar g\u00fcvenlik de kritik \u00f6neme sahiptir.<\/p>\n<h3>Hassas Bilgilerin Y\u00f6netimi<\/h3>\n<p>*   <strong>Ortam De\u011fi\u015fkenleri:<\/strong> Django <code>SECRET_KEY<\/code>, veritaban\u0131 kimlik bilgileri, API anahtarlar\u0131 gibi hassas bilgileri do\u011frudan kodda veya s\u00fcr\u00fcm kontrol sisteminde saklamay\u0131n. Bunlar\u0131 <code>.env<\/code> dosyalar\u0131 arac\u0131l\u0131\u011f\u0131yla ortam de\u011fi\u015fkenleri olarak y\u00f6netin ve <code>.env<\/code> dosyas\u0131n\u0131 <code>.gitignore<\/code>&#8216;a ekleyin.<br \/>\n*   <strong>Docker Secrets:<\/strong> \u00dcretim ortam\u0131nda daha g\u00fcvenli bir y\u00f6ntem olarak Docker Secrets veya Kubernetes Secrets kullanmay\u0131 d\u00fc\u015f\u00fcn\u00fcn.<\/p>\n<h3>A\u011f \u0130zolasyonu<\/h3>\n<p><code>docker-compose<\/code> taraf\u0131ndan olu\u015fturulan \u00f6zel a\u011flar, servislerin birbirleriyle g\u00fcvenli bir \u015fekilde ileti\u015fim kurmas\u0131n\u0131 sa\u011flar. Servisleri sadece ihtiya\u00e7 duyduklar\u0131 portlardan ve di\u011fer servislerden eri\u015filebilir hale getirin. \u00d6rne\u011fin, PostgreSQL&#8217;in d\u0131\u015f d\u00fcnyaya a\u00e7\u0131lmas\u0131na izin vermeyin, sadece <code>web<\/code> servisi taraf\u0131ndan eri\u015filebilir olsun.<\/p>\n<h3>G\u00fcvenlik Duvar\u0131 (Firewall)<\/h3>\n<p>Sunucunuzda bir g\u00fcvenlik duvar\u0131 (\u00f6rn. UFW veya <code>iptables<\/code>) etkinle\u015ftirin ve sadece gerekli portlara (80, 443, SSH) d\u0131\u015far\u0131dan eri\u015fime izin verin. Di\u011fer t\u00fcm portlar\u0131 kapat\u0131n.<\/p>\n<h3>G\u00fcnl\u00fckleme ve \u0130zleme<\/h3>\n<p>Uygulama, Nginx ve veritaban\u0131 g\u00fcnl\u00fcklerini d\u00fczenli olarak izleyin. Merkezi bir g\u00fcnl\u00fckleme sistemi (ELK Stack, Grafana Loki vb.) kullanarak t\u00fcm g\u00fcnl\u00fckleri tek bir yerden toplay\u0131p analiz etmek, sorunlar\u0131 tespit etmek ve g\u00fcvenlik olaylar\u0131n\u0131 izlemek i\u00e7in \u00e7ok \u00f6nemlidir. Prometheus ve Grafana gibi ara\u00e7larla performans metriklerini izlemek de proaktif bir g\u00fcvenlik ve performans y\u00f6netimi sa\u011flar.<\/p>\n<h3>G\u00fcncel Tutma<\/h3>\n<p>Kulland\u0131\u011f\u0131n\u0131z t\u00fcm yaz\u0131l\u0131mlar\u0131 ve ba\u011f\u0131ml\u0131l\u0131klar\u0131 (Python, Django, Nginx, PostgreSQL, Redis, Docker imajlar\u0131, k\u00fct\u00fcphaneler) d\u00fczenli olarak g\u00fcncelleyin. G\u00fcvenlik a\u00e7\u0131klar\u0131 genellikle eski s\u00fcr\u00fcmlerde bulunur ve g\u00fcncellemelerle giderilir.<\/p>\n<h2>Da\u011f\u0131t\u0131m ve Otomasyon<\/h2>\n<p>\u00dcretim ortam\u0131na da\u011f\u0131t\u0131m s\u00fcreci, otomasyon ile \u00e7ok daha verimli ve hatas\u0131z hale getirilebilir.<\/p>\n<h3>\u00dcretim Ortam\u0131na Da\u011f\u0131t\u0131m<\/h3>\n<p>Da\u011f\u0131t\u0131m yapmadan \u00f6nce <code>docker-compose.prod.yml<\/code> gibi ayr\u0131 bir dosya kullanarak \u00fcretim ortam\u0131na \u00f6zel ayarlar\u0131 (\u00f6rne\u011fin, geli\u015ftirme i\u00e7in kullan\u0131lan bind mount&#8217;lar\u0131 kald\u0131rmak, daha g\u00fcvenli imajlar kullanmak) tan\u0131mlayabilirsiniz.<br \/>\nDa\u011f\u0131t\u0131m s\u0131ras\u0131nda \u00e7al\u0131\u015ft\u0131rman\u0131z gereken \u00f6nemli komutlar:<br \/>\n*   <code>docker-compose exec web python manage.py migrate<\/code>: Veritaban\u0131 \u015femas\u0131 g\u00fcncellemelerini uygular.<br \/>\n*   <code>docker-compose exec web python manage.py collectstatic --noinput<\/code>: Statik dosyalar\u0131 tekrar toplar (e\u011fer kodda de\u011fi\u015fiklikler varsa).<\/p>\n<h3>S\u00fcrekli Entegrasyon\/S\u00fcrekli Da\u011f\u0131t\u0131m (CI\/CD)<\/h3>\n<p>CI\/CD i\u015flem hatlar\u0131, kod de\u011fi\u015fikliklerinin otomatik olarak test edilmesini, Docker imajlar\u0131n\u0131n olu\u015fturulmas\u0131n\u0131 ve \u00fcretim ortam\u0131na da\u011f\u0131t\u0131lmas\u0131n\u0131 sa\u011flar. GitHub Actions, GitLab CI\/CD, Jenkins veya CircleCI gibi ara\u00e7lar bu s\u00fcre\u00e7leri otomatikle\u015ftirerek insan hatas\u0131n\u0131 azalt\u0131r ve da\u011f\u0131t\u0131m h\u0131z\u0131n\u0131 art\u0131r\u0131r. Bu, \u00f6zellikle b\u00fcy\u00fck ekipler ve s\u0131k g\u00fcncellemeler i\u00e7in vazge\u00e7ilmezdir.<\/p>\n<h2>Sonu\u00e7<\/h2>\n<p>Bu makalede, bir Django uygulamas\u0131n\u0131 Docker, Nginx ve Let&#8217;s Encrypt kullanarak nas\u0131l \u00f6l\u00e7eklenebilir ve g\u00fcvenli hale getirece\u011fimizi ayr\u0131nt\u0131l\u0131 bir \u015fekilde inceledik. Docker ile uygulaman\u0131z\u0131 ve ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 izole ettik, <code>docker-compose<\/code> ile servislerin koordinasyonunu sa\u011flad\u0131k. Gunicorn&#8217;u Django i\u00e7in bir WSGI sunucusu olarak yap\u0131land\u0131rd\u0131k. Nginx&#8217;i ters proxy, y\u00fck dengeleyici ve statik dosya sunucusu olarak konumland\u0131rd\u0131k. Let&#8217;s Encrypt ve Certbot ile \u00fccretsiz ve otomatik SSL\/TLS sertifikalar\u0131 sa\u011flayarak uygulaman\u0131n g\u00fcvenli\u011fini art\u0131rd\u0131k. Ayr\u0131ca, \u00f6l\u00e7eklendirme stratejileri ve g\u00fcvenlik en iyi uygulamalar\u0131 hakk\u0131nda \u00f6nemli bilgiler payla\u015ft\u0131k.<\/p>\n<p>Bu mimari, Django uygulaman\u0131z i\u00e7in sa\u011flam, esnek ve g\u00fcvenli bir temel olu\u015fturur. Uygulaman\u0131z b\u00fcy\u00fcd\u00fck\u00e7e, bu yap\u0131land\u0131rma sayesinde kolayca \u00f6l\u00e7eklenebilir ve performans\u0131n\u0131 koruyabilir. Gelecekte, daha b\u00fcy\u00fck \u00f6l\u00e7ekli ve karma\u015f\u0131k da\u011f\u0131t\u0131mlar i\u00e7in Docker Swarm veya Kubernetes gibi konteyner orkestrasyon ara\u00e7lar\u0131n\u0131 ke\u015ffedebilirsiniz. Unutmay\u0131n ki s\u00fcrekli izleme, d\u00fczenli g\u00fcncellemeler ve g\u00fcvenlik denetimleri, uygulaman\u0131z\u0131n uzun vadeli sa\u011fl\u0131\u011f\u0131 ve g\u00fcvenli\u011fi i\u00e7in kritik \u00f6neme sahiptir.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Django Uygulamas\u0131n\u0131 Docker, Nginx ve Let&#8217;s Encrypt ile \u00d6l\u00e7eklendirme ve G\u00fcvenli\u011fini Sa\u011flama\nGiri\u015f\nModern web uygulamalar\u0131, kullan\u0131c\u0131 bekle","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1504],"tags":[],"class_list":{"0":"post-31726","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-nginx","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Django Uygulamas\u0131n\u0131 Docker, Nginx ve Let&#039;s Encrypt ile \u00d6l\u00e7eklendirme ve G\u00fcvenli\u011fini Sa\u011flama - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Django Uygulamas\u0131n\u0131 Docker, Nginx ve Let&#039;s Encrypt ile \u00d6l\u00e7eklendirme ve G\u00fcvenli\u011fini Sa\u011flama\" \/>\n<meta property=\"og:description\" content=\"Django Uygulamas\u0131n\u0131 Docker, Nginx ve Let&#039;s Encrypt ile \u00d6l\u00e7eklendirme ve G\u00fcvenli\u011fini Sa\u011flama Giri\u015f Modern web uygulamalar\u0131, kullan\u0131c\u0131 bekle\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-13T05:41:17+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"19 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Django Uygulamas\u0131n\u0131 Docker, Nginx ve Let&#8217;s Encrypt ile \u00d6l\u00e7eklendirme ve G\u00fcvenli\u011fini Sa\u011flama\",\"datePublished\":\"2025-10-13T05:41:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/\"},\"wordCount\":2917,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Nginx\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/\",\"name\":\"Django Uygulamas\u0131n\u0131 Docker, Nginx ve Let's Encrypt ile \u00d6l\u00e7eklendirme ve G\u00fcvenli\u011fini Sa\u011flama - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-13T05:41:17+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Django Uygulamas\u0131n\u0131 Docker, Nginx ve Let&#8217;s Encrypt ile \u00d6l\u00e7eklendirme ve G\u00fcvenli\u011fini Sa\u011flama\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Django Uygulamas\u0131n\u0131 Docker, Nginx ve Let's Encrypt ile \u00d6l\u00e7eklendirme ve G\u00fcvenli\u011fini Sa\u011flama - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/","og_locale":"tr_TR","og_type":"article","og_title":"Django Uygulamas\u0131n\u0131 Docker, Nginx ve Let's Encrypt ile \u00d6l\u00e7eklendirme ve G\u00fcvenli\u011fini Sa\u011flama","og_description":"Django Uygulamas\u0131n\u0131 Docker, Nginx ve Let's Encrypt ile \u00d6l\u00e7eklendirme ve G\u00fcvenli\u011fini Sa\u011flama Giri\u015f Modern web uygulamalar\u0131, kullan\u0131c\u0131 bekle","og_url":"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-13T05:41:17+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"19 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Django Uygulamas\u0131n\u0131 Docker, Nginx ve Let&#8217;s Encrypt ile \u00d6l\u00e7eklendirme ve G\u00fcvenli\u011fini Sa\u011flama","datePublished":"2025-10-13T05:41:17+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/"},"wordCount":2917,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Nginx"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/","url":"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/","name":"Django Uygulamas\u0131n\u0131 Docker, Nginx ve Let's Encrypt ile \u00d6l\u00e7eklendirme ve G\u00fcvenli\u011fini Sa\u011flama - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-13T05:41:17+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/django-uygulamasini-docker-nginx-ve-lets-encrypt-ile-olceklendirme-ve-guvenligini-saglama\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Django Uygulamas\u0131n\u0131 Docker, Nginx ve Let&#8217;s Encrypt ile \u00d6l\u00e7eklendirme ve G\u00fcvenli\u011fini Sa\u011flama"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31726","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=31726"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31726\/revisions"}],"predecessor-version":[{"id":31727,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31726\/revisions\/31727"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=31726"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=31726"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=31726"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}