{"id":37262,"date":"2025-12-29T15:41:40","date_gmt":"2025-12-29T12:41:40","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=37262"},"modified":"2025-12-29T15:41:40","modified_gmt":"2025-12-29T12:41:40","slug":"1-on-hazirliklar-ve-gerekli-araclar","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/","title":{"rendered":"1. \u00d6n Haz\u0131rl\u0131klar ve Gerekli Ara\u00e7lar"},"content":{"rendered":"<p><body><\/p>\n<p>G\u00fcn\u00fcm\u00fcz yaz\u0131l\u0131m geli\u015ftirme d\u00fcnyas\u0131nda h\u0131z ve g\u00fcvenilirlik, rekabet avantaj\u0131 sa\u011flaman\u0131n anahtarlar\u0131d\u0131r. S\u00fcrekli Entegrasyon (CI) ve S\u00fcrekli Da\u011f\u0131t\u0131m (CD) pratikleri, bu hedeflere ula\u015fmak i\u00e7in vazge\u00e7ilmez ara\u00e7lar haline gelmi\u015ftir. Bu rehberde, GitLab CI\/CD kullanarak kodunuzu bir Ubuntu sunucusuna otomatik olarak da\u011f\u0131tacak sa\u011flam bir S\u00fcrekli Da\u011f\u0131t\u0131m (CD) hatt\u0131n\u0131 nas\u0131l kuraca\u011f\u0131n\u0131z\u0131 ad\u0131m ad\u0131m \u00f6\u011freneceksiniz.<\/p>\n<p>GitLab CI\/CD, GitLab&#8217;\u0131n kendisiyle entegre \u00e7al\u0131\u015fan g\u00fc\u00e7l\u00fc bir otomasyon arac\u0131d\u0131r. Kod depolar\u0131n\u0131zla sorunsuz bir \u015fekilde birle\u015ferek, her kod de\u011fi\u015fikli\u011finde testleri \u00e7al\u0131\u015ft\u0131rman\u0131za, derleme yapman\u0131za ve hatta uygulaman\u0131z\u0131 da\u011f\u0131tman\u0131za olanak tan\u0131r. Ubuntu ise, sunucu taraf\u0131nda en pop\u00fcler ve yayg\u0131n kullan\u0131lan i\u015fletim sistemlerinden biridir. Bu kombinasyon, geli\u015ftirme s\u00fcre\u00e7lerinizi otomatikle\u015ftirmek ve manuel hatalar\u0131 en aza indirmek i\u00e7in ideal bir \u00e7\u00f6z\u00fcm sunar.<\/p>\n<p>Bu rehberin sonunda, bir Git push i\u015flemiyle tetiklenen, testleri ge\u00e7en ve uygulaman\u0131z\u0131 belirledi\u011finiz bir Ubuntu sunucusuna otomatik olarak da\u011f\u0131tan bir CI\/CD hatt\u0131na sahip olacaks\u0131n\u0131z. Bu, geli\u015ftiricilerin kodlar\u0131n\u0131 daha h\u0131zl\u0131 ve g\u00fcvenle canl\u0131ya almalar\u0131n\u0131 sa\u011flayarak, i\u015f ak\u0131\u015f\u0131n\u0131 \u00f6nemli \u00f6l\u00e7\u00fcde h\u0131zland\u0131racakt\u0131r.<\/p>\n<h2>1. \u00d6n Haz\u0131rl\u0131klar ve Gerekli Ara\u00e7lar<\/h2>\n<p>CD hatt\u0131n\u0131 kurmaya ba\u015flamadan \u00f6nce baz\u0131 temel gereksinimleri ve ara\u00e7lar\u0131 haz\u0131r etmemiz gerekiyor. Bu ad\u0131mlar, sorunsuz bir kurulum s\u00fcreci i\u00e7in kritik \u00f6neme sahiptir.<\/p>\n<h3>GitLab Projesi ve Kod Deposu<\/h3>\n<p>\u00d6ncelikle, da\u011f\u0131t\u0131m\u0131n\u0131 yapaca\u011f\u0131n\u0131z uygulaman\u0131n kaynak kodunu i\u00e7eren bir GitLab projeniz olmal\u0131. Bu proje, CI\/CD hatt\u0131n\u0131n tetiklenece\u011fi ana merkez olacakt\u0131r. Projenizin ana dal\u0131nda (genellikle <code>main<\/code> veya <code>master<\/code>) da\u011f\u0131t\u0131ma haz\u0131r bir kod taban\u0131n\u0131z oldu\u011fundan emin olun.<\/p>\n<h3>Hedef Ubuntu Sunucusu<\/h3>\n<p>Uygulaman\u0131z\u0131 da\u011f\u0131taca\u011f\u0131m\u0131z bir Ubuntu sunucusuna ihtiyac\u0131m\u0131z var. Bu sunucuya SSH ile eri\u015fiminizin olmas\u0131 ve da\u011f\u0131t\u0131m i\u015flemlerini ger\u00e7ekle\u015ftirecek yetkilere sahip bir kullan\u0131c\u0131 hesab\u0131n\u0131z\u0131n bulunmas\u0131 gerekmektedir. Sunucunuzun g\u00fcncel oldu\u011fundan emin olmak i\u00e7in a\u015fa\u011f\u0131daki komutu \u00e7al\u0131\u015ft\u0131rabilirsiniz:<\/p>\n<pre><code class=\"language-bash\">sudo apt update && sudo apt upgrade -y\n<\/code><\/pre>\n<p>Ayr\u0131ca, sunucunuzda uygulaman\u0131z\u0131n \u00e7al\u0131\u015fmas\u0131 i\u00e7in gerekli olan t\u00fcm ba\u011f\u0131ml\u0131l\u0131klar\u0131n (Node.js, Python, Java Runtime vb.) kurulu oldu\u011fundan emin olun.<\/p>\n<h3>GitLab Runner<\/h3>\n<p>GitLab Runner, GitLab CI\/CD i\u015flerini \u00e7al\u0131\u015ft\u0131ran bir arac\u0131d\u0131r. Bu rehberde, Ubuntu sunucumuza bir GitLab Runner kurarak, CI\/CD i\u015flerinin do\u011frudan bu sunucu \u00fczerinde \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flayaca\u011f\u0131z. Runner&#8217;lar, GitLab projenizdeki <code>.gitlab-ci.yml<\/code> dosyas\u0131nda tan\u0131mlanan ad\u0131mlar\u0131 y\u00fcr\u00fct\u00fcr.<\/p>\n<h3>SSH Anahtar \u00c7ifti<\/h3>\n<p>GitLab CI\/CD hatt\u0131m\u0131z\u0131n, Ubuntu sunucumuza g\u00fcvenli bir \u015fekilde ba\u011flan\u0131p komutlar\u0131 y\u00fcr\u00fctebilmesi i\u00e7in SSH anahtar \u00e7ifti kullanaca\u011f\u0131z. Bu, parola gerektirmeyen, otomatik ve g\u00fcvenli bir ba\u011flant\u0131 sa\u011flar.<\/p>\n<h2>2. GitLab Runner Kurulumu ve Kayd\u0131<\/h2>\n<p>CD hatt\u0131m\u0131z\u0131n en kritik bile\u015fenlerinden biri olan GitLab Runner&#8217;\u0131 hedef Ubuntu sunucumuza kurup kaydedece\u011fiz. Bu sayede GitLab, da\u011f\u0131t\u0131m komutlar\u0131n\u0131 bu Runner arac\u0131l\u0131\u011f\u0131yla sunucumuzda \u00e7al\u0131\u015ft\u0131rabilecektir.<\/p>\n<h3>Runner Kurulumu<\/h3>\n<p>Ubuntu sunucunuzda a\u015fa\u011f\u0131daki ad\u0131mlar\u0131 izleyerek GitLab Runner&#8217;\u0131 kurun:<\/p>\n<ol>\n<li>Gerekli ba\u011f\u0131ml\u0131l\u0131klar\u0131 y\u00fckleyin:\n<pre><code class=\"language-bash\">sudo apt update\nsudo apt install -y curl gnupg2\n<\/code><\/pre>\n<\/li>\n<li>GitLab Runner deposunu ekleyin:\n<pre><code class=\"language-bash\">curl -L \"https:\/\/packages.gitlab.com\/install\/repositories\/runner\/gitlab-runner\/script.deb.sh\" | sudo bash\n<\/code><\/pre>\n<\/li>\n<li>GitLab Runner&#8217;\u0131 y\u00fckleyin:\n<pre><code class=\"language-bash\">sudo apt install gitlab-runner\n<\/code><\/pre>\n<\/li>\n<\/ol>\n<h3>Runner Kayd\u0131<\/h3>\n<p>Runner&#8217;\u0131 kurduktan sonra, onu GitLab projenize kaydetmeniz gerekir. Bu i\u015flem, Runner&#8217;\u0131n hangi GitLab projesiyle ileti\u015fim kuraca\u011f\u0131n\u0131 belirler.<\/p>\n<ol>\n<li>GitLab projenize gidin. Sol men\u00fcden <strong>Settings > CI\/CD<\/strong> se\u00e7ene\u011fine t\u0131klay\u0131n.<\/li>\n<li><strong>Runners<\/strong> b\u00f6l\u00fcm\u00fcn\u00fc geni\u015fletin. Burada, Runner&#8217;\u0131n\u0131z\u0131 kaydetmek i\u00e7in gerekli olan GitLab URL&#8217;ini ve Kay\u0131t Token&#8217;\u0131n\u0131 (Registration Token) bulacaks\u0131n\u0131z.<\/li>\n<li>Ubuntu sunucunuzda a\u015fa\u011f\u0131daki komutu \u00e7al\u0131\u015ft\u0131r\u0131n:\n<pre><code class=\"language-bash\">sudo gitlab-runner register\n<\/code><\/pre>\n<\/li>\n<li>Komut sizden a\u015fa\u011f\u0131daki bilgileri isteyecektir:\n<ul>\n<li><strong>GitLab instance URL:<\/strong> GitLab projenizin URL&#8217;i (\u00f6rn: <code>https:\/\/gitlab.com<\/code> veya kendi sunucunuzun URL&#8217;i).<\/li>\n<li><strong>Registration token:<\/strong> GitLab projenizin Runner ayarlar\u0131nda buldu\u011funuz token.<\/li>\n<li><strong>Description for the runner:<\/strong> Runner i\u00e7in a\u00e7\u0131klay\u0131c\u0131 bir isim (\u00f6rn: <code>ubuntu-deploy-runner<\/code>).<\/li>\n<li><strong>Tags for the runner:<\/strong> Bu \u00e7ok \u00f6nemli bir ad\u0131md\u0131r. Runner&#8217;a etiketler atay\u0131n (\u00f6rn: <code>ubuntu<\/code>, <code>production<\/code>, <code>my-app-deploy<\/code>). Bu etiketler, <code>.gitlab-ci.yml<\/code> dosyan\u0131zda belirli i\u015fleri bu Runner&#8217;a atamak i\u00e7in kullan\u0131lacakt\u0131r.<\/li>\n<li><strong>Executor:<\/strong> <code>shell<\/code> se\u00e7ene\u011fini girin. Bu, i\u015flerin do\u011frudan sunucunun kabuk ortam\u0131nda \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131n\u0131 sa\u011flar. (Daha karma\u015f\u0131k senaryolar i\u00e7in Docker veya Kubernetes de se\u00e7ilebilir).<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>Ba\u015far\u0131l\u0131 bir kayd\u0131n ard\u0131ndan, GitLab projenizin Runner&#8217;lar sayfas\u0131nda yeni Runner&#8217;\u0131n\u0131z\u0131 &#8220;Online&#8221; olarak g\u00f6rmelisiniz.<\/p>\n<h2>3. Da\u011f\u0131t\u0131m \u0130\u00e7in SSH Eri\u015fimi Ayarlar\u0131<\/h2>\n<p>GitLab CI\/CD hatt\u0131n\u0131n Ubuntu sunucumuza g\u00fcvenli ve otomatik olarak ba\u011flanabilmesi i\u00e7in SSH anahtar \u00e7ifti kullanaca\u011f\u0131z. Bu anahtar \u00e7iftini olu\u015fturacak ve GitLab CI\/CD de\u011fi\u015fkeni olarak g\u00fcvenli bir \u015fekilde saklayaca\u011f\u0131z.<\/p>\n<h3>SSH Anahtar \u00c7ifti Olu\u015fturma<\/h3>\n<p>Yerel makinenizde (veya GitLab Runner&#8217;\u0131n \u00e7al\u0131\u015ft\u0131\u011f\u0131 sunucuda ge\u00e7ici olarak) yeni bir SSH anahtar \u00e7ifti olu\u015fturun. Bu anahtar\u0131 kimseyle payla\u015fmay\u0131n ve g\u00fcvenli bir yerde saklay\u0131n:<\/p>\n<pre><code class=\"language-bash\">ssh-keygen -t rsa -b 4096 -C \"gitlab-deploy-key\" -f ~\/.ssh\/gitlab-deploy-key\n<\/code><\/pre>\n<p>Bu komut, <code>~\/.ssh\/gitlab-deploy-key<\/code> (private key) ve <code>~\/.ssh\/gitlab-deploy-key.pub<\/code> (public key) ad\u0131nda iki dosya olu\u015fturacakt\u0131r. Parola sormazsa, bo\u015f b\u0131rakmak i\u00e7in Enter tu\u015funa bas\u0131n.<\/p>\n<h3>Public Key&#8217;i Ubuntu Sunucusuna Ekleme<\/h3>\n<p>Olu\u015fturdu\u011fumuz public key&#8217;i (<code>~\/.ssh\/gitlab-deploy-key.pub<\/code>) Ubuntu sunucunuzdaki da\u011f\u0131t\u0131m kullan\u0131c\u0131s\u0131n\u0131n <code>~\/.ssh\/authorized_keys<\/code> dosyas\u0131na eklemeniz gerekiyor. Bu sayede, private key&#8217;e sahip olan herhangi bir sistem, bu kullan\u0131c\u0131 olarak sunucuya parola girmeden ba\u011flanabilecektir.<\/p>\n<p>Public key&#8217;in i\u00e7eri\u011fini kopyalay\u0131n:<\/p>\n<pre><code class=\"language-bash\">cat ~\/.ssh\/gitlab-deploy-key.pub\n<\/code><\/pre>\n<p>Kopyalad\u0131\u011f\u0131n\u0131z i\u00e7eri\u011fi Ubuntu sunucunuzdaki da\u011f\u0131t\u0131m kullan\u0131c\u0131s\u0131n\u0131n (\u00f6rn: <code>deployuser<\/code>) <code>~\/.ssh\/authorized_keys<\/code> dosyas\u0131na ekleyin. E\u011fer dosya veya dizin yoksa olu\u015fturun ve do\u011fru izinleri verin:<\/p>\n<pre><code class=\"language-bash\"># Ubuntu sunucusunda\nmkdir -p ~\/.ssh\nchmod 700 ~\/.ssh\nnano ~\/.ssh\/authorized_keys # veya tercih etti\u011finiz edit\u00f6r\n<h2>Kopyalad\u0131\u011f\u0131n\u0131z public key'i bu dosyaya yap\u0131\u015ft\u0131r\u0131n ve kaydedin<\/h2>\nchmod 600 ~\/.ssh\/authorized_keys\n<\/code><\/pre>\n<p>Bu ad\u0131mdan sonra, private key&#8217;i kullanarak Ubuntu sunucunuza parola sormadan SSH ba\u011flant\u0131s\u0131 kurabilmeniz gerekir. Test etmek i\u00e7in yerel makinenizden deneyebilirsiniz:<\/p>\n<pre><code class=\"language-bash\">ssh -i ~\/.ssh\/gitlab-deploy-key deployuser@your_ubuntu_server_ip\n<\/code><\/pre>\n<h3>GitLab CI\/CD De\u011fi\u015fkeni Olarak Private Key Ekleme<\/h3>\n<p>\u015eimdi, olu\u015fturdu\u011fumuz private key&#8217;i GitLab projemizin CI\/CD de\u011fi\u015fkenlerine ekleyece\u011fiz. Bu, private key&#8217;in <code>.gitlab-ci.yml<\/code> dosyas\u0131nda do\u011frudan g\u00f6r\u00fcnmeden g\u00fcvenli bir \u015fekilde kullan\u0131lmas\u0131na olanak tan\u0131r.<\/p>\n<ol>\n<li>GitLab projenize gidin. Sol men\u00fcden <strong>Settings > CI\/CD<\/strong> se\u00e7ene\u011fine t\u0131klay\u0131n.<\/li>\n<li><strong>Variables<\/strong> b\u00f6l\u00fcm\u00fcn\u00fc geni\u015fletin ve <strong>Add Variable<\/strong> d\u00fc\u011fmesine t\u0131klay\u0131n.<\/li>\n<li><strong>Key<\/strong> alan\u0131na <code>SSH_PRIVATE_KEY<\/code> yaz\u0131n.<\/li>\n<li><strong>Value<\/strong> alan\u0131na, <code>~\/.ssh\/gitlab-deploy-key<\/code> dosyas\u0131n\u0131n t\u00fcm i\u00e7eri\u011fini (<code>-----BEGIN RSA PRIVATE KEY-----<\/code> ile ba\u015flay\u0131p <code>-----END RSA PRIVATE KEY-----<\/code> ile biten t\u00fcm blo\u011fu) yap\u0131\u015ft\u0131r\u0131n.<\/li>\n<li><strong>Type<\/strong> olarak <code>File<\/code> se\u00e7ene\u011fini se\u00e7in. (Bu, i\u00e7eri\u011fi bir dosya olarak CI\/CD ortam\u0131na sunar, bu da SSH agent i\u00e7in daha kullan\u0131\u015fl\u0131d\u0131r.)<\/li>\n<li><strong>Protect variable<\/strong> kutucu\u011funu i\u015faretleyin. Bu, de\u011fi\u015fkenin sadece korumal\u0131 dallarda veya etiketlerde \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flar.<\/li>\n<li><strong>Mask variable<\/strong> kutucu\u011funu i\u015faretleyin. Bu, de\u011fi\u015fkenin pipeline loglar\u0131nda g\u00f6r\u00fcnmesini engeller ve g\u00fcvenlik a\u00e7\u0131s\u0131ndan \u00f6nemlidir.<\/li>\n<li><strong>Add variable<\/strong> d\u00fc\u011fmesine t\u0131klayarak kaydedin.<\/li>\n<\/ol>\n<h2>4. .gitlab-ci.yml Dosyas\u0131n\u0131 Yap\u0131land\u0131rma<\/h2>\n<p>GitLab CI\/CD hatt\u0131n\u0131n kalbi, projenizin k\u00f6k dizininde bulunan <code>.gitlab-ci.yml<\/code> dosyas\u0131d\u0131r. Bu dosya, CI\/CD i\u015flerinin hangi a\u015famalardan olu\u015faca\u011f\u0131n\u0131, hangi komutlar\u0131 \u00e7al\u0131\u015ft\u0131raca\u011f\u0131n\u0131 ve hangi ko\u015fullar alt\u0131nda tetiklenece\u011fini tan\u0131mlar.<\/p>\n<h3>Temel Yap\u0131 ve A\u015famalar<\/h3>\n<p>Tipik bir <code>.gitlab-ci.yml<\/code> dosyas\u0131, <code>stages<\/code> (a\u015famalar) ve her a\u015famaya ait i\u015fleri (jobs) tan\u0131mlar. \u00d6rne\u011fin, bir web uygulamas\u0131 i\u00e7in genellikle <code>build<\/code> (derleme), <code>test<\/code> (test etme) ve <code>deploy<\/code> (da\u011f\u0131t\u0131m) a\u015famalar\u0131 bulunur.<\/p>\n<pre><code class=\"language-yaml\">stages:\n  - build\n  - test\n  - deploy\n\nimage: node:18-alpine # Uygulaman\u0131z\u0131n t\u00fcr\u00fcne g\u00f6re (node, python, ruby vb.) de\u011fi\u015ftirin\n\ncache:\n  paths:\n    - node_modules\/ # Ba\u011f\u0131ml\u0131l\u0131klar\u0131 \u00f6nbelle\u011fe alarak build s\u00fcrelerini k\u0131salt\u0131n\n\nvariables:\n  APP_DIR: \/var\/www\/my-awesome-app # Ubuntu sunucusundaki uygulama dizini\n  SSH_USER: deployuser # Ubuntu sunucusundaki SSH kullan\u0131c\u0131s\u0131\n  SSH_HOST: your_ubuntu_server_ip # Ubuntu sunucunuzun IP adresi veya hostname\n\nbuild_job:\n  stage: build\n  script:\n    - echo \"Uygulama derleniyor...\"\n    - npm install\n    - npm run build\n  artifacts:\n    paths:\n      - build\/ # Derlenen dosyalar\u0131 sonraki a\u015famalar i\u00e7in sakla\n    expire_in: 1 day\n\ntest_job:\n  stage: test\n  script:\n    - echo \"Uygulama testleri \u00e7al\u0131\u015ft\u0131r\u0131l\u0131yor...\"\n    - npm test\n  # Sadece main branch'inde \u00e7al\u0131\u015ft\u0131r\n  only:\n    - main\n\ndeploy_production:\n  stage: deploy\n  environment:\n    name: production\n    url: http:\/\/your_ubuntu_server_ip # Canl\u0131 uygulaman\u0131z\u0131n URL'i\n  before_script:\n    - chmod 400 $SSH_PRIVATE_KEY # Private key'e do\u011fru izinleri ver\n    - eval \"$(ssh-agent -s)\" # SSH agent'\u0131 ba\u015flat\n    - ssh-add $SSH_PRIVATE_KEY # Private key'i agent'a ekle\n    - mkdir -p ~\/.ssh\n    - echo -e \"Host *\\n\\tStrictHostKeyChecking no\\n\\tUserKnownHostsFile \/dev\/null\" > ~\/.ssh\/config # Host anahtar kontrol\u00fcn\u00fc devre d\u0131\u015f\u0131 b\u0131rak (g\u00fcvenlik uyar\u0131s\u0131 a\u015fa\u011f\u0131da)\n  script:\n    - echo \"Da\u011f\u0131t\u0131m ba\u015flat\u0131l\u0131yor...\"\n    - ssh ${SSH_USER}@${SSH_HOST} \"mkdir -p ${APP_DIR} && cd ${APP_DIR} && git pull origin main\" # Sunucuda dizini olu\u015ftur ve kodu \u00e7ek\n    - ssh ${SSH_USER}@${SSH_HOST} \"cd ${APP_DIR} && npm install --production && npm run build\" # Ba\u011f\u0131ml\u0131l\u0131klar\u0131 y\u00fckle ve yeniden derle\n    - ssh ${SSH_USER}@${SSH_HOST} \"sudo systemctl restart my-app-service\" # Uygulama servisini yeniden ba\u015flat (servis ad\u0131n\u0131 de\u011fi\u015ftirin)\n    - echo \"Da\u011f\u0131t\u0131m tamamland\u0131!\"\n  only:\n    - main # Sadece main branch'ine yap\u0131lan push'larda da\u011f\u0131t\u0131m yap\n  tags:\n    - ubuntu-deploy-runner # Runner kayd\u0131 s\u0131ras\u0131nda belirledi\u011finiz etiket\n<\/code><\/pre>\n<h3>Kod \u00d6rne\u011fi A\u00e7\u0131klamas\u0131<\/h3>\n<ul>\n<li><code>stages<\/code>: Pipeline&#8217;\u0131n a\u015famalar\u0131n\u0131 tan\u0131mlar.<\/li>\n<li><code>image<\/code>: \u0130\u015flerin \u00e7al\u0131\u015faca\u011f\u0131 Docker imaj\u0131n\u0131 belirtir. Uygulaman\u0131z\u0131n teknolojisine g\u00f6re (Node.js, Python, PHP vb.) uygun bir imaj se\u00e7melisiniz.<\/li>\n<li><code>cache<\/code>: Ba\u011f\u0131ml\u0131l\u0131klar\u0131 (\u00f6rn: <code>node_modules<\/code>) \u00f6nbelle\u011fe alarak sonraki CI\/CD \u00e7al\u0131\u015ft\u0131rmalar\u0131n\u0131 h\u0131zland\u0131r\u0131r.<\/li>\n<li><code>variables<\/code>: Pipeline genelinde kullan\u0131labilecek de\u011fi\u015fkenleri tan\u0131mlar. Burada Ubuntu sunucusunun dizin, kullan\u0131c\u0131 ve IP bilgilerini sakl\u0131yoruz.<\/li>\n<li><code>build_job<\/code>: Uygulaman\u0131n ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 kurup derlendi\u011fi a\u015fama. <code>artifacts<\/code> ile derlenen dosyalar\u0131 sonraki a\u015famalara aktar\u0131r\u0131z.<\/li>\n<li><code>test_job<\/code>: Uygulaman\u0131n testlerinin ko\u015fuldu\u011fu a\u015fama. <code>only: - main<\/code> ile sadece <code>main<\/code> branch&#8217;inde \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flar\u0131z.<\/li>\n<li><code>deploy_production<\/code>:\n<ul>\n<li><code>stage: deploy<\/code>: Bu i\u015fin da\u011f\u0131t\u0131m a\u015famas\u0131nda oldu\u011funu belirtir.<\/li>\n<li><code>environment<\/code>: GitLab&#8217;\u0131n ortam \u00f6zelliklerini kullan\u0131r.<\/li>\n<li><code>before_script<\/code>: Her i\u015fin <code>script<\/code> b\u00f6l\u00fcm\u00fc \u00e7al\u0131\u015fmadan \u00f6nce y\u00fcr\u00fct\u00fclen komutlard\u0131r.\n<ul>\n<li><code>chmod 400 $SSH_PRIVATE_KEY<\/code>: GitLab de\u011fi\u015fkeni olarak ekledi\u011fimiz private key dosyas\u0131n\u0131n (<code>Type: File<\/code> oldu\u011fu i\u00e7in bir dosya olarak eri\u015filebilir) izinlerini ayarlar.<\/li>\n<li><code>eval \"$(ssh-agent -s)\"<\/code> ve <code>ssh-add $SSH_PRIVATE_KEY<\/code>: SSH agent&#8217;\u0131 ba\u015flat\u0131r ve private key&#8217;i agent&#8217;a ekler. Bu sayede sonraki <code>ssh<\/code> komutlar\u0131 otomatik olarak bu anahtar\u0131 kullan\u0131r.<\/li>\n<li><code>echo -e \"Host ... StrictHostKeyChecking no\"<\/code>: Bu sat\u0131r, ilk SSH ba\u011flant\u0131s\u0131nda sunucu anahtar parmak izini sormay\u0131 devre d\u0131\u015f\u0131 b\u0131rak\u0131r. <strong>G\u00fcvenlik Notu:<\/strong> \u00dcretim ortamlar\u0131nda bu ayar\u0131 kullan\u0131rken dikkatli olun. Daha g\u00fcvenli bir yakla\u015f\u0131m, bilinen anahtarlar\u0131 (<code>known_hosts<\/code>) GitLab de\u011fi\u015fkeni olarak eklemek veya SSH taray\u0131c\u0131 parmak izini \u00f6nceden eklemektir. Ancak basit CD kurulumlar\u0131 i\u00e7in bu pratik bir yakla\u015f\u0131md\u0131r.<\/li>\n<\/ul>\n<\/li>\n<li><code>script<\/code>: Da\u011f\u0131t\u0131m\u0131n as\u0131l ad\u0131mlar\u0131 burada yer al\u0131r.\n<ul>\n<li><code>ssh ${SSH_USER}@${SSH_HOST} \"...\"<\/code>: Uzak Ubuntu sunucusunda komutlar\u0131 y\u00fcr\u00fct\u00fcr.\n<ul>\n<li><code>mkdir -p ${APP_DIR} && cd ${APP_DIR} && git pull origin main<\/code>: Uygulama dizinini olu\u015fturur, oraya gider ve kod deposunu \u00e7eker.<\/li>\n<li><code>npm install --production && npm run build<\/code>: Uygulaman\u0131n ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 kurar ve yeniden derler. Uygulaman\u0131z\u0131n gereksinimlerine g\u00f6re bu komutlar de\u011fi\u015febilir (\u00f6rn: <code>pip install -r requirements.txt<\/code>, <code>composer install<\/code>).<\/li>\n<li><code>sudo systemctl restart my-app-service<\/code>: Uygulaman\u0131z\u0131n sistem servisini yeniden ba\u015flat\u0131r. Uygulaman\u0131z\u0131n nas\u0131l \u00e7al\u0131\u015ft\u0131\u011f\u0131na ba\u011fl\u0131 olarak bu komutu ayarlaman\u0131z gerekir (\u00f6rn: <code>pm2 restart my-app<\/code>, <code>gunicorn restart<\/code>).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li><code>only: - main<\/code>: Bu i\u015fin sadece <code>main<\/code> branch&#8217;ine yap\u0131lan push&#8217;larda tetiklenmesini sa\u011flar.<\/li>\n<li><code>tags: - ubuntu-deploy-runner<\/code>: Bu i\u015fi, daha \u00f6nce kaydetti\u011fimiz ve bu etikete sahip olan Runner&#8217;\u0131n \u00e7al\u0131\u015ft\u0131rmas\u0131n\u0131 sa\u011flar. Bu, birden fazla Runner&#8217;\u0131n\u0131z oldu\u011funda belirli i\u015fleri belirli sunuculara atamak i\u00e7in kullan\u0131l\u0131r.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2>5. Da\u011f\u0131t\u0131m Sonras\u0131 Kontroller ve \u0130yile\u015ftirmeler<\/h2>\n<p>CD hatt\u0131n\u0131 kurduktan sonra, her \u015feyin beklendi\u011fi gibi \u00e7al\u0131\u015ft\u0131\u011f\u0131ndan emin olmak ve gelecekteki iyile\u015ftirmeler i\u00e7in baz\u0131 noktalar\u0131 g\u00f6z \u00f6n\u00fcnde bulundurmak \u00f6nemlidir.<\/p>\n<h3>Hata Ay\u0131klama (Troubleshooting)<\/h3>\n<p>Pipeline&#8217;\u0131n\u0131z ba\u015far\u0131s\u0131z olursa endi\u015felenmeyin. GitLab CI\/CD, her i\u015f i\u00e7in detayl\u0131 loglar sunar. Pipeline&#8217;\u0131n\u0131z\u0131n \u00e7\u0131kt\u0131s\u0131n\u0131 dikkatlice inceleyerek hatan\u0131n nerede oldu\u011funu belirleyebilirsiniz:<\/p>\n<ul>\n<li><strong>SSH Ba\u011flant\u0131 Sorunlar\u0131:<\/strong> Loglarda &#8220;Permission denied (publickey)&#8221; veya &#8220;Host key verification failed&#8221; gibi hatalar g\u00f6r\u00fcyorsan\u0131z, SSH anahtar \u00e7iftinizin do\u011fru ayarland\u0131\u011f\u0131ndan, public key&#8217;in Ubuntu sunucusundaki <code>authorized_keys<\/code> dosyas\u0131na do\u011fru eklendi\u011finden ve <code>SSH_PRIVATE_KEY<\/code> de\u011fi\u015fkeninin GitLab&#8217;da do\u011fru de\u011ferle ve izinlerle tan\u0131mland\u0131\u011f\u0131ndan emin olun.<\/li>\n<li><strong>Komut Hatalar\u0131:<\/strong> Uzak sunucuda \u00e7al\u0131\u015ft\u0131r\u0131lan komutlarda (<code>git pull<\/code>, <code>npm install<\/code>, <code>systemctl restart<\/code> vb.) hatalar al\u0131yorsan\u0131z, komutlar\u0131n Ubuntu sunucusunda manuel olarak \u00e7al\u0131\u015ft\u0131r\u0131ld\u0131\u011f\u0131nda da ayn\u0131 hatay\u0131 verip vermedi\u011fini kontrol edin. \u0130zin sorunlar\u0131, ba\u011f\u0131ml\u0131l\u0131k eksiklikleri veya yanl\u0131\u015f dizinler yayg\u0131n nedenlerdir.<\/li>\n<li><strong>Runner Etiketi:<\/strong> \u0130\u015finizin \u00e7al\u0131\u015fmad\u0131\u011f\u0131n\u0131 g\u00f6r\u00fcyorsan\u0131z, <code>.gitlab-ci.yml<\/code> dosyas\u0131ndaki <code>tags<\/code> b\u00f6l\u00fcm\u00fcn\u00fcn, Runner kayd\u0131 s\u0131ras\u0131nda verdi\u011finiz etiketle tam olarak e\u015fle\u015fti\u011finden emin olun.<\/li>\n<\/ul>\n<h3>\u0130yile\u015ftirme \u00d6nerileri<\/h3>\n<p>Bu temel CD hatt\u0131n\u0131 kurduktan sonra, projenizin ihtiya\u00e7lar\u0131na g\u00f6re daha da geli\u015ftirebilirsiniz:<\/p>\n<ul>\n<li><strong>Ortam De\u011fi\u015fkenleri:<\/strong> Geli\u015ftirme, haz\u0131rl\u0131k (staging) ve \u00fcretim (production) gibi farkl\u0131 ortamlar i\u00e7in ayr\u0131 da\u011f\u0131t\u0131m i\u015fleri olu\u015fturabilir ve her ortam i\u00e7in farkl\u0131 de\u011fi\u015fkenler (veritaban\u0131 ba\u011flant\u0131 bilgileri, API anahtarlar\u0131 vb.) kullanabilirsiniz.<\/li>\n<li><strong>Rollback Stratejileri:<\/strong> Da\u011f\u0131t\u0131m sonras\u0131 kritik bir hata olu\u015fursa, h\u0131zl\u0131 bir \u015fekilde \u00f6nceki s\u00fcr\u00fcme d\u00f6nmenizi sa\u011flayacak bir geri alma (rollback) stratejisi ekleyin. Bu, genellikle \u00f6nceki bir Git commit&#8217;ine d\u00f6nmek veya uygulaman\u0131n \u00f6nceki bir derlemesini yeniden da\u011f\u0131tmak \u015feklinde olabilir.<\/li>\n<li><strong>Docker Compose Kullan\u0131m\u0131:<\/strong> Uygulaman\u0131z birden fazla servisten (veritaban\u0131, \u00f6n u\u00e7, arka u\u00e7 vb.) olu\u015fuyorsa, Docker Compose kullanarak da\u011f\u0131t\u0131m s\u00fcrecini daha da basitle\u015ftirebilirsiniz. Runner&#8217;\u0131n\u0131zda Docker executor kullanmak bu senaryoda daha uygun olabilir.<\/li>\n<li><strong>Bildirimler:<\/strong> Da\u011f\u0131t\u0131m\u0131n ba\u015far\u0131l\u0131 veya ba\u015far\u0131s\u0131z oldu\u011fu durumlarda Slack, E-posta veya di\u011fer ara\u00e7lar arac\u0131l\u0131\u011f\u0131yla bildirimler g\u00f6ndererek ekip \u00fcyelerini bilgilendirebilirsiniz.<\/li>\n<li><strong>G\u00fcvenlik \u0130yile\u015ftirmeleri:<\/strong> <code>StrictHostKeyChecking no<\/code> yerine, ilk ba\u011flant\u0131da host key&#8217;i manuel olarak ekleyerek veya bir GitLab de\u011fi\u015fkeni arac\u0131l\u0131\u011f\u0131yla <code>known_hosts<\/code> dosyas\u0131n\u0131 olu\u015fturarak daha g\u00fcvenli bir SSH ba\u011flant\u0131s\u0131 sa\u011flayabilirsiniz.<\/li>\n<li><strong>Veritaban\u0131 Migrasyonlar\u0131:<\/strong> Uygulaman\u0131z veritaban\u0131 kullan\u0131yorsa, da\u011f\u0131t\u0131m sonras\u0131 veritaban\u0131 migrasyonlar\u0131n\u0131 otomatik olarak \u00e7al\u0131\u015ft\u0131racak ad\u0131mlar eklemeyi unutmay\u0131n.<\/li>\n<\/ul>\n<h2>Sonu\u00e7 ve S\u0131k\u00e7a Sorulan Sorular<\/h2>\n<p>Bu rehberde, GitLab CI\/CD kullanarak bir Ubuntu sunucusuna otomatik da\u011f\u0131t\u0131m yapan bir S\u00fcrekli Da\u011f\u0131t\u0131m hatt\u0131n\u0131 nas\u0131l kuraca\u011f\u0131n\u0131z\u0131 \u00f6\u011frendiniz. GitLab Runner&#8217;\u0131n kurulumundan, SSH anahtar \u00e7ifti y\u00f6netimine ve <code>.gitlab-ci.yml<\/code> dosyas\u0131n\u0131n yap\u0131land\u0131rmas\u0131na kadar t\u00fcm \u00f6nemli ad\u0131mlar\u0131 ele ald\u0131k. Art\u0131k kod de\u011fi\u015fikliklerinizi daha h\u0131zl\u0131, g\u00fcvenli ve otomatik bir \u015fekilde canl\u0131ya alabilirsiniz. Bu, geli\u015ftirme s\u00fcre\u00e7lerinizi optimize etmenize ve pazar\u0131n\u0131za daha h\u0131zl\u0131 de\u011fer sunman\u0131za yard\u0131mc\u0131 olacakt\u0131r.<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular (SSS)<\/h3>\n<p><strong>S: Neden <code>StrictHostKeyChecking=no<\/code> kullan\u0131ld\u0131 ve bu g\u00fcvenli mi?<\/strong><br \/>\nC: <code>StrictHostKeyChecking=no<\/code>, SSH ba\u011flant\u0131s\u0131 s\u0131ras\u0131nda sunucunun anahtar parmak izini ilk kez do\u011frulamay\u0131 atlar. CI\/CD ortam\u0131nda, manuel etkile\u015fimi ortadan kald\u0131rmak i\u00e7in bazen kullan\u0131l\u0131r. Ancak, bu, potansiyel bir &#8220;man-in-the-middle&#8221; sald\u0131r\u0131s\u0131na kar\u015f\u0131 daha savunmas\u0131z hale getirir. \u00dcretim ortamlar\u0131nda, daha g\u00fcvenli bir yakla\u015f\u0131m, sunucunun anahtar parmak izini (public key&#8217;ini) \u00f6nceden <code>known_hosts<\/code> dosyas\u0131na eklemek veya GitLab CI\/CD de\u011fi\u015fkeni olarak g\u00fcvenli bir \u015fekilde saklamakt\u0131r.<\/p>\n<p><strong>S: Birden fazla sunucuya nas\u0131l da\u011f\u0131t\u0131m yap\u0131l\u0131r?<\/strong><br \/>\nC: Birden fazla sunucuya da\u011f\u0131t\u0131m yapmak i\u00e7in <code>.gitlab-ci.yml<\/code> dosyan\u0131zda her sunucu i\u00e7in ayr\u0131 bir da\u011f\u0131t\u0131m i\u015fi tan\u0131mlayabilir veya bir d\u00f6ng\u00fc i\u00e7inde t\u00fcm sunuculara da\u011f\u0131t\u0131m yapacak bir script yazabilirsiniz. Her sunucu i\u00e7in farkl\u0131 <code>SSH_HOST<\/code> de\u011fi\u015fkenleri veya etiketlenmi\u015f farkl\u0131 Runner&#8217;lar kullanabilirsiniz.<\/p>\n<p><strong>S: Runner&#8217;\u0131 Docker executor olarak kullanman\u0131n avantajlar\u0131 nelerdir?<\/strong><br \/>\nC: Docker executor kullanmak, her CI\/CD i\u015finin izole bir Docker konteyneri i\u00e7inde \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flar. Bu, ba\u011f\u0131ml\u0131l\u0131k \u00e7ak\u0131\u015fmalar\u0131n\u0131 \u00f6nler, ortam\u0131n tutarl\u0131l\u0131\u011f\u0131n\u0131 garanti eder ve i\u015flerin yerel makinenizdeki ortamdan tamamen ba\u011f\u0131ms\u0131z olmas\u0131n\u0131 sa\u011flar. \u00d6zellikle farkl\u0131 projeler veya farkl\u0131 ba\u011f\u0131ml\u0131l\u0131klara sahip a\u015famalar i\u00e7in \u00e7ok kullan\u0131\u015fl\u0131d\u0131r.<\/p>\n<p><strong>S: Da\u011f\u0131t\u0131m sonras\u0131 veritaban\u0131 migrasyonlar\u0131 nas\u0131l y\u00f6netilir?<\/strong><br \/>\nC: Veritaban\u0131 migrasyonlar\u0131, <code>.gitlab-ci.yml<\/code> dosyas\u0131ndaki da\u011f\u0131t\u0131m a\u015famas\u0131n\u0131n bir par\u00e7as\u0131 olarak \u00e7al\u0131\u015ft\u0131r\u0131labilir. \u00d6rne\u011fin, uygulaman\u0131z bir ORM (Object-Relational Mapper) kullan\u0131yorsa, da\u011f\u0131t\u0131m script&#8217;inize <code>ssh ${SSH_USER}@${SSH_HOST} \"cd ${APP_DIR} && python manage.py migrate\"<\/code> (Django i\u00e7in) veya <code>ssh ${SSH_USER}@${SSH_HOST} \"cd ${APP_DIR} && npx prisma migrate deploy\"<\/code> (Prisma i\u00e7in) gibi bir komut ekleyebilirsiniz. Bu komutlar\u0131n, uygulaman\u0131z\u0131n kod taban\u0131n\u0131 g\u00fcncelledikten hemen sonra \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131 \u00f6nemlidir.<\/p>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"G\u00fcn\u00fcm\u00fcz yaz\u0131l\u0131m geli\u015ftirme d\u00fcnyas\u0131nda h\u0131z ve g\u00fcvenilirlik, rekabet avantaj\u0131 sa\u011flaman\u0131n anahtarlar\u0131d\u0131r. S\u00fcrekli Entegrasyon (CI) ve S\u00fc","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":[1],"tags":[],"class_list":{"0":"post-37262","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","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>1. \u00d6n Haz\u0131rl\u0131klar ve Gerekli Ara\u00e7lar - 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\/1-on-hazirliklar-ve-gerekli-araclar\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"1. \u00d6n Haz\u0131rl\u0131klar ve Gerekli Ara\u00e7lar\" \/>\n<meta property=\"og:description\" content=\"G\u00fcn\u00fcm\u00fcz yaz\u0131l\u0131m geli\u015ftirme d\u00fcnyas\u0131nda h\u0131z ve g\u00fcvenilirlik, rekabet avantaj\u0131 sa\u011flaman\u0131n anahtarlar\u0131d\u0131r. S\u00fcrekli Entegrasyon (CI) ve S\u00fc\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-12-29T12:41:40+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=\"16 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"1. \u00d6n Haz\u0131rl\u0131klar ve Gerekli Ara\u00e7lar\",\"datePublished\":\"2025-12-29T12:41:40+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/\"},\"wordCount\":2557,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/\",\"name\":\"1. \u00d6n Haz\u0131rl\u0131klar ve Gerekli Ara\u00e7lar - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-12-29T12:41:40+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"1. \u00d6n Haz\u0131rl\u0131klar ve Gerekli Ara\u00e7lar\"}]},{\"@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":"1. \u00d6n Haz\u0131rl\u0131klar ve Gerekli Ara\u00e7lar - 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\/1-on-hazirliklar-ve-gerekli-araclar\/","og_locale":"tr_TR","og_type":"article","og_title":"1. \u00d6n Haz\u0131rl\u0131klar ve Gerekli Ara\u00e7lar","og_description":"G\u00fcn\u00fcm\u00fcz yaz\u0131l\u0131m geli\u015ftirme d\u00fcnyas\u0131nda h\u0131z ve g\u00fcvenilirlik, rekabet avantaj\u0131 sa\u011flaman\u0131n anahtarlar\u0131d\u0131r. S\u00fcrekli Entegrasyon (CI) ve S\u00fc","og_url":"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-12-29T12:41:40+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"16 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"1. \u00d6n Haz\u0131rl\u0131klar ve Gerekli Ara\u00e7lar","datePublished":"2025-12-29T12:41:40+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/"},"wordCount":2557,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/","url":"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/","name":"1. \u00d6n Haz\u0131rl\u0131klar ve Gerekli Ara\u00e7lar - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-12-29T12:41:40+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/1-on-hazirliklar-ve-gerekli-araclar\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"1. \u00d6n Haz\u0131rl\u0131klar ve Gerekli Ara\u00e7lar"}]},{"@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\/37262","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=37262"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/37262\/revisions"}],"predecessor-version":[{"id":37263,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/37262\/revisions\/37263"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=37262"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=37262"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=37262"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}