{"id":36329,"date":"2025-12-13T19:31:04","date_gmt":"2025-12-13T16:31:04","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/"},"modified":"2025-12-13T19:31:04","modified_gmt":"2025-12-13T16:31:04","slug":"dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/","title":{"rendered":"Dockerfile ile Kendi Docker \u0130maj\u0131n\u0131z\u0131 Ad\u0131m Ad\u0131m Olu\u015fturun"},"content":{"rendered":"<p><body><\/p>\n<p>Uygulamalar\u0131n\u0131z\u0131 daha verimli da\u011f\u0131tmak ve y\u00f6netmek mi istiyorsunuz? Dockerfile kullanarak \u00f6zel Docker imajlar\u0131 olu\u015fturman\u0131n inceliklerini \u00f6\u011frenin ve projelerinizi standardizasyonla g\u00fc\u00e7lendirin. Bu rehber, en temelden en ileri d\u00fczeye kadar her \u015feyi kaps\u0131yor.<\/p>\n<p>Her geli\u015ftiricinin a\u015fina oldu\u011fu o klasik senaryoyu d\u00fc\u015f\u00fcn\u00fcn: &#8220;Benim makinemde \u00e7al\u0131\u015f\u0131yordu ama neden \u015fimdi \u00e7al\u0131\u015fm\u0131yor?&#8221; Bu s\u00f6z, asl\u0131nda yaz\u0131l\u0131m geli\u015ftirme d\u00fcnyas\u0131n\u0131n en b\u00fcy\u00fck ve en inat\u00e7\u0131 sorunlar\u0131ndan birini \u00f6zetler. Bir uygulaman\u0131n farkl\u0131 ortamlarda (geli\u015ftirme, test, \u00fcretim) tutarl\u0131 bir \u015fekilde \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flamak, y\u0131llarca s\u00fcren bir m\u00fccadele olmu\u015ftur. Yaz\u0131l\u0131mlar sadece koddan ibaret de\u011fildir; ba\u011f\u0131ml\u0131l\u0131klar, i\u015fletim sistemi konfig\u00fcrasyonlar\u0131, \u00e7evre de\u011fi\u015fkenleri ve daha niceleri bir araya gelerek karma\u015f\u0131k bir ekosistem olu\u015fturur. Bu karma\u015fa, uygulaman\u0131n bir sunucudan di\u011ferine ta\u015f\u0131nmas\u0131n\u0131 veya farkl\u0131 geli\u015ftiricilerin makinelerinde \u00e7al\u0131\u015fmas\u0131n\u0131 son derece zorla\u015ft\u0131r\u0131r. \u0130\u015fte tam da bu noktada, Docker ve Dockerfile devreye girerek bu geleneksel engelleri ortadan kald\u0131r\u0131yor.<\/p>\n<p>Docker, uygulamalar\u0131n\u0131z\u0131 ve ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 izole edilmi\u015f, ta\u015f\u0131nabilir konteynerler i\u00e7inde paketlemenize olanak tan\u0131yan devrim niteli\u011finde bir platformdur. Bu konteynerler, uygulaman\u0131z\u0131n ihtiya\u00e7 duydu\u011fu her \u015feyi, kendi hafif, ta\u015f\u0131nabilir paketi i\u00e7inde bar\u0131nd\u0131r\u0131r. B\u00f6ylece, uygulamalar\u0131n\u0131z\u0131n &#8220;her yerde ayn\u0131 \u015fekilde&#8221; \u00e7al\u0131\u015fmas\u0131n\u0131 garanti eder. Art\u0131k ba\u011f\u0131ml\u0131l\u0131k sorunlar\u0131yla u\u011fra\u015fmak, bir da\u011f\u0131t\u0131m ortam\u0131n\u0131 s\u0131f\u0131rdan kurmak veya g\u00fcnlerce s\u00fcren hata ay\u0131klamalarla bo\u011fu\u015fmak zorunda kalmayacaks\u0131n\u0131z. Docker, geli\u015ftiricilerin daha verimli \u00e7al\u0131\u015fmas\u0131n\u0131, operasyon ekiplerinin da\u011f\u0131t\u0131m s\u00fcre\u00e7lerini basitle\u015ftirmesini ve t\u00fcm ekibin daha h\u0131zl\u0131 hareket etmesini sa\u011flar. \u00d6zellikle modern DevOps pratiklerinde ve mikroservis mimarilerinde Docker, vazge\u00e7ilmez bir ara\u00e7 haline gelmi\u015ftir. Peki, bu sihirli konteynerler nas\u0131l olu\u015fturulur? \u0130\u015fte burada Dockerfile&#8217;lar sahneye \u00e7\u0131k\u0131yor.<\/p>\n<div class=\"expert-tip\">Uzman \u0130pucu: Da\u011f\u0131t\u0131m s\u00fcrecindeki hatalar\u0131n %60&#8217;\u0131ndan fazlas\u0131 ortam tutars\u0131zl\u0131klar\u0131ndan kaynaklan\u0131r. Dockerfile, bu oran\u0131 b\u00fcy\u00fck \u00f6l\u00e7\u00fcde d\u00fc\u015f\u00fcrerek zaman ve maliyet tasarrufu sa\u011flar.<\/div>\n<p>Bu makalede, Docker&#8217;\u0131n temel ta\u015f\u0131 olan Dockerfile&#8217;lar\u0131 kullanarak kendi \u00f6zel Docker imajlar\u0131n\u0131z\u0131 ad\u0131m ad\u0131m nas\u0131l olu\u015fturaca\u011f\u0131n\u0131z\u0131 detayl\u0131 bir \u015fekilde \u00f6\u011freneceksiniz. S\u0131f\u0131rdan bir Dockerfile yazmaktan, imaj boyutunu optimize etmeye ve ger\u00e7ek d\u00fcnya senaryolar\u0131nda kullanmaya kadar her y\u00f6n\u00fcyle bu konuyu ele alaca\u011f\u0131z. Hedefimiz, bu rehberin sonunda, Dockerfile&#8217;lar\u0131 tam anlam\u0131yla kavrayarak projelerinizde aktif olarak kullanabilmenizdir. Uygulama da\u011f\u0131t\u0131m s\u00fcre\u00e7lerinizi standardizasyonla ve otomasyonla g\u00fc\u00e7lendirmenin zaman\u0131 geldi.<\/p>\n<h2>Dockerfile Nedir ve Neden Hayati \u00d6nem Ta\u015f\u0131r? Temel Kavramlara H\u0131zl\u0131 Bir Bak\u0131\u015f<\/h2>\n<p>Docker ekosistemini anlamak i\u00e7in \u00f6ncelikle iki temel kavram\u0131 netle\u015ftirmeliyiz: Docker \u0130majlar\u0131 ve Docker Konteynerleri. Basit\u00e7e ifade etmek gerekirse, bir Docker \u0130maj\u0131, uygulaman\u0131z\u0131n \u00e7al\u0131\u015fmas\u0131 i\u00e7in gerekli t\u00fcm kodlar\u0131, \u00e7al\u0131\u015fma zaman\u0131n\u0131, sistem ara\u00e7lar\u0131n\u0131, k\u00fct\u00fcphaneleri ve ayarlar\u0131 i\u00e7eren, okunabilir bir \u015fablon veya pakettir. T\u0131pk\u0131 bir yaz\u0131l\u0131m\u0131n kurulum dosyas\u0131n\u0131n bir kopyas\u0131 gibi d\u00fc\u015f\u00fcnebilirsiniz. Bir imaj statiktir ve \u00fczerinde de\u011fi\u015fiklik yap\u0131lamaz. Konteyner ise bu imajdan yarat\u0131lan, \u00e7al\u0131\u015fan, canl\u0131 bir \u00f6rnektir. Bir imajdan birden fazla konteyner olu\u015fturabilir ve her biri birbirinden izole bir \u015fekilde \u00e7al\u0131\u015fabilir. Bu analojiyi bir pasta tarifi ve pi\u015fmi\u015f pasta olarak d\u00fc\u015f\u00fcnebiliriz. Tarife (imaj) g\u00f6re birden \u00e7ok pasta (konteyner) yapabilirsiniz.<\/p>\n<p>Peki, bu imajlar\u0131 nas\u0131l olu\u015ftururuz? \u0130\u015fte burada Dockerfile devreye giriyor. Dockerfile, Docker imajlar\u0131n\u0131 olu\u015fturmak i\u00e7in kullan\u0131lan metin tabanl\u0131 bir talimat listesidir. Uygulaman\u0131z\u0131 \u00e7al\u0131\u015ft\u0131rmak i\u00e7in ad\u0131m ad\u0131m ne yap\u0131lmas\u0131 gerekti\u011fini Docker&#8217;a anlatan bir komut dosyas\u0131d\u0131r. Her bir talimat, imajda yeni bir katman olu\u015fturur ve bu katmanlar \u00fcst \u00fcste birikerek nihai imaj\u0131 meydana getirir. Bu katmanl\u0131 dosya sistemi, Docker&#8217;\u0131n verimlili\u011finin anahtarlar\u0131ndan biridir; zira ayn\u0131 katmanlar birden fazla imaj aras\u0131nda payla\u015f\u0131labilir ve yaln\u0131zca de\u011fi\u015fen katmanlar\u0131n yeniden indirilmesi veya olu\u015fturulmas\u0131 gerekir.<\/p>\n<p>Dockerfile&#8217;\u0131n sundu\u011fu faydalar, modern yaz\u0131l\u0131m geli\u015ftirme ve operasyon s\u00fcre\u00e7leri i\u00e7in hayati \u00f6neme sahiptir:<\/p>\n<ul>\n<li><strong>Tutarl\u0131l\u0131k ve Ta\u015f\u0131nabilirlik:<\/strong> Dockerfile, imaj olu\u015fturma s\u00fcrecini belgeledi\u011fi i\u00e7in, ayn\u0131 Dockerfile ile her zaman ayn\u0131 imaj\u0131 olu\u015fturursunuz. Bu, uygulaman\u0131z\u0131n farkl\u0131 ortamlarda (geli\u015ftirme, test, \u00fcretim) her zaman ayn\u0131 \u015fekilde \u00e7al\u0131\u015fmas\u0131n\u0131 garanti eder. Uygulaman\u0131z\u0131 bir sunucudan di\u011ferine ta\u015f\u0131mak veya farkl\u0131 bir bulut sa\u011flay\u0131c\u0131s\u0131na ge\u00e7mek art\u0131k \u00e7ok daha kolayd\u0131r.<\/li>\n<li><strong>S\u00fcr\u00fcm Kontrol\u00fc ve \u0130\u015fbirli\u011fi:<\/strong> Dockerfile&#8217;lar metin dosyalar\u0131 oldu\u011fundan, Git gibi s\u00fcr\u00fcm kontrol sistemlerinde saklanabilir. Bu sayede, imaj olu\u015fturma s\u00fcrecinin tarih\u00e7esini takip edebilir, farkl\u0131 versiyonlar aras\u0131nda kolayca ge\u00e7i\u015f yapabilir ve ekip \u00fcyeleri aras\u0131nda i\u015fbirli\u011fini g\u00fc\u00e7lendirebilirsiniz.<\/li>\n<li><strong>Otomasyon ve CI\/CD Entegrasyonu:<\/strong> Dockerfile&#8217;lar, Continuous Integration\/Continuous Deployment (CI\/CD) pipeline&#8217;lar\u0131n\u0131n ayr\u0131lmaz bir par\u00e7as\u0131d\u0131r. Geli\u015ftiriciler kodu depoya itti\u011finde, CI\/CD sistemleri otomatik olarak Dockerfile&#8217;\u0131 kullanarak yeni bir imaj olu\u015fturabilir, test edebilir ve konteyner kay\u0131t defterine g\u00f6nderebilir. Bu, da\u011f\u0131t\u0131m s\u00fcre\u00e7lerini b\u00fcy\u00fck \u00f6l\u00e7\u00fcde h\u0131zland\u0131r\u0131r ve insan hatas\u0131n\u0131 minimize eder.<\/li>\n<li><strong>Verimlilik ve Kaynak Kullan\u0131m\u0131:<\/strong> Katmanl\u0131 dosya sistemi sayesinde, imajlar daha verimli depolan\u0131r ve iletilir. Sadece de\u011fi\u015fen katmanlar yeniden olu\u015fturuldu\u011fu veya indirildi\u011fi i\u00e7in, derleme ve da\u011f\u0131t\u0131m s\u00fcreleri k\u0131sal\u0131r.<\/li>\n<\/ul>\n<p>K\u0131sacas\u0131, Dockerfile bir imaj\u0131n nas\u0131l in\u015fa edilece\u011finin tarifidir. Bu tarif, sadece bir uygulaman\u0131n nas\u0131l paketlendi\u011fini de\u011fil, ayn\u0131 zamanda o uygulaman\u0131n ya\u015fam d\u00f6ng\u00fcs\u00fc boyunca nas\u0131l tutarl\u0131, ta\u015f\u0131nabilir ve otomatik olarak y\u00f6netilebilir k\u0131l\u0131naca\u011f\u0131n\u0131 da belirler. Bu nedenle, Docker ekosistemindeki merkezi rol\u00fc tart\u0131\u015f\u0131lmazd\u0131r.<\/p>\n<h2>Ad\u0131m Ad\u0131m \u0130lk Dockerfile&#8217;\u0131m\u0131z\u0131 Nas\u0131l Yazar\u0131z? Pratik Bir Ba\u015flang\u0131\u00e7<\/h2>\n<p>Art\u0131k Dockerfile&#8217;\u0131n ne oldu\u011funu ve neden \u00f6nemli oldu\u011funu anlad\u0131\u011f\u0131m\u0131za g\u00f6re, ilk kendi \u00f6zel imaj\u0131m\u0131z\u0131 olu\u015fturmak i\u00e7in kollar\u0131m\u0131z\u0131 s\u0131vayabiliriz. Bu b\u00f6l\u00fcmde, basit bir Python web uygulamas\u0131n\u0131 Dockerize ederek Dockerfile yaz\u0131m\u0131n\u0131n temel ad\u0131mlar\u0131n\u0131 ve komutlar\u0131n\u0131 \u00f6\u011frenece\u011fiz. \u0130htiyac\u0131n\u0131z olan tek \u015fey, makinenize kurulu Docker ve bir metin d\u00fczenleyici.<\/p>\n<h3>1. Basit Bir Uygulama Olu\u015ftural\u0131m<\/h3>\n<p>\u00d6ncelikle, Dockerize edece\u011fimiz k\u00fc\u00e7\u00fck bir Python Flask uygulamas\u0131 haz\u0131rlayal\u0131m. \u00c7al\u0131\u015fma dizininizde <code>app.py<\/code> ad\u0131nda bir dosya olu\u015fturun ve i\u00e7ine a\u015fa\u011f\u0131daki kodu yap\u0131\u015ft\u0131r\u0131n:<\/p>\n<pre><code>\n# app.py\nfrom flask import Flask\n\napp = Flask(__name__)\n\n@app.route('\/')\ndef hello_world():\n    return 'Merhaba, Docker D\u00fcnyas\u0131!'\n\nif __name__ == '__main__':\n    app.run(debug=True, host='0.0.0.0')\n<\/pre>\n<p><\/code><\/p>\n<p>Bu uygulama, root URL'e gelen istekleri \"Merhaba, Docker D\u00fcnyas\u0131!\" mesaj\u0131yla yan\u0131tlayan basit bir web sunucusudur. Flask'\u0131 kurmak i\u00e7in <code>requirements.txt<\/code> dosyas\u0131na ihtiyac\u0131m\u0131z olacak. Ayn\u0131 dizinde <code>requirements.txt<\/code> ad\u0131nda bir dosya olu\u015fturun ve i\u00e7ine \u015funu yaz\u0131n:<\/p>\n<pre><code>\nFlask==2.2.2\n<\/pre>\n<p><\/code><\/p>\n<p>Uygulama yap\u0131n\u0131z \u015fimdi \u015f\u00f6yle olmal\u0131:<\/p>\n<ul>\n<li><code>my-flask-app\/<\/code>\n<ul>\n<li><code>app.py<\/code><\/li>\n<li><code>requirements.txt<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>2. Dockerfile Yaz\u0131m\u0131na Ba\u015flayal\u0131m<\/h3>\n<p>\u015eimdi ayn\u0131 dizinde, dosya uzant\u0131s\u0131 olmayan <code>Dockerfile<\/code> ad\u0131nda bir dosya olu\u015fturun. \u0130\u00e7ine a\u015fa\u011f\u0131daki talimatlar\u0131 ad\u0131m ad\u0131m ekleyece\u011fiz.<\/p>\n<p><strong>Ad\u0131m 1: Temel \u0130maj\u0131 Belirleme (<code>FROM<\/code>)<\/strong><\/p>\n<p>Her Dockerfile, bir temel imaj ile ba\u015flar. Bu imaj, uygulaman\u0131z\u0131n \u00e7al\u0131\u015faca\u011f\u0131 i\u015fletim sistemi ortam\u0131n\u0131 (\u00f6rne\u011fin Ubuntu, Alpine) ve gerekli \u00e7al\u0131\u015fma zaman\u0131n\u0131 (\u00f6rne\u011fin Python, Node.js, Java) sa\u011flar. Bizim Python uygulamam\u0131z i\u00e7in Python'\u0131n resmi imajlar\u0131ndan birini kullanaca\u011f\u0131z.<\/p>\n<pre><code>\nFROM python:3.9-slim-buster\n<\/pre>\n<p><\/code><\/p>\n<p><code>python:3.9-slim-buster<\/code>, Python 3.9 s\u00fcr\u00fcm\u00fcn\u00fc i\u00e7eren, Debian Buster tabanl\u0131 ve daha k\u00fc\u00e7\u00fck boyutlu bir imajd\u0131r. <code>slim<\/code> varyantlar\u0131 genellikle daha az ba\u011f\u0131ml\u0131l\u0131k i\u00e7erdi\u011fi i\u00e7in daha hafiftir ve g\u00fcvenlik a\u00e7\u0131s\u0131ndan da avantajl\u0131d\u0131r.<\/p>\n<p><strong>Ad\u0131m 2: \u00c7al\u0131\u015fma Dizinini Ayarlama (<code>WORKDIR<\/code>)<\/strong><\/p>\n<p><code>WORKDIR<\/code> komutu, sonraki t\u00fcm komutlar\u0131n (<code>RUN<\/code>, <code>CMD<\/code>, <code>COPY<\/code> vb.) \u00e7al\u0131\u015faca\u011f\u0131 varsay\u0131lan dizini belirler. Bu, konteyner i\u00e7indeki dosya yollar\u0131n\u0131 y\u00f6netmeyi kolayla\u015ft\u0131r\u0131r.<\/p>\n<pre><code>\nWORKDIR \/app\n<\/pre>\n<p><\/code><\/p>\n<p>Art\u0131k t\u00fcm i\u015flemlerimiz <code>\/app<\/code> dizini alt\u0131nda yap\u0131lacak.<\/p>\n<p><strong>Ad\u0131m 3: Ba\u011f\u0131ml\u0131l\u0131klar\u0131 Kopyalama ve Kurma (<code>COPY<\/code>, <code>RUN<\/code>)<\/strong><\/p>\n<p>Uygulaman\u0131z\u0131n \u00e7al\u0131\u015fmas\u0131 i\u00e7in gerekli ba\u011f\u0131ml\u0131l\u0131klar\u0131 (<code>requirements.txt<\/code>) kopyalay\u0131p kurmam\u0131z gerekiyor. \u00d6nce <code>requirements.txt<\/code> dosyas\u0131n\u0131 kopyalayaca\u011f\u0131z, sonra da pip ile kuraca\u011f\u0131z. Ba\u011f\u0131ml\u0131l\u0131klar\u0131, uygulama kodundan \u00f6nce kopyalamak katman \u00f6nbelleklemesi a\u00e7\u0131s\u0131ndan \u00f6nemlidir. E\u011fer ba\u011f\u0131ml\u0131l\u0131klar de\u011fi\u015fmezse, bu katman yeniden in\u015fa edilmez, bu da derleme s\u00fcresini h\u0131zland\u0131r\u0131r.<\/p>\n<pre><code>\nCOPY requirements.txt .\nRUN pip install -r requirements.txt\n<\/pre>\n<p><\/code><\/p>\n<p><code>.<\/code> (nokta), mevcut \u00e7al\u0131\u015fma dizini olan <code>\/app<\/code>'\u0131 temsil eder. Yani <code>requirements.txt<\/code> dosyas\u0131n\u0131 host makinenin o anki dizininden (Dockerfile'\u0131n bulundu\u011fu yer) konteyner i\u00e7indeki <code>\/app<\/code> dizinine kopyal\u0131yoruz.<\/p>\n<p><strong>Ad\u0131m 4: Uygulama Kodunu Kopyalama (<code>COPY<\/code>)<\/strong><\/p>\n<p>\u015eimdi s\u0131ra uygulama kodumuzu konteyner i\u00e7ine kopyalamakta.<\/p>\n<pre><code>\nCOPY . .\n<\/pre>\n<p><\/code><\/p>\n<p>Bu komut, Dockerfile'\u0131n bulundu\u011fu dizindeki t\u00fcm dosyalar\u0131 (<code>.dockerignore<\/code> taraf\u0131ndan yoksay\u0131lanlar hari\u00e7) konteynerin <code>\/app<\/code> dizinine kopyalar.<\/p>\n<p><strong>Ad\u0131m 5: Portu A\u00e7\u0131klama (<code>EXPOSE<\/code>)<\/strong><\/p>\n<p><code>EXPOSE<\/code> komutu, konteynerin hangi portta dinleyece\u011fini belirtir. Bu sadece bir belgelemedir ve ger\u00e7ekte portu d\u0131\u015far\u0131ya a\u00e7maz; sadece portun uygulama taraf\u0131ndan kullan\u0131laca\u011f\u0131n\u0131 bildirir. Uygulamam\u0131z 5000 portunda \u00e7al\u0131\u015f\u0131yor.<\/p>\n<pre><code>\nEXPOSE 5000\n<\/pre>\n<p><\/code><\/p>\n<p><strong>Ad\u0131m 6: Uygulamay\u0131 Ba\u015flatma (<code>CMD<\/code>)<\/strong><\/p>\n<p><code>CMD<\/code> komutu, konteyner ba\u015flat\u0131ld\u0131\u011f\u0131nda \u00e7al\u0131\u015ft\u0131r\u0131lacak varsay\u0131lan komutu belirler. Sadece bir <code>CMD<\/code> komutu olabilir. E\u011fer birden fazla <code>CMD<\/code> belirtilirse, sadece sonuncusu ge\u00e7erli olur.<\/p>\n<pre><code>\nCMD [\"python\", \"app.py\"]\n<\/pre>\n<p><\/code><\/p>\n<p>Bu komut, konteyner ba\u015flat\u0131ld\u0131\u011f\u0131nda <code>app.py<\/code> dosyas\u0131n\u0131 Python yorumlay\u0131c\u0131s\u0131 ile \u00e7al\u0131\u015ft\u0131racakt\u0131r.<\/p>\n<p>Tamamlanm\u0131\u015f Dockerfile'\u0131m\u0131z \u015f\u00f6yle g\u00f6r\u00fcnecek:<\/p>\n<pre><code>\n# Dockerfile\nFROM python:3.9-slim-buster\nWORKDIR \/app\nCOPY requirements.txt .\nRUN pip install -r requirements.txt\nCOPY . .\nEXPOSE 5000\nCMD [\"python\", \"app.py\"]\n<\/pre>\n<p><\/code><\/p>\n<h3>3. Docker \u0130maj\u0131n\u0131 Olu\u015fturma<\/h3>\n<p>\u015eimdi Dockerfile'\u0131 kullanarak imaj\u0131m\u0131z\u0131 olu\u015ftural\u0131m. Terminalinizi a\u00e7\u0131n ve Dockerfile ile uygulama dosyalar\u0131n\u0131n bulundu\u011fu dizine gidin. Ard\u0131ndan a\u015fa\u011f\u0131daki komutu \u00e7al\u0131\u015ft\u0131r\u0131n:<\/p>\n<pre><code>\ndocker build -t my-flask-app:1.0 .\n<\/pre>\n<p><\/code><\/p>\n<p>Buradaki parametrelerin anlamlar\u0131:<\/p>\n<ul>\n<li><code>docker build<\/code>: Docker'a bir imaj olu\u015fturmas\u0131n\u0131 s\u00f6yler.<\/li>\n<li><code>-t my-flask-app:1.0<\/code>: Olu\u015fturulan imaja bir etiket (tag) veririz. <code>my-flask-app<\/code> imaj\u0131n ad\u0131, <code>1.0<\/code> ise versiyonudur.<\/li>\n<li><code>.<\/code> (nokta): Dockerfile'\u0131n ve ba\u011flam\u0131n (context) bulundu\u011fu dizini belirtir. Docker, imaj\u0131 olu\u015fturmak i\u00e7in bu dizindeki t\u00fcm dosyalar\u0131 kullan\u0131r.<\/li>\n<\/ul>\n<p>Komutu \u00e7al\u0131\u015ft\u0131rd\u0131ktan sonra Docker, Dockerfile'daki her bir talimat\u0131 s\u0131ras\u0131yla y\u00fcr\u00fctecek ve her ad\u0131mda bir katman olu\u015fturacakt\u0131r. Ba\u015far\u0131l\u0131 bir derlemeden sonra imaj\u0131n\u0131z haz\u0131r olacakt\u0131r.<\/p>\n<h3>4. Docker Konteynerini \u00c7al\u0131\u015ft\u0131rma<\/h3>\n<p>\u0130maj\u0131m\u0131z\u0131 ba\u015far\u0131yla olu\u015fturdu\u011fumuza g\u00f6re, ondan bir konteyner \u00e7al\u0131\u015ft\u0131rabiliriz:<\/p>\n<pre><code>\ndocker run -p 5000:5000 my-flask-app:1.0\n<\/pre>\n<p><\/code><\/p>\n<p>Bu komutun a\u00e7\u0131klamas\u0131:<\/p>\n<ul>\n<li><code>docker run<\/code>: Bir konteyner \u00e7al\u0131\u015ft\u0131rmak i\u00e7in kullan\u0131l\u0131r.<\/li>\n<li><code>-p 5000:5000<\/code>: Port e\u015flemesi yapar. \u0130lk <code>5000<\/code> host makinenizin portu, ikinci <code>5000<\/code> ise konteynerin i\u00e7indeki porttur. Yani host makinenizin 5000 portuna gelen istekler, konteynerin 5000 portuna y\u00f6nlendirilecektir.<\/li>\n<li><code>my-flask-app:1.0<\/code>: \u00c7al\u0131\u015ft\u0131rmak istedi\u011fimiz imaj\u0131n ad\u0131 ve versiyonu.<\/li>\n<\/ul>\n<p>Konteyner ba\u015flad\u0131ktan sonra, web taray\u0131c\u0131n\u0131z\u0131 a\u00e7\u0131n ve <code>http:\/\/localhost:5000<\/code> adresine gidin. \"Merhaba, Docker D\u00fcnyas\u0131!\" mesaj\u0131n\u0131 g\u00f6rmelisiniz. Tebrikler, ilk \u00f6zel Docker imaj\u0131n\u0131z\u0131 ba\u015far\u0131yla olu\u015fturdunuz ve \u00e7al\u0131\u015ft\u0131rd\u0131n\u0131z!<\/p>\n<h2>Ger\u00e7ek D\u00fcnya Senaryosu: Bir Web Uygulamas\u0131 i\u00e7in Optimize Edilmi\u015f Docker \u0130maj\u0131 Olu\u015fturma<\/h2>\n<p>\u00d6nceki b\u00f6l\u00fcmde basit bir Python Flask uygulamas\u0131n\u0131 Dockerize ettik. \u015eimdi ise biraz daha karma\u015f\u0131k ve ger\u00e7ek d\u00fcnyaya yak\u0131n bir senaryo ele alal\u0131m: performans ve g\u00fcvenlik g\u00f6z \u00f6n\u00fcnde bulundurularak optimize edilmi\u015f bir web uygulamas\u0131 Docker imaj\u0131 olu\u015fturmak. Bu, sadece uygulaman\u0131z\u0131n \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flamakla kalmayacak, ayn\u0131 zamanda daha k\u00fc\u00e7\u00fck, daha h\u0131zl\u0131 ve daha g\u00fcvenli imajlar elde etmenize yard\u0131mc\u0131 olacakt\u0131r.<\/p>\n<h3>Senaryo: Bir Node.js Express Uygulamas\u0131<\/h3>\n<p>Farz edelim ki, bir Node.js Express tabanl\u0131 API'niz var. Bu API, <code>package.json<\/code> ile ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 y\u00f6netiyor ve 3000 portunda \u00e7al\u0131\u015f\u0131yor. Geli\u015ftirme ortam\u0131n\u0131zda her \u015fey yolunda giderken, \u00fcretim ortam\u0131na da\u011f\u0131t\u0131m yaparken imaj boyutunu k\u00fc\u00e7\u00fcltmek ve g\u00fcvenlik a\u00e7\u0131klar\u0131n\u0131 azaltmak istiyorsunuz.<\/p>\n<p><strong>Uygulama Yap\u0131s\u0131:<\/strong><\/p>\n<ul>\n<li><code>my-node-app\/<\/code>\n<ul>\n<li><code>app.js<\/code> (Basit bir Express uygulamas\u0131)<\/li>\n<li><code>package.json<\/code> (Ba\u011f\u0131ml\u0131l\u0131klar\u0131 tan\u0131mlar)<\/li>\n<li><code>.dockerignore<\/code> (Docker'\u0131n dikkate almamas\u0131 gereken dosyalar)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><strong><code>app.js<\/code> i\u00e7eri\u011fi:<\/strong><\/p>\n<pre><code>\n\/\/ app.js\nconst express = require('express');\nconst app = express();\nconst port = 3000;\n\napp.get('\/', (req, res) => {\n  res.send('Merhaba, Optimize Edilmi\u015f Docker Konteyneri!');\n});\n\napp.listen(port, () => {\n  console.log(<code>Uygulama http:\/\/localhost:${port} adresinde \u00e7al\u0131\u015f\u0131yor.<\/code>);\n});\n<\/pre>\n<p><\/code><\/p>\n<p><strong><code>package.json<\/code> i\u00e7eri\u011fi:<\/strong><\/p>\n<pre><code>\n{\n  \"name\": \"my-node-app\",\n  \"version\": \"1.0.0\",\n  \"description\": \"A simple Node.js Express app\",\n  \"main\": \"app.js\",\n  \"scripts\": {\n    \"start\": \"node app.js\"\n  },\n  \"dependencies\": {\n    \"express\": \"^4.18.2\"\n  }\n}\n<\/pre>\n<p><\/code><\/p>\n<p><strong><code>.dockerignore<\/code> i\u00e7eri\u011fi:<\/strong><\/p>\n<p>Bu dosya, Docker'\u0131n ba\u011flam\u0131na (context) hangi dosyalar\u0131n dahil edilmeyece\u011fini belirtir. <code>node_modules<\/code> gibi b\u00fcy\u00fck boyutlu veya hassas dosyalar\u0131n imaja kopyalanmas\u0131n\u0131 engellemek i\u00e7in \u00e7ok \u00f6nemlidir. Bu, hem imaj boyutunu k\u00fc\u00e7\u00fclt\u00fcr hem de gereksiz dosyalar\u0131n kopyalanmas\u0131n\u0131 \u00f6nler.<\/p>\n<pre><code>\nnode_modules\nnpm-debug.log\n.git\n.gitignore\nDockerfile\nREADME.md\n<\/pre>\n<p><\/code><\/p>\n<h3>Optimize Edilmi\u015f Dockerfile Olu\u015fturma<\/h3>\n<p>\u015eimdi <code>Dockerfile<\/code> dosyam\u0131z\u0131 olu\u015fturmaya ba\u015flayal\u0131m. Burada birka\u00e7 optimizasyon tekni\u011fi uygulayaca\u011f\u0131z.<\/p>\n<p><strong>1. Do\u011fru Temel \u0130maj Se\u00e7imi<\/strong><\/p>\n<p>Node.js i\u00e7in genellikle <code>node:lts-alpine<\/code> gibi Alpine tabanl\u0131 imajlar tercih edilir. Alpine Linux, \u00e7ok k\u00fc\u00e7\u00fck boyutlu bir da\u011f\u0131t\u0131m oldu\u011fu i\u00e7in nihai imaj boyutunu \u00f6nemli \u00f6l\u00e7\u00fcde k\u00fc\u00e7\u00fclt\u00fcr.<\/p>\n<pre><code>\nFROM node:18-alpine\n<\/pre>\n<p><\/code><\/p>\n<p><strong>2. \u00c7al\u0131\u015fma Dizini ve Kullan\u0131c\u0131 Ayar\u0131<\/strong><\/p>\n<p>Her zaman root kullan\u0131c\u0131s\u0131 olarak \u00e7al\u0131\u015fmak yerine, daha az yetkiye sahip bir kullan\u0131c\u0131 olu\u015fturmak g\u00fcvenlik a\u00e7\u0131s\u0131ndan \u00f6nemlidir.<\/p>\n<pre><code>\nWORKDIR \/app\nRUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser\nUSER appuser\n<\/pre>\n<p><\/code><\/p>\n<p>Bu ad\u0131mlar, <code>appgroup<\/code> ad\u0131nda bir sistem grubu ve <code>appuser<\/code> ad\u0131nda bir sistem kullan\u0131c\u0131s\u0131 olu\u015fturur, ard\u0131ndan sonraki komutlar\u0131n bu kullan\u0131c\u0131 ba\u011flam\u0131nda \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flar.<\/p>\n<div class=\"expert-tip\">Uzman \u0130pucu: \u00dcretim ortam\u0131nda asla root kullan\u0131c\u0131s\u0131 olarak konteyner \u00e7al\u0131\u015ft\u0131rmay\u0131n. Olas\u0131 bir g\u00fcvenlik a\u00e7\u0131\u011f\u0131nda, sald\u0131rgan t\u00fcm host sistemine eri\u015fim sa\u011flayabilir.<\/div>\n<p><strong>3. Ba\u011f\u0131ml\u0131l\u0131klar\u0131n Ak\u0131ll\u0131ca Kopyalanmas\u0131 ve Kurulmas\u0131<\/strong><\/p>\n<p>Docker'\u0131n katman \u00f6nbellekleme mekanizmas\u0131n\u0131 en iyi \u015fekilde kullanmak i\u00e7in, s\u0131k de\u011fi\u015fmeyen dosyalar\u0131 (<code>package.json<\/code> ve <code>package-lock.json<\/code>) uygulama kodundan \u00f6nce kopyalay\u0131p ba\u011f\u0131ml\u0131l\u0131klar\u0131 kurmal\u0131y\u0131z. E\u011fer bu ba\u011f\u0131ml\u0131l\u0131k dosyalar\u0131 de\u011fi\u015fmezse, Docker <code>RUN npm install<\/code> katman\u0131n\u0131 yeniden \u00e7al\u0131\u015ft\u0131rmak yerine \u00f6nbelle\u011fi kullan\u0131r.<\/p>\n<pre><code>\nCOPY package*.json .\/\nRUN npm install --production\n<\/pre>\n<p><\/code><\/p>\n<p>Burada <code>--production<\/code> bayra\u011f\u0131, yaln\u0131zca \u00fcretim ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131n (<code>devDependencies<\/code> hari\u00e7) kurulmas\u0131n\u0131 sa\u011flar, bu da imaj boyutunu daha da k\u00fc\u00e7\u00fclt\u00fcr.<\/p>\n<p><strong>4. Uygulama Kodunu Kopyalama<\/strong><\/p>\n<p>\u015eimdi uygulama kodumuzu kopyalayabiliriz. Unutmay\u0131n, <code>.dockerignore<\/code> sayesinde gereksiz dosyalar (<code>node_modules<\/code> gibi) bu ad\u0131mda kopyalanmayacak.<\/p>\n<pre><code>\nCOPY . .\n<\/pre>\n<p><\/code><\/p>\n<p><strong>5. Portu Belirtme ve Uygulamay\u0131 Ba\u015flatma<\/strong><\/p>\n<p>Uygulama 3000 portunda dinledi\u011fi i\u00e7in bu portu <code>EXPOSE<\/code> ile belirtece\u011fiz ve <code>npm start<\/code> komutu ile uygulamay\u0131 ba\u015flataca\u011f\u0131z.<\/p>\n<pre><code>\nEXPOSE 3000\nCMD [\"npm\", \"start\"]\n<\/pre>\n<p><\/code><\/p>\n<p><strong>Tamamlanm\u0131\u015f Optimize Edilmi\u015f Dockerfile:<\/strong><\/p>\n<pre><code>\n# Dockerfile\nFROM node:18-alpine\n\nWORKDIR \/app\n\n# G\u00fcvenlik i\u00e7in ayr\u0131 bir kullan\u0131c\u0131 olu\u015ftur\nRUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser\nUSER appuser\n\n# Ba\u011f\u0131ml\u0131l\u0131klar\u0131 kopyala ve kur (\u00f6nbellekleme avantaj\u0131 i\u00e7in \u00f6nce)\nCOPY package*.json .\/\nRUN npm install --production --silent\n\n# Uygulama kodunu kopyala (\u00f6nce .dockerignore dosyas\u0131 ile gereksizleri d\u0131\u015far\u0131da b\u0131rak)\nCOPY . .\n\n# Konteynerin dinleyece\u011fi portu belirt\nEXPOSE 3000\n\n# Uygulamay\u0131 ba\u015flat\nCMD [\"npm\", \"start\"]\n<\/pre>\n<p><\/code><\/p>\n<h3>\u0130maj\u0131 Olu\u015fturma ve \u00c7al\u0131\u015ft\u0131rma<\/h3>\n<p>Yukar\u0131daki Dockerfile ile imaj\u0131 olu\u015fturmak i\u00e7in terminalde uygulama dizininize gidin ve:<\/p>\n<pre><code>\ndocker build -t my-optimized-node-app:1.0 .\n<\/pre>\n<p><\/code><\/p>\n<p>Ard\u0131ndan konteyneri \u00e7al\u0131\u015ft\u0131r\u0131n:<\/p>\n<pre><code>\ndocker run -p 3000:3000 my-optimized-node-app:1.0\n<\/pre>\n<p><\/code><\/p>\n<p>Taray\u0131c\u0131n\u0131zda <code>http:\/\/localhost:3000<\/code> adresine giderek uygulaman\u0131n \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 kontrol edebilirsiniz.<\/p>\n<p>Bu senaryoda, <code>node:18-alpine<\/code> gibi daha k\u00fc\u00e7\u00fck bir temel imaj kullanmak, \u00fcretim ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 kurmak ve root olmayan bir kullan\u0131c\u0131 ile \u00e7al\u0131\u015fmak gibi ad\u0131mlar, daha g\u00fcvenli ve daha hafif bir imaj elde etmenizi sa\u011flam\u0131\u015ft\u0131r. \u00d6zellikle <code>.dockerignore<\/code> dosyas\u0131n\u0131n \u00f6nemi, b\u00fcy\u00fck projelerde gereksiz dosyalar\u0131n imaja dahil edilmesini engelleyerek hem boyutu hem de derleme s\u00fcresini optimize etmektir.<\/p>\n<h2>\u0130leri D\u00fczey \u0130pu\u00e7lar\u0131 ve P\u00fcf Noktalar\u0131: Docker \u0130majlar\u0131n\u0131z\u0131 Nas\u0131l Daha Verimli Hale Getirirsiniz?<\/h2>\n<p>Docker imajlar\u0131n\u0131 sadece \u00e7al\u0131\u015f\u0131r hale getirmek yeterli de\u011fildir; ayn\u0131 zamanda onlar\u0131 verimli, g\u00fcvenli ve kolay y\u00f6netilebilir k\u0131lmak da \u00f6nemlidir. Bu b\u00f6l\u00fcmde, Dockerfile'lar\u0131n\u0131z\u0131 optimize etmek i\u00e7in ileri d\u00fczey teknikleri ve en iyi pratikleri inceleyece\u011fiz. Bu ipu\u00e7lar\u0131, hem imaj boyutunu k\u00fc\u00e7\u00fcltmenize hem de derleme s\u00fcrelerini h\u0131zland\u0131rman\u0131za yard\u0131mc\u0131 olacakt\u0131r.<\/p>\n<h3>1. \u0130maj Boyutunu K\u00fc\u00e7\u00fcltme Stratejileri<\/h3>\n<p>K\u00fc\u00e7\u00fck imajlar, daha h\u0131zl\u0131 da\u011f\u0131t\u0131m, daha az depolama alan\u0131 ve daha d\u00fc\u015f\u00fck g\u00fcvenlik riski anlam\u0131na gelir.<\/p>\n<ul>\n<li>\n        <strong>Do\u011fru Temel \u0130maj\u0131 Se\u00e7in:<\/strong><\/p>\n<p>Her zaman uygulaman\u0131z\u0131n ihtiya\u00e7 duydu\u011fu en hafif temel imaj\u0131 se\u00e7in. \u00d6rne\u011fin, Python i\u00e7in <code>python:3.9-slim-buster<\/code> veya <code>python:3.9-alpine<\/code>, Node.js i\u00e7in <code>node:lts-alpine<\/code> gibi varyantlar, genellikle tam \u00f6zellikli (\u00f6rne\u011fin <code>python:3.9<\/code>) imajlardan \u00e7ok daha k\u00fc\u00e7\u00fckt\u00fcr. Alpine tabanl\u0131 imajlar, genellikle musl libc kullanmalar\u0131 nedeniyle GNU libc tabanl\u0131 imajlara g\u00f6re \u00e7ok daha k\u00fc\u00e7\u00fck olabilir.<\/p>\n<\/li>\n<li>\n        <strong>Katman \u00d6nbelle\u011fini Ak\u0131ll\u0131ca Kullan\u0131n:<\/strong><\/p>\n<p>Docker, her <code>RUN<\/code>, <code>COPY<\/code>, <code>ADD<\/code> komutu i\u00e7in bir katman olu\u015fturur ve bu katmanlar\u0131 \u00f6nbelle\u011fe al\u0131r. Dockerfile'daki bir sat\u0131r de\u011fi\u015fti\u011finde, o sat\u0131rdan sonraki t\u00fcm katmanlar yeniden in\u015fa edilir. Bu nedenle, s\u0131k de\u011fi\u015fen komutlar\u0131 (\u00f6rne\u011fin uygulama kodu kopyalama) Dockerfile'\u0131n alt k\u0131s\u0131mlar\u0131na, nadiren de\u011fi\u015fen komutlar\u0131 (\u00f6rne\u011fin ba\u011f\u0131ml\u0131l\u0131klar\u0131 kurma) \u00fcst k\u0131s\u0131mlara ta\u015f\u0131yarak derleme s\u00fcresini \u00f6nemli \u00f6l\u00e7\u00fcde h\u0131zland\u0131rabilirsiniz. \u00d6nce ba\u011f\u0131ml\u0131l\u0131k dosyalar\u0131n\u0131 kopyalay\u0131p kurmak, sonra t\u00fcm uygulama kodunu kopyalamak bunun klasik bir \u00f6rne\u011fidir.<\/p>\n<pre><code>\nFROM python:3.9-slim-buster\nWORKDIR \/app\nCOPY requirements.txt .           # Bu katman genellikle de\u011fi\u015fmez\nRUN pip install -r requirements.txt # Bu katman da genellikle de\u011fi\u015fmez\nCOPY . .                         # Bu katman s\u0131k de\u011fi\u015fir, bu y\u00fczden sonda\nCMD [\"python\", \"app.py\"]\n        <\/pre>\n<p><\/code>\n    <\/li>\n<li>\n        <strong>Ara Dosyalar\u0131 Temizleyin:<\/strong><\/p>\n<p><code>RUN<\/code> komutlar\u0131 i\u00e7inde paket y\u00f6neticileri (<code>apt-get<\/code>, <code>apk<\/code>) ile kurdu\u011funuz paketlerin \u00f6nbelleklerini temizleyin. Birden fazla komutu tek bir <code>RUN<\/code> talimat\u0131 alt\u0131nda birle\u015ftirerek ve <code>&&<\/code> ile ba\u011flayarak, ara katmanlar\u0131n olu\u015fmas\u0131n\u0131 engeller ve daha k\u00fc\u00e7\u00fck bir nihai imaj elde edersiniz.<\/p>\n<pre><code>\n# K\u00f6t\u00fc \u00f6rnek: Fazladan katmanlar ve b\u00fcy\u00fck \u00f6nbellek\nRUN apt-get update\nRUN apt-get install -y some-package\nRUN rm -rf \/var\/lib\/apt\/lists\/*\n\n# \u0130yi \u00f6rnek: Tek RUN komutu ile optimize edilmi\u015f\nRUN apt-get update \\\n    && apt-get install -y --no-install-recommends some-package \\\n    && rm -rf \/var\/lib\/apt\/lists\/*\n        <\/pre>\n<p><\/code>\n    <\/li>\n<li>\n        <strong>\u00c7ok A\u015famal\u0131 Derleme (Multi-Stage Builds):<\/strong><\/p>\n<p>Bu, imaj boyutunu k\u00fc\u00e7\u00fcltmek i\u00e7in en g\u00fc\u00e7l\u00fc tekniklerden biridir. Geli\u015ftirme ve derleme ortam\u0131n\u0131zda ihtiya\u00e7 duydu\u011funuz t\u00fcm ara\u00e7lara (derleyiciler, SDK'lar, test ba\u011f\u0131ml\u0131l\u0131klar\u0131) sahip a\u011f\u0131r bir imaj kullan\u0131rken, nihai \u00fcretim imaj\u0131n\u0131za sadece uygulaman\u0131z\u0131n \u00e7al\u0131\u015fmas\u0131 i\u00e7in gerekli olan bitmi\u015f \u00e7\u0131kt\u0131lar\u0131 (\u00e7al\u0131\u015ft\u0131r\u0131labilir dosyalar, statik varl\u0131klar) kopyalaman\u0131z\u0131 sa\u011flar. Bu sayede, derleme ara\u00e7lar\u0131 nihai imajda yer almaz.<\/p>\n<pre><code>\n# A\u015fama 1: Derleme a\u015famas\u0131 (daha b\u00fcy\u00fck imaj, t\u00fcm derleme ara\u00e7lar\u0131 burada)\nFROM node:18-slim as builder\nWORKDIR \/app\nCOPY package*.json .\/\nRUN npm install\nCOPY . .\nRUN npm run build # Uygulamay\u0131 derle, \u00f6rn: React, Angular\n\n# A\u015fama 2: \u00dcretim a\u015famas\u0131 (daha k\u00fc\u00e7\u00fck imaj, sadece uygulaman\u0131n \u00e7al\u0131\u015fan\u0131)\nFROM node:18-alpine\nWORKDIR \/app\nCOPY --from=builder \/app\/build .\/build # Derlenmi\u015f dosyalar\u0131 kopyala\nCOPY package*.json .\/\nRUN npm install --production --silent\nCOPY --from=builder \/app\/node_modules .\/node_modules # Sadece \u00fcretim ba\u011f\u0131ml\u0131l\u0131klar\u0131\nEXPOSE 3000\nCMD [\"npm\", \"start\"]\n        <\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, ilk a\u015famada (<code>builder<\/code>) t\u00fcm <code>npm install<\/code> ve <code>npm run build<\/code> i\u015flemleri yap\u0131l\u0131r. \u0130kinci a\u015famada, sadece derlenmi\u015f <code>build<\/code> klas\u00f6r\u00fc ve \u00fcretim ba\u011f\u0131ml\u0131l\u0131klar\u0131 kopyalan\u0131r. Bu, gereksiz geli\u015ftirme ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 ve derleme ara\u00e7lar\u0131n\u0131 nihai imajdan d\u0131\u015far\u0131da b\u0131rak\u0131r.<\/p>\n<\/li>\n<\/ul>\n<h3>2. .dockerignore Dosyas\u0131n\u0131n \u00d6nemi<\/h3>\n<p><code>.dockerignore<\/code> dosyas\u0131, Docker'\u0131n ba\u011flam\u0131na hangi dosyalar\u0131n dahil edilmeyece\u011fini belirtir. T\u0131pk\u0131 <code>.gitignore<\/code> gibi \u00e7al\u0131\u015f\u0131r. Bu dosya sayesinde, <code>node_modules<\/code>, <code>.git<\/code>, yerel geli\u015ftirme ayarlar\u0131, IDE dosyalar\u0131 gibi gereksiz veya hassas dosyalar\u0131n Docker imaj\u0131n\u0131za kopyalanmas\u0131n\u0131 engelleyebilirsiniz. Bu, hem imaj boyutunu k\u00fc\u00e7\u00fclt\u00fcr hem de derleme s\u00fcresini h\u0131zland\u0131r\u0131r, \u00e7\u00fcnk\u00fc Docker'\u0131n daha az veri ta\u015f\u0131mas\u0131 gerekir.<\/p>\n<pre><code>\n# \u00d6rnek .dockerignore i\u00e7eri\u011fi\n**\/node_modules\n.git\n.gitignore\n*.log\nnpm-debug.log*\n.env\nDockerfile\ndocker-compose.yml\n<\/pre>\n<p><\/code><\/p>\n<h3>3. G\u00fcvenlik \u0130pu\u00e7lar\u0131<\/h3>\n<ul>\n<li>\n        <strong>Root Olmayan Kullan\u0131c\u0131 Kullan\u0131n:<\/strong><\/p>\n<p>\u00d6nceki b\u00f6l\u00fcmde de belirtti\u011fimiz gibi, konteynerleri root kullan\u0131c\u0131s\u0131 olarak \u00e7al\u0131\u015ft\u0131rmaktan ka\u00e7\u0131n\u0131n. Kapsay\u0131c\u0131 i\u00e7inde root kullan\u0131c\u0131s\u0131n\u0131n yetkisinin k\u00f6t\u00fcye kullan\u0131lmas\u0131, host sisteminde ciddi g\u00fcvenlik riskleri olu\u015fturabilir. <code>USER<\/code> talimat\u0131n\u0131 kullanarak ayr\u0131cal\u0131ks\u0131z bir kullan\u0131c\u0131 olu\u015fturun ve konteyneri bu kullan\u0131c\u0131yla \u00e7al\u0131\u015ft\u0131r\u0131n.<\/p>\n<\/li>\n<li>\n        <strong>Minimum Gerekli Ba\u011f\u0131ml\u0131l\u0131klar\u0131 Kurun:<\/strong><\/p>\n<p>\u0130maj\u0131n\u0131za sadece uygulaman\u0131z\u0131n \u00e7al\u0131\u015fmas\u0131 i\u00e7in kesinlikle gerekli olan paketleri ve ba\u011f\u0131ml\u0131l\u0131klar\u0131 ekleyin. Fazladan her paket, potansiyel bir g\u00fcvenlik a\u00e7\u0131\u011f\u0131 riski ta\u015f\u0131r.<\/p>\n<\/li>\n<li>\n        <strong>G\u00fcvenlik Taramalar\u0131 Yap\u0131n:<\/strong><\/p>\n<p>Olu\u015fturdu\u011funuz Docker imajlar\u0131n\u0131 d\u00fczenli olarak g\u00fcvenlik a\u00e7\u0131klar\u0131 i\u00e7in taray\u0131n. Docker Hub, Clair, Trivy gibi ara\u00e7lar bu konuda yard\u0131mc\u0131 olabilir. CI\/CD pipeline'\u0131n\u0131za imaj g\u00fcvenlik taramas\u0131n\u0131 dahil edin.<\/p>\n<\/li>\n<\/ul>\n<h3>4. <code>ENTRYPOINT<\/code> ve <code>CMD<\/code> Aras\u0131ndaki Fark\u0131 Anlamak<\/h3>\n<p>Her ikisi de konteyner ba\u015flat\u0131ld\u0131\u011f\u0131nda \u00e7al\u0131\u015facak komutu belirtir, ancak farkl\u0131 ama\u00e7lara hizmet ederler:<\/p>\n<ul>\n<li>\n        <strong><code>CMD<\/code>:<\/strong> Konteynerin varsay\u0131lan y\u00fcr\u00fct\u00fclebilir komutunu veya <code>ENTRYPOINT<\/code> komutuna arg\u00fcmanlar\u0131 sa\u011flar. Dockerfile'da birden fazla <code>CMD<\/code> komutu bulunursa, sadece en sonuncusu uygulan\u0131r. E\u011fer <code>docker run<\/code> komutunda ek arg\u00fcmanlar belirtilirse, <code>CMD<\/code> de\u011feri ge\u00e7ersiz k\u0131l\u0131n\u0131r.\n    <\/li>\n<li>\n        <strong><code>ENTRYPOINT<\/code>:<\/strong> Konteyneri bir y\u00fcr\u00fct\u00fclebilir dosya gibi yap\u0131land\u0131rman\u0131za olanak tan\u0131r. Genellikle uygulaman\u0131n ana komutunu (\u00f6rne\u011fin <code>java -jar app.jar<\/code> veya <code>python app.py<\/code>) burada belirtirsiniz. <code>CMD<\/code> ise bu <code>ENTRYPOINT<\/code>'e varsay\u0131lan arg\u00fcmanlar\u0131 sa\u011flar. <code>ENTRYPOINT<\/code> varsay\u0131lan olarak ge\u00e7ersiz k\u0131l\u0131namaz, ancak <code>--entrypoint<\/code> bayra\u011f\u0131 ile de\u011fi\u015ftirilebilir.\n    <\/li>\n<\/ul>\n<p><strong>\u00d6rnek Kullan\u0131m:<\/strong><\/p>\n<pre><code>\nENTRYPOINT [\"nginx\"]\nCMD [\"-g\", \"daemon off;\"]\n<\/pre>\n<p><\/code><\/p>\n<p>Bu durumda, konteyner <code>nginx -g \"daemon off;\"<\/code> komutunu \u00e7al\u0131\u015ft\u0131r\u0131r. E\u011fer <code>docker run my-nginx ls<\/code> derseniz, <code>nginx ls<\/code> \u00e7al\u0131\u015f\u0131r (<code>CMD<\/code> arg\u00fcman\u0131 <code>ls<\/code> ile ge\u00e7ersiz k\u0131l\u0131nd\u0131).<\/p>\n<p>Bu ileri d\u00fczey ipu\u00e7lar\u0131 ve teknikler, Docker imajlar\u0131n\u0131z\u0131 sadece \u00e7al\u0131\u015f\u0131r hale getirmekle kalmaz, ayn\u0131 zamanda onlar\u0131 end\u00fcstri standartlar\u0131nda, \u00fcretime haz\u0131r hale getirir. Her zaman en iyi pratikleri takip ederek daha g\u00fcvenli, verimli ve y\u00f6netilebilir Docker ortamlar\u0131 olu\u015fturabilirsiniz.<\/p>\n<h2>Uygulamal\u0131 Vaka Analizi: Modern CI\/CD S\u00fcre\u00e7lerinde Dockerfile'\u0131n Yeri<\/h2>\n<p>G\u00fcn\u00fcm\u00fcz\u00fcn \u00e7evik geli\u015ftirme d\u00fcnyas\u0131nda, Continuous Integration (CI) ve Continuous Delivery\/Deployment (CD) s\u00fcre\u00e7leri yaz\u0131l\u0131m geli\u015ftirme ya\u015fam d\u00f6ng\u00fcs\u00fcn\u00fcn vazge\u00e7ilmez bir par\u00e7as\u0131d\u0131r. CI\/CD, yaz\u0131l\u0131m\u0131n daha h\u0131zl\u0131, daha g\u00fcvenilir ve daha az hata ile m\u00fc\u015fteriye ula\u015fmas\u0131n\u0131 sa\u011flar. Bu dinamik s\u00fcre\u00e7lerin merkezinde ise Dockerfile ve onunla olu\u015fturulan Docker imajlar\u0131 yer al\u0131r. Dockerfile, CI\/CD pipeline'lar\u0131n\u0131n otomasyon ve standardizasyon hedeflerine ula\u015fmas\u0131nda kritik bir rol oynar.<\/p>\n<h3>Senaryo: Microservice Mimarisine Sahip Bir Web Uygulamas\u0131<\/h3>\n<p>Bir geli\u015ftirme ekibi, birbirine ba\u011f\u0131ml\u0131 birden fazla microservice'ten olu\u015fan (\u00f6rne\u011fin, kullan\u0131c\u0131 y\u00f6netimi, \u00fcr\u00fcn katalogu, sipari\u015f i\u015fleme) bir e-ticaret platformu \u00fczerinde \u00e7al\u0131\u015f\u0131yor. Her microservice'in kendi kodu, ba\u011f\u0131ml\u0131l\u0131klar\u0131 ve da\u011f\u0131t\u0131m d\u00f6ng\u00fcs\u00fc var. Geli\u015ftiriciler, her kod de\u011fi\u015fikli\u011finde bu servislerin h\u0131zl\u0131ca test edilip \u00fcretime al\u0131nmas\u0131n\u0131 istiyor. Bu senaryoda Dockerfile'\u0131n rol\u00fcn\u00fc inceleyelim.<\/p>\n<h4>1. S\u00fcr\u00fcm Kontrol\u00fc ve Dockerfile<\/h4>\n<p>Her microservice'in kendi Git deposu bulunur ve bu depo i\u00e7inde uygulamaya \u00f6zel bir Dockerfile yer al\u0131r. \u00d6rne\u011fin, \"Kullan\u0131c\u0131 Servisi\"nin deposunda <code>user-service\/Dockerfile<\/code> bulunur. Bu Dockerfile, servisin nas\u0131l derlenece\u011fini, ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131n nas\u0131l kurulaca\u011f\u0131n\u0131 ve nas\u0131l ba\u015flat\u0131laca\u011f\u0131n\u0131 ad\u0131m ad\u0131m belirtir. Bu, geli\u015ftiricilerin kodlar\u0131yla birlikte da\u011f\u0131t\u0131m tarifini de s\u00fcr\u00fcm kontrol\u00fcnde tutmalar\u0131 anlam\u0131na gelir. Herhangi bir zamanda, belirli bir kod s\u00fcr\u00fcm\u00fcyle hangi Dockerfile versiyonunun kullan\u0131ld\u0131\u011f\u0131n\u0131 g\u00f6rmek m\u00fcmk\u00fcnd\u00fcr, bu da tutarl\u0131l\u0131\u011f\u0131 art\u0131r\u0131r.<\/p>\n<h4>2. CI Tetikleyicileri ve \u0130maj Olu\u015fturma<\/h4>\n<p>Bir geli\u015ftirici \"Kullan\u0131c\u0131 Servisi\" kodunda de\u011fi\u015fiklik yapar ve bu de\u011fi\u015fikli\u011fi Git deposuna (\u00f6rne\u011fin, <code>main<\/code> dal\u0131na) iter. Bu eylem, bir CI\/CD arac\u0131 (\u00f6rne\u011fin Jenkins, GitLab CI, GitHub Actions) taraf\u0131ndan alg\u0131lan\u0131r ve otomatik bir pipeline tetiklenir:<\/p>\n<ol>\n<li><strong>Kodu \u00c7ekme:<\/strong> CI\/CD arac\u0131, deponun en son halini \u00e7eker.<\/li>\n<li><strong>Docker \u0130maj\u0131 Olu\u015fturma:<\/strong> CI\/CD arac\u0131, <code>Dockerfile<\/code>'\u0131 kullanarak yeni bir Docker imaj\u0131 olu\u015fturur. Bu ad\u0131m, <code>docker build -t user-service:$(git rev-parse --short HEAD) .<\/code> gibi bir komutla ger\u00e7ekle\u015ftirilebilir. Burada imaj\u0131n etiketi olarak Git commit hash'i kullan\u0131l\u0131r, bu da her imaj\u0131n belirli bir kod s\u00fcr\u00fcm\u00fcyle e\u015fle\u015fmesini sa\u011flar ve izlenebilirli\u011fi art\u0131r\u0131r.<\/li>\n<pre><code>\n# .gitlab-ci.yml veya .github\/workflows\/main.yml i\u00e7indeki bir ad\u0131m\nbuild_image:\n  stage: build\n  script:\n    - docker build -t registry.example.com\/user-service:$CI_COMMIT_SHORT_SHA .\n    - docker push registry.example.com\/user-service:$CI_COMMIT_SHORT_SHA\n  only:\n    - main\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu s\u00fcre\u00e7, <code>Dockerfile<\/code> i\u00e7indeki optimizasyonlar\u0131n (multi-stage builds, do\u011fru temel imaj se\u00e7imi vb.) ne kadar \u00f6nemli oldu\u011funu bir kez daha g\u00f6sterir, \u00e7\u00fcnk\u00fc her kod de\u011fi\u015fikli\u011finde bu imaj\u0131n h\u0131zl\u0131ca in\u015fa edilmesi gerekir.<\/p>\n<\/ol>\n<h4>3. Test S\u00fcre\u00e7leri<\/h4>\n<p>\u0130maj olu\u015fturulduktan sonra, pipeline otomatik testleri (birim testleri, entegrasyon testleri) \u00e7al\u0131\u015ft\u0131r\u0131r. Bu testler genellikle yeni olu\u015fturulan Docker imaj\u0131ndan ba\u015flat\u0131lan konteynerler \u00fczerinde yap\u0131l\u0131r. Bu sayede, test ortam\u0131n\u0131n \u00fcretim ortam\u0131yla tam olarak ayn\u0131 oldu\u011fu garanti edilir, bu da \"benim makinemde \u00e7al\u0131\u015f\u0131yordu\" sorununu ortadan kald\u0131r\u0131r. E\u011fer testler ba\u015far\u0131s\u0131z olursa, pipeline durur ve geli\u015ftiriciye geri bildirim sa\u011flan\u0131r.<\/p>\n<h4>4. Konteyner Kay\u0131t Defterine (Container Registry) G\u00f6nderme<\/h4>\n<p>T\u00fcm testler ba\u015far\u0131yla ge\u00e7tikten sonra, yeni olu\u015fturulan Docker imaj\u0131 bir konteyner kay\u0131t defterine (Docker Hub, Google Container Registry, AWS ECR, GitLab Container Registry gibi) g\u00f6nderilir. Bu kay\u0131t defteri, da\u011f\u0131t\u0131m i\u00e7in haz\u0131r olan t\u00fcm imajlar\u0131 depolar ve merkezi bir eri\u015fim noktas\u0131 sa\u011flar.<\/p>\n<h4>5. Da\u011f\u0131t\u0131m (Deployment)<\/h4>\n<p>Son olarak, CI\/CD pipeline'\u0131 yeni imaj\u0131 kullanarak uygulamay\u0131 da\u011f\u0131t\u0131r. Bu, Kubernetes gibi bir konteyner orkestrasyon arac\u0131na yeni imaj\u0131n ad\u0131n\u0131 bildirmekle veya mevcut konteynerleri yeni imajla g\u00fcncellemekle ger\u00e7ekle\u015fir. Dockerfile sayesinde, da\u011f\u0131t\u0131m s\u00fcrecinde ortam ba\u011f\u0131ml\u0131l\u0131klar\u0131 veya konfig\u00fcrasyon farkl\u0131l\u0131klar\u0131 endi\u015fesi olmaz, \u00e7\u00fcnk\u00fc her \u015fey imaj\u0131n i\u00e7inde paketlenmi\u015ftir.<\/p>\n<p>Bu vaka analizi, Dockerfile'\u0131n modern CI\/CD s\u00fcre\u00e7lerinde nas\u0131l bir k\u00f6pr\u00fc g\u00f6revi g\u00f6rd\u00fc\u011f\u00fcn\u00fc a\u00e7\u0131k\u00e7a ortaya koymaktad\u0131r. Koddan \u00fcretime giden yolu otomatikle\u015ftirmek, h\u0131zland\u0131rmak ve g\u00fcvenilir hale getirmek i\u00e7in Dockerfile vazge\u00e7ilmez bir ara\u00e7t\u0131r. Geli\u015ftiricilerin daha \u00e7ok kod yazmaya odaklanmas\u0131n\u0131 sa\u011flarken, operasyon ekiplerinin de da\u011f\u0131t\u0131m ve y\u00f6netim y\u00fck\u00fcn\u00fc hafifletir.<\/p>\n<h2>Sonu\u00e7: Dockerfile ile Gelece\u011fin Uygulama Da\u011f\u0131t\u0131m\u0131na Y\u00f6n Verin<\/h2>\n<p>Bu kapsaml\u0131 rehber boyunca, \"Dockerfile ile \u00d6zel Docker \u0130maj\u0131 Olu\u015fturma\" s\u00fcrecini en temel ad\u0131mlardan en ileri d\u00fczey optimizasyon tekniklerine kadar detayl\u0131 bir \u015fekilde inceledik. Dockerfile'\u0131n sadece bir talimat listesi olmaktan \u00f6te, uygulama da\u011f\u0131t\u0131m\u0131n\u0131n tutarl\u0131l\u0131\u011f\u0131, ta\u015f\u0131nabilirli\u011fi, g\u00fcvenli\u011fi ve otomasyonu i\u00e7in kritik bir ara\u00e7 oldu\u011funu g\u00f6rd\u00fck. Art\u0131k \"benim makinemde \u00e7al\u0131\u015f\u0131yor\" sorununu geride b\u0131rakabilir, uygulamalar\u0131n\u0131z\u0131 her ortamda istikrarl\u0131 bir \u015fekilde \u00e7al\u0131\u015ft\u0131rabilirsiniz.<\/p>\n<p>Dockerfile ile kendi \u00f6zel imajlar\u0131n\u0131z\u0131 olu\u015fturarak, uygulama geli\u015ftirme s\u00fcre\u00e7lerinizi h\u0131zland\u0131rabilir, CI\/CD pipeline'lar\u0131n\u0131z\u0131 g\u00fc\u00e7lendirebilir ve modern DevOps pratiklerini benimseyebilirsiniz. Unutmay\u0131n, iyi yaz\u0131lm\u0131\u015f bir Dockerfile, sadece bir uygulamay\u0131 paketlemekle kalmaz, ayn\u0131 zamanda gelecekteki \u00f6l\u00e7eklenebilirlik ve s\u00fcrd\u00fcr\u00fclebilirlik i\u00e7in sa\u011flam bir temel olu\u015fturur. Bu bilgileri projelerinize uygulayarak, uygulama da\u011f\u0131t\u0131m\u0131n\u0131n karma\u015f\u0131kl\u0131\u011f\u0131n\u0131 basitle\u015ftirecek ve geli\u015ftirme ekiplerinizin verimlili\u011fini art\u0131racaks\u0131n\u0131z. \u015eimdi s\u0131ra sizde, Dockerfile'\u0131n g\u00fcc\u00fcn\u00fc ke\u015ffedin ve projelerinizi bir sonraki seviyeye ta\u015f\u0131y\u0131n!<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular (SSS)<\/h3>\n<p><strong>1. Dockerfile olmadan Docker imaj\u0131 olu\u015fturabilir miyim?<\/strong><\/p>\n<p>Evet, teorik olarak Dockerfile olmadan da imaj olu\u015fturabilirsiniz. \u00d6rne\u011fin, \u00e7al\u0131\u015fan bir konteyner \u00fczerinde de\u011fi\u015fiklikler yap\u0131p bu konteyneri <code>docker commit<\/code> komutu ile yeni bir imaja d\u00f6n\u00fc\u015ft\u00fcrebilirsiniz. Ancak bu y\u00f6ntem, yeniden \u00fcretilebilirlik, s\u00fcr\u00fcm kontrol\u00fc ve otomasyon a\u00e7\u0131s\u0131ndan son derece dezavantajl\u0131d\u0131r. Dockerfile kullanmak, en iyi ve \u00f6nerilen y\u00f6ntemdir.<\/p>\n<p><strong>2. <code>COPY<\/code> ve <code>ADD<\/code> aras\u0131ndaki temel fark nedir?<\/strong><\/p>\n<p>Her ikisi de dosyalar\u0131 host sistemden konteyner i\u00e7ine kopyalar. Ancak <code>ADD<\/code>, birka\u00e7 ek \u00f6zelli\u011fe sahiptir:<\/p>\n<ul>\n<li><code>ADD<\/code>, s\u0131k\u0131\u015ft\u0131r\u0131lm\u0131\u015f (tar, gzip, bzip2, xz) dosyalar\u0131 otomatik olarak a\u00e7abilir.<\/li>\n<li><code>ADD<\/code>, bir URL'den dosya indirebilir.<\/li>\n<\/ul>\n<p>Genel olarak, yerel dosyalar\u0131 kopyalamak i\u00e7in <code>COPY<\/code> kullan\u0131lmas\u0131 \u00f6nerilir, \u00e7\u00fcnk\u00fc daha \u015feffaft\u0131r ve beklenmedik davran\u0131\u015flara yol a\u00e7ma olas\u0131l\u0131\u011f\u0131 daha d\u00fc\u015f\u00fckt\u00fcr. <code>ADD<\/code>'yi yaln\u0131zca s\u0131k\u0131\u015ft\u0131r\u0131lm\u0131\u015f dosyalar\u0131 a\u00e7man\u0131z veya URL'den indirmeniz gerekti\u011finde kullan\u0131n.<\/p>\n<p><strong>3. \u00c7ok a\u015famal\u0131 derleme (multi-stage builds) neden \u00f6nemlidir?<\/strong><\/p>\n<p>\u00c7ok a\u015famal\u0131 derlemeler, nihai Docker imaj\u0131n\u0131z\u0131n boyutunu \u00f6nemli \u00f6l\u00e7\u00fcde k\u00fc\u00e7\u00fcltmek i\u00e7in kritiktir. Genellikle, uygulaman\u0131z\u0131 derlemek i\u00e7in b\u00fcy\u00fck derleme ara\u00e7lar\u0131na, SDK'lara ve geli\u015ftirme ba\u011f\u0131ml\u0131l\u0131klar\u0131na ihtiyac\u0131n\u0131z olur. Ancak uygulaman\u0131z derlendikten sonra, bu ara\u00e7lara \u00fcretim ortam\u0131nda ihtiyac\u0131n\u0131z olmaz. \u00c7ok a\u015famal\u0131 derlemeler, bu derleme ara\u00e7lar\u0131n\u0131 i\u00e7eren bir \"derleme a\u015famas\u0131\" kullanman\u0131za ve ard\u0131ndan nihai \"\u00fcretim a\u015famas\u0131na\" sadece uygulaman\u0131n \u00e7al\u0131\u015ft\u0131r\u0131labilir \u00e7\u0131kt\u0131lar\u0131n\u0131 kopyalaman\u0131za olanak tan\u0131r. B\u00f6ylece, gereksiz katmanlar nihai imaja dahil edilmez.<\/p>\n<p><strong>4. Dockerfile'daki <code>CMD<\/code> ve <code>ENTRYPOINT<\/code> aras\u0131ndaki fark nedir?<\/strong><\/p>\n<p><code>CMD<\/code>, konteyner ba\u015flat\u0131ld\u0131\u011f\u0131nda \u00e7al\u0131\u015facak varsay\u0131lan komutu veya <code>ENTRYPOINT<\/code> komutuna arg\u00fcmanlar\u0131 sa\u011flar. E\u011fer <code>docker run<\/code> komutunda ba\u015fka bir komut belirtilirse, <code>CMD<\/code> ge\u00e7ersiz k\u0131l\u0131n\u0131r. <code>ENTRYPOINT<\/code> ise konteyneri bir y\u00fcr\u00fct\u00fclebilir dosya gibi yap\u0131land\u0131rman\u0131za olanak tan\u0131r; genellikle uygulaman\u0131n ana ba\u015flatma komutunu (\u00f6rne\u011fin <code>java -jar app.jar<\/code>) i\u00e7erir ve <code>CMD<\/code> bu <code>ENTRYPOINT<\/code>'e varsay\u0131lan arg\u00fcmanlar\u0131 sa\u011flar. <code>ENTRYPOINT<\/code> varsay\u0131lan olarak ge\u00e7ersiz k\u0131l\u0131namaz.<\/p>\n<p><strong>5. \u0130maj\u0131m\u0131 Docker Hub'a nas\u0131l y\u00fcklerim?<\/strong><\/p>\n<p>\u0130maj\u0131n\u0131z\u0131 Docker Hub'a y\u00fcklemek i\u00e7in \u00f6ncelikle bir Docker Hub hesab\u0131n\u0131z olmal\u0131 ve terminalde <code>docker login<\/code> komutuyla giri\u015f yapmal\u0131s\u0131n\u0131z. Ard\u0131ndan, imaj\u0131n\u0131z\u0131 Docker Hub kullan\u0131c\u0131 ad\u0131n\u0131zla etiketlemeniz gerekir: <code>docker tag my-flask-app:1.0 your-dockerhub-username\/my-flask-app:1.0<\/code>. Son olarak, imaj\u0131 y\u00fcklemek i\u00e7in <code>docker push your-dockerhub-username\/my-flask-app:1.0<\/code> komutunu kullanabilirsiniz.<\/p>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Uygulamalar\u0131n\u0131z\u0131 daha verimli da\u011f\u0131tmak ve y\u00f6netmek mi istiyorsunuz? Dockerfile kullanarak \u00f6zel Docker imajlar\u0131 olu\u015fturman\u0131n inceliklerini \u00f6\u011frenin ve projelerinizi&hellip;","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":[1407],"tags":[],"class_list":{"0":"post-36329","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-docker","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>Dockerfile ile Kendi Docker \u0130maj\u0131n\u0131z\u0131 Ad\u0131m Ad\u0131m Olu\u015fturun<\/title>\n<meta name=\"description\" content=\"Uygulamalar\u0131n\u0131z\u0131 daha verimli da\u011f\u0131tmak ve y\u00f6netmek mi istiyorsunuz? Dockerfile kullanarak \u00f6zel Docker imajlar\u0131 olu\u015fturman\u0131n inceliklerini \u00f6\u011frenin ve projelerinizi standardizasyonla g\u00fc\u00e7lendirin. Bu rehber, en temelden en ileri d\u00fczeye kadar her \u015feyi kaps\u0131yor.\" \/>\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\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Dockerfile ile Kendi Docker \u0130maj\u0131n\u0131z\u0131 Ad\u0131m Ad\u0131m Olu\u015fturun\" \/>\n<meta property=\"og:description\" content=\"Uygulamalar\u0131n\u0131z\u0131 daha verimli da\u011f\u0131tmak ve y\u00f6netmek mi istiyorsunuz? Dockerfile kullanarak \u00f6zel Docker imajlar\u0131 olu\u015fturman\u0131n inceliklerini \u00f6\u011frenin ve projelerinizi standardizasyonla g\u00fc\u00e7lendirin. Bu rehber, en temelden en ileri d\u00fczeye kadar her \u015feyi kaps\u0131yor.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-12-13T16:31:04+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=\"27 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Dockerfile ile Kendi Docker \u0130maj\u0131n\u0131z\u0131 Ad\u0131m Ad\u0131m Olu\u015fturun\",\"datePublished\":\"2025-12-13T16:31:04+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/\"},\"wordCount\":4728,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Docker\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/\",\"name\":\"Dockerfile ile Kendi Docker \u0130maj\u0131n\u0131z\u0131 Ad\u0131m Ad\u0131m Olu\u015fturun\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-12-13T16:31:04+00:00\",\"description\":\"Uygulamalar\u0131n\u0131z\u0131 daha verimli da\u011f\u0131tmak ve y\u00f6netmek mi istiyorsunuz? Dockerfile kullanarak \u00f6zel Docker imajlar\u0131 olu\u015fturman\u0131n inceliklerini \u00f6\u011frenin ve projelerinizi standardizasyonla g\u00fc\u00e7lendirin. Bu rehber, en temelden en ileri d\u00fczeye kadar her \u015feyi kaps\u0131yor.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Dockerfile ile Kendi Docker \u0130maj\u0131n\u0131z\u0131 Ad\u0131m Ad\u0131m Olu\u015fturun\"}]},{\"@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":"Dockerfile ile Kendi Docker \u0130maj\u0131n\u0131z\u0131 Ad\u0131m Ad\u0131m Olu\u015fturun","description":"Uygulamalar\u0131n\u0131z\u0131 daha verimli da\u011f\u0131tmak ve y\u00f6netmek mi istiyorsunuz? Dockerfile kullanarak \u00f6zel Docker imajlar\u0131 olu\u015fturman\u0131n inceliklerini \u00f6\u011frenin ve projelerinizi standardizasyonla g\u00fc\u00e7lendirin. Bu rehber, en temelden en ileri d\u00fczeye kadar her \u015feyi kaps\u0131yor.","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\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/","og_locale":"tr_TR","og_type":"article","og_title":"Dockerfile ile Kendi Docker \u0130maj\u0131n\u0131z\u0131 Ad\u0131m Ad\u0131m Olu\u015fturun","og_description":"Uygulamalar\u0131n\u0131z\u0131 daha verimli da\u011f\u0131tmak ve y\u00f6netmek mi istiyorsunuz? Dockerfile kullanarak \u00f6zel Docker imajlar\u0131 olu\u015fturman\u0131n inceliklerini \u00f6\u011frenin ve projelerinizi standardizasyonla g\u00fc\u00e7lendirin. Bu rehber, en temelden en ileri d\u00fczeye kadar her \u015feyi kaps\u0131yor.","og_url":"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-12-13T16:31:04+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"27 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Dockerfile ile Kendi Docker \u0130maj\u0131n\u0131z\u0131 Ad\u0131m Ad\u0131m Olu\u015fturun","datePublished":"2025-12-13T16:31:04+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/"},"wordCount":4728,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Docker"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/","url":"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/","name":"Dockerfile ile Kendi Docker \u0130maj\u0131n\u0131z\u0131 Ad\u0131m Ad\u0131m Olu\u015fturun","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-12-13T16:31:04+00:00","description":"Uygulamalar\u0131n\u0131z\u0131 daha verimli da\u011f\u0131tmak ve y\u00f6netmek mi istiyorsunuz? Dockerfile kullanarak \u00f6zel Docker imajlar\u0131 olu\u015fturman\u0131n inceliklerini \u00f6\u011frenin ve projelerinizi standardizasyonla g\u00fc\u00e7lendirin. Bu rehber, en temelden en ileri d\u00fczeye kadar her \u015feyi kaps\u0131yor.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/dockerfile-ile-kendi-docker-imajinizi-adim-adim-olusturun\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Dockerfile ile Kendi Docker \u0130maj\u0131n\u0131z\u0131 Ad\u0131m Ad\u0131m Olu\u015fturun"}]},{"@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\/36329","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=36329"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/36329\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=36329"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=36329"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=36329"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}