{"id":31631,"date":"2025-10-12T03:41:00","date_gmt":"2025-10-12T00:41:00","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=31631"},"modified":"2025-10-12T03:41:00","modified_gmt":"2025-10-12T00:41:00","slug":"github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/","title":{"rendered":"GitHub Actions ile DigitalOcean&#8217;a Otomatik Da\u011f\u0131t\u0131m: Kapsaml\u0131 Bir Rehber"},"content":{"rendered":"<p><body><\/p>\n<h2>GitHub Actions ile DigitalOcean&#8217;a Otomatik Da\u011f\u0131t\u0131m: Kapsaml\u0131 Bir Rehber<\/h2>\n<h3>Giri\u015f<\/h3>\n<p>Modern yaz\u0131l\u0131m geli\u015ftirme s\u00fcre\u00e7lerinde h\u0131z, g\u00fcvenilirlik ve verimlilik, ba\u015far\u0131 i\u00e7in kritik \u00f6neme sahiptir. Uygulamalar\u0131n s\u00fcrekli entegrasyon (CI) ve s\u00fcrekli da\u011f\u0131t\u0131m (CD) pratikleri arac\u0131l\u0131\u011f\u0131yla otomatik olarak test edilmesi ve da\u011f\u0131t\u0131lmas\u0131, geli\u015ftiricilerin daha h\u0131zl\u0131 inovasyon yapmas\u0131na ve \u00fcr\u00fcnlerini pazara daha \u00e7abuk sunmas\u0131na olanak tan\u0131r. Bu ba\u011flamda, GitHub Actions ve DigitalOcean gibi g\u00fc\u00e7l\u00fc ara\u00e7lar\u0131n birle\u015fimi, geli\u015ftiricilere bulut ortam\u0131na otomatik da\u011f\u0131t\u0131m i\u00e7in kusursuz bir yol sunar.<\/p>\n<p>Bu makale, GitHub Actions kullanarak DigitalOcean&#8217;a nas\u0131l otomatik da\u011f\u0131t\u0131m yap\u0131laca\u011f\u0131n\u0131 ad\u0131m ad\u0131m detayland\u0131racakt\u0131r. \u0130ki ana DigitalOcean hizmeti olan Droplets (sanal makineler) ve App Platform (y\u00f6netilen uygulama platformu) i\u00e7in da\u011f\u0131t\u0131m senaryolar\u0131n\u0131 ele alacak, gerekli yap\u0131land\u0131rmalar\u0131, en iyi uygulamalar\u0131 ve s\u0131k kar\u015f\u0131la\u015f\u0131lan sorunlar\u0131 tart\u0131\u015faca\u011f\u0131z. Amac\u0131m\u0131z, geli\u015ftiricilerin CI\/CD s\u00fcre\u00e7lerini otomatize ederek geli\u015ftirme d\u00f6ng\u00fclerini h\u0131zland\u0131rmalar\u0131na ve operasyonel y\u00fcklerini azaltmalar\u0131na yard\u0131mc\u0131 olmakt\u0131r.<\/p>\n<h3>CI\/CD Nedir ve Neden \u00d6nemlidir?<\/h3>\n<p>CI\/CD, Continuous Integration (S\u00fcrekli Entegrasyon) ve Continuous Delivery\/Deployment (S\u00fcrekli Teslimat\/Da\u011f\u0131t\u0131m) kavramlar\u0131n\u0131n k\u0131saltmas\u0131d\u0131r. Yaz\u0131l\u0131m geli\u015ftirme ya\u015fam d\u00f6ng\u00fcs\u00fcn\u00fc otomatikle\u015ftirmeyi ve iyile\u015ftirmeyi ama\u00e7layan bir dizi prensip ve pratikten olu\u015fur.<\/p>\n<h4>S\u00fcrekli Entegrasyon (CI)<\/h4>\n<p>S\u00fcrekli Entegrasyon, geli\u015ftiricilerin kod de\u011fi\u015fikliklerini ana kod taban\u0131na d\u00fczenli olarak, genellikle g\u00fcnde birka\u00e7 kez, entegre etme prati\u011fidir. Her entegrasyon, otomatik testler (birim testleri, entegrasyon testleri) ve derleme (build) s\u00fcre\u00e7leriyle do\u011frulan\u0131r. CI&#8217;nin temel amac\u0131, entegrasyon sorunlar\u0131n\u0131 erken a\u015famada tespit etmek ve \u00e7\u00f6zmek, b\u00f6ylece b\u00fcy\u00fck entegrasyon \u00e7at\u0131\u015fmalar\u0131n\u0131 \u00f6nlemektir. Bu, kod kalitesini art\u0131r\u0131r ve geli\u015ftirme ekibinin daha g\u00fcvenle \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flar.<\/p>\n<h4>S\u00fcrekli Teslimat (CD) ve S\u00fcrekli Da\u011f\u0131t\u0131m (CD)<\/h4>\n<p>S\u00fcrekli Teslimat (Continuous Delivery), CI&#8217;nin bir uzant\u0131s\u0131d\u0131r. Kod de\u011fi\u015fikliklerinin test edildikten ve derlendikten sonra, manuel bir onayla \u00fcretime da\u011f\u0131t\u0131ma haz\u0131r hale getirilmesini sa\u011flar. Bu, her an g\u00fcvenle da\u011f\u0131t\u0131labilecek bir yaz\u0131l\u0131m s\u00fcr\u00fcm\u00fc oldu\u011fu anlam\u0131na gelir. S\u00fcrekli Da\u011f\u0131t\u0131m (Continuous Deployment) ise S\u00fcrekli Teslimat&#8217;\u0131n bir ad\u0131m \u00f6tesidir. Kod de\u011fi\u015fiklikleri, otomatik testlerden ge\u00e7tikten sonra herhangi bir insan m\u00fcdahalesi olmadan otomatik olarak \u00fcretime da\u011f\u0131t\u0131l\u0131r. Bu, yaz\u0131l\u0131m\u0131n pazara sunulma s\u00fcresini (time-to-market) \u00f6nemli \u00f6l\u00e7\u00fcde k\u0131salt\u0131r.<\/p>\n<h4>CI\/CD&#8217;nin Faydalar\u0131<\/h4>\n<p>*   <strong>Daha H\u0131zl\u0131 Teslimat:<\/strong> Otomatik s\u00fcre\u00e7ler sayesinde yaz\u0131l\u0131m daha s\u0131k ve daha h\u0131zl\u0131 bir \u015fekilde kullan\u0131c\u0131lara ula\u015ft\u0131r\u0131l\u0131r.<br \/>\n*   <strong>Daha Az Hata:<\/strong> Otomatik testler, hatalar\u0131n erken a\u015famada yakalanmas\u0131n\u0131 sa\u011flar, bu da \u00fcretim ortam\u0131na ula\u015fan hata say\u0131s\u0131n\u0131 azalt\u0131r.<br \/>\n*   <strong>Geli\u015ftirici Verimlili\u011fi:<\/strong> Geli\u015ftiriciler manuel da\u011f\u0131t\u0131m s\u00fcre\u00e7leriyle u\u011fra\u015fmak yerine kod yazmaya odaklanabilirler.<br \/>\n*   <strong>Daha \u0130yi Kod Kalitesi:<\/strong> D\u00fczenli entegrasyon ve otomatik testler, kod kalitesini s\u00fcrekli olarak y\u00fcksek tutar.<br \/>\n*   <strong>Geri Alma Kolayl\u0131\u011f\u0131:<\/strong> Ba\u015far\u0131s\u0131z da\u011f\u0131t\u0131mlar durumunda, \u00f6nceki kararl\u0131 s\u00fcr\u00fcme geri d\u00f6nmek genellikle daha kolayd\u0131r.<\/p>\n<h3>GitHub Actions&#8217;a Yak\u0131ndan Bak\u0131\u015f<\/h3>\n<p>GitHub Actions, GitHub&#8217;\u0131n do\u011frudan entegre edilmi\u015f bir CI\/CD platformudur. Deponuzdaki olaylara (push, pull request vb.) yan\u0131t olarak kod derleme, test etme ve da\u011f\u0131tma gibi otomasyon g\u00f6revlerini ger\u00e7ekle\u015ftirmenizi sa\u011flar.<\/p>\n<h4>Temel Bile\u015fenler<\/h4>\n<p>*   <strong>Workflow (\u0130\u015f Ak\u0131\u015f\u0131):<\/strong> GitHub Actions&#8217;\u0131n kalbidir. <code>.github\/workflows<\/code> dizininde depolanan YAML dosyalar\u0131yla tan\u0131mlan\u0131r. Bir i\u015f ak\u0131\u015f\u0131, bir veya daha fazla i\u015f (job) i\u00e7erir ve belirli bir olay (event) taraf\u0131ndan tetiklenir.<br \/>\n*   <strong>Event (Olay):<\/strong> Bir i\u015f ak\u0131\u015f\u0131n\u0131 tetikleyen belirli bir aktivite veya durumdur. \u00d6rnekler aras\u0131nda bir <code>push<\/code> olay\u0131 (koda yeni commit g\u00f6nderildi\u011finde), bir <code>pull_request<\/code> a\u00e7\u0131ld\u0131\u011f\u0131nda, <code>schedule<\/code> (belirli zamanlarda) veya <code>workflow_dispatch<\/code> (manuel tetikleme) yer al\u0131r.<br \/>\n*   <strong>Job (\u0130\u015f):<\/strong> Bir i\u015f ak\u0131\u015f\u0131n\u0131n i\u00e7indeki mant\u0131ksal birimdir. Bir veya daha fazla ad\u0131m (step) i\u00e7erir ve kendi sanal makinesinde (runner) \u00e7al\u0131\u015f\u0131r. \u0130\u015fler birbirine ba\u011f\u0131ml\u0131 olabilir veya paralel olarak \u00e7al\u0131\u015fabilir.<br \/>\n*   <strong>Step (Ad\u0131m):<\/strong> Bir i\u015fin i\u00e7indeki tekil bir g\u00f6revdir. Bir komut (\u00f6rne\u011fin, <code>run: npm install<\/code>) veya bir eylem (action) \u00e7al\u0131\u015ft\u0131rabilir.<br \/>\n*   <strong>Action (Eylem):<\/strong> Tekrar kullan\u0131labilir birimlerdir. Bir komut dosyas\u0131n\u0131, bir Docker kapsay\u0131c\u0131s\u0131n\u0131 veya bir JavaScript uygulamas\u0131n\u0131 \u00e7al\u0131\u015ft\u0131ran \u00f6nceden olu\u015fturulmu\u015f g\u00f6revlerdir. GitHub Marketplace&#8217;te bir\u00e7ok haz\u0131r eylem bulunur veya kendi \u00f6zel eylemlerinizi yazabilirsiniz. \u00d6rne\u011fin, <code>actions\/checkout@v4<\/code> deposu kodunu runner&#8217;a kopyalamak i\u00e7in kullan\u0131lan pop\u00fcler bir eylemdir.<br \/>\n*   <strong>Runner (Ko\u015fucu):<\/strong> \u0130\u015f ak\u0131\u015f\u0131ndaki i\u015fleri y\u00fcr\u00fcten sanal makinelerdir. GitHub taraf\u0131ndan bar\u0131nd\u0131r\u0131lan runner&#8217;lar (Ubuntu, Windows, macOS) veya kendi bar\u0131nd\u0131rd\u0131\u011f\u0131n\u0131z runner&#8217;lar kullanabilirsiniz. GitHub taraf\u0131ndan bar\u0131nd\u0131r\u0131lan runner&#8217;lar, her i\u015f i\u00e7in temiz bir ortam sa\u011flar.<br \/>\n*   <strong>Secrets (S\u0131rlar):<\/strong> Hassas bilgileri (API anahtarlar\u0131, SSH \u00f6zel anahtarlar\u0131, parolalar) g\u00fcvenli bir \u015fekilde depolamak i\u00e7in kullan\u0131l\u0131r. GitHub deposu ayarlar\u0131nda tan\u0131mlan\u0131r ve i\u015f ak\u0131\u015flar\u0131nda <code>secrets.SECRET_NAME<\/code> \u015feklinde referans verilir. Bu s\u0131rlar, loglarda veya i\u015f ak\u0131\u015f\u0131 \u00e7\u0131kt\u0131lar\u0131nda asla g\u00f6r\u00fcnmez.<\/p>\n<h3>DigitalOcean&#8217;a Yak\u0131ndan Bak\u0131\u015f<\/h3>\n<p>DigitalOcean, geli\u015ftiriciler i\u00e7in tasarlanm\u0131\u015f basit, \u00f6l\u00e7eklenebilir ve uygun fiyatl\u0131 bir bulut platformudur. Uygulamalar\u0131 da\u011f\u0131tmak ve y\u00f6netmek i\u00e7in \u00e7e\u015fitli hizmetler sunar.<\/p>\n<h4>Temel Hizmetler (Da\u011f\u0131t\u0131m \u0130\u00e7in \u0130lgili Olanlar)<\/h4>\n<p>*   <strong>Droplets (Sanal Makineler):<\/strong> DigitalOcean&#8217;\u0131n temel hizmetidir. Linux tabanl\u0131 sanal \u00f6zel sunuculard\u0131r (VPS). Geli\u015ftiricilere tam kontrol sa\u011flar; i\u015fletim sistemi, yaz\u0131l\u0131m y\u0131\u011f\u0131n\u0131 ve yap\u0131land\u0131rma \u00fczerinde tam yetkiye sahip olursunuz. Geleneksel sunucu da\u011f\u0131t\u0131mlar\u0131 i\u00e7in idealdir.<br \/>\n*   <strong>App Platform:<\/strong> Kaynak kodu do\u011frudan ba\u011flayarak veya bir container imaj\u0131 sa\u011flayarak uygulamalar\u0131 h\u0131zl\u0131 bir \u015fekilde da\u011f\u0131tman\u0131za olanak tan\u0131yan y\u00f6netilen bir platformdur. Altyap\u0131 y\u00f6netimiyle u\u011fra\u015fmak istemeyen veya daha h\u0131zl\u0131 da\u011f\u0131t\u0131m d\u00f6ng\u00fclerine ihtiya\u00e7 duyan geli\u015ftiriciler i\u00e7in tasarlanm\u0131\u015ft\u0131r. \u00c7e\u015fitli dilleri ve framework&#8217;leri (Node.js, Python, Go, PHP, Ruby vb.) destekler ve otomatik \u00f6l\u00e7eklendirme, HTTPS, veritaban\u0131 entegrasyonu gibi \u00f6zellikleri sa\u011flar.<br \/>\n*   <strong>Managed Kubernetes:<\/strong> Konteynerize edilmi\u015f uygulamalar\u0131 \u00f6l\u00e7ekli olarak \u00e7al\u0131\u015ft\u0131rmak i\u00e7in y\u00f6netilen Kubernetes k\u00fcmeleri sunar. Mikroservis mimarileri ve karma\u015f\u0131k uygulamalar i\u00e7in uygundur.<br \/>\n*   <strong>Spaces (Nesne Depolama):<\/strong> Statik dosyalar\u0131, yedeklemeleri ve di\u011fer b\u00fcy\u00fck verileri depolamak i\u00e7in S3 uyumlu bir nesne depolama hizmetidir.<br \/>\n*   <strong>Managed Databases:<\/strong> PostgreSQL, MySQL, Redis ve MongoDB i\u00e7in y\u00f6netilen veritaban\u0131 hizmetleri sunar.<\/p>\n<p>Bu makalede, Droplet&#8217;e SSH \u00fczerinden da\u011f\u0131t\u0131m ve App Platform&#8217;a entegre da\u011f\u0131t\u0131m olmak \u00fczere iki ana da\u011f\u0131t\u0131m stratejisine odaklanaca\u011f\u0131z.<\/p>\n<h3>Da\u011f\u0131t\u0131m Senaryolar\u0131 ve \u00d6n Gereksinimler<\/h3>\n<p>GitHub Actions ile DigitalOcean&#8217;a da\u011f\u0131t\u0131m yaparken, uygulaman\u0131z\u0131n t\u00fcr\u00fcne ve kontrol tercihlerinize g\u00f6re farkl\u0131 senaryolar izleyebilirsiniz.<\/p>\n<h4>Senaryo 1: Droplet&#8217;e SSH \u00dczerinden Da\u011f\u0131t\u0131m (Geleneksel)<\/h4>\n<p>Bu senaryo, uygulaman\u0131z\u0131 bir DigitalOcean Droplet&#8217;e do\u011frudan SSH ba\u011flant\u0131s\u0131 kurarak da\u011f\u0131tmay\u0131 i\u00e7erir. Tam sunucu kontrol\u00fcne sahip olmak isteyen veya \u00f6zel bir yaz\u0131l\u0131m y\u0131\u011f\u0131n\u0131 gerektiren uygulamalar i\u00e7in idealdir.<\/p>\n<h5>\u00d6n Gereksinimler:<\/h5>\n<p>*   <strong>DigitalOcean Hesab\u0131 ve Droplet:<\/strong> \u00c7al\u0131\u015f\u0131r durumda bir DigitalOcean hesab\u0131 ve da\u011f\u0131t\u0131m yapaca\u011f\u0131n\u0131z bir Droplet&#8217;in mevcut olmas\u0131.<br \/>\n*   <strong>Droplet&#8217;e SSH Eri\u015fimi:<\/strong> Droplet&#8217;e SSH \u00fczerinden manuel olarak ba\u011flanabildi\u011finizden emin olun.<br \/>\n*   <strong>GitHub Deposu:<\/strong> Da\u011f\u0131t\u0131lacak uygulaman\u0131n kodunu i\u00e7eren bir GitHub deposu.<br \/>\n*   <strong>Uygulama:<\/strong> Da\u011f\u0131t\u0131lacak bir web uygulamas\u0131 (\u00f6rne\u011fin, Node.js, Python Flask\/Django, PHP Laravel\/Symfony).<br \/>\n*   <strong>SSH Anahtar \u00c7ifti:<\/strong> GitHub Actions&#8217;\u0131n Droplet&#8217;e g\u00fcvenli bir \u015fekilde ba\u011flanabilmesi i\u00e7in \u00f6zel bir SSH anahtar \u00e7ifti (public\/private key) olu\u015fturulmas\u0131 gereklidir.<br \/>\n*   <strong>GitHub Secrets:<\/strong> SSH \u00f6zel anahtar\u0131, Droplet&#8217;in IP adresi ve kullan\u0131c\u0131 ad\u0131 gibi hassas bilgilerin GitHub Secrets&#8217;ta saklanmas\u0131.<\/p>\n<h4>Senaryo 2: DigitalOcean App Platform&#8217;a Da\u011f\u0131t\u0131m<\/h4>\n<p>Bu senaryo, uygulaman\u0131z\u0131 DigitalOcean&#8217;\u0131n y\u00f6netilen App Platform hizmetine da\u011f\u0131tmay\u0131 kapsar. Altyap\u0131 y\u00f6netimiyle u\u011fra\u015fmak istemeyen ve h\u0131zl\u0131 da\u011f\u0131t\u0131m d\u00f6ng\u00fclerine ihtiya\u00e7 duyan projeler i\u00e7in daha uygundur. App Platform, genellikle GitHub deposundaki kod de\u011fi\u015fikliklerini otomatik olarak alg\u0131lar ve da\u011f\u0131t\u0131r, ancak GitHub Actions ile bu s\u00fcreci daha da \u00f6zelle\u015ftirebilirsiniz.<\/p>\n<h5>\u00d6n Gereksinimler:<\/h5>\n<p>*   <strong>DigitalOcean Hesab\u0131:<\/strong> \u00c7al\u0131\u015f\u0131r durumda bir DigitalOcean hesab\u0131.<br \/>\n*   <strong>GitHub Deposu:<\/strong> Da\u011f\u0131t\u0131lacak uygulaman\u0131n kodunu i\u00e7eren bir GitHub deposu.<br \/>\n*   <strong>Uygulama:<\/strong> App Platform&#8217;un destekledi\u011fi dillerden veya framework&#8217;lerden biriyle yaz\u0131lm\u0131\u015f bir uygulama.<br \/>\n*   <strong>DigitalOcean API Token:<\/strong> GitHub Actions&#8217;\u0131n DigitalOcean API&#8217;si ile etkile\u015fim kurabilmesi i\u00e7in bir API token&#8217;\u0131 olu\u015fturulmas\u0131 gereklidir.<br \/>\n*   <strong>GitHub Secrets:<\/strong> DigitalOcean API token&#8217;\u0131n\u0131n GitHub Secrets&#8217;ta saklanmas\u0131.<\/p>\n<h3>GitHub Actions ile DigitalOcean Droplet&#8217;e Da\u011f\u0131t\u0131m Ad\u0131m Ad\u0131m Rehber<\/h3>\n<p>Bu b\u00f6l\u00fcmde, bir web uygulamas\u0131n\u0131 GitHub Actions kullanarak bir DigitalOcean Droplet&#8217;ine SSH \u00fczerinden nas\u0131l da\u011f\u0131taca\u011f\u0131m\u0131z\u0131 ad\u0131m ad\u0131m inceleyece\u011fiz.<\/p>\n<h4>Ad\u0131m 1: Droplet Haz\u0131rl\u0131\u011f\u0131<\/h4>\n<p>1.  <strong>Droplet Olu\u015fturma:<\/strong> DigitalOcean kontrol panelinden yeni bir Droplet olu\u015fturun. Ubuntu 22.04 LTS gibi g\u00fcncel bir Linux da\u011f\u0131t\u0131m\u0131 se\u00e7mek iyi bir ba\u015flang\u0131\u00e7t\u0131r. SSH anahtar\u0131n\u0131z\u0131 Droplet&#8217;e eklemeyi unutmay\u0131n.<br \/>\n2.  <strong>Gerekli Yaz\u0131l\u0131mlar\u0131 Y\u00fckleme:<\/strong> Droplet&#8217;e SSH ile ba\u011flan\u0131n ve uygulaman\u0131z\u0131n \u00e7al\u0131\u015fmas\u0131 i\u00e7in gerekli yaz\u0131l\u0131mlar\u0131 y\u00fckleyin. \u00d6rne\u011fin, bir Node.js uygulamas\u0131 i\u00e7in:<\/p>\n<pre><code class=\"language-bash\">sudo apt update\n    sudo apt install -y curl git\n    curl -fsSL https:\/\/deb.nodesource.com\/setup_20.x | sudo -E bash -\n    sudo apt install -y nodejs\n    sudo npm install -g pm2 # Uygulamay\u0131 arka planda \u00e7al\u0131\u015ft\u0131rmak i\u00e7in\n    # Nginx gibi bir web sunucusu da gerekebilir\n    sudo apt install -y nginx\n    sudo systemctl enable nginx\n    sudo systemctl start nginx<\/code><\/pre>\n<p>3.  <strong>Uygulama Dizini Olu\u015fturma:<\/strong> Uygulaman\u0131z i\u00e7in bir dizin olu\u015fturun ve gerekli izinleri ayarlay\u0131n. \u00d6rne\u011fin:<\/p>\n<pre><code class=\"language-bash\">sudo mkdir -p \/var\/www\/your-app-directory\n    sudo chown -R your_user:your_user \/var\/www\/your-app-directory # your_user yerine kendi kullan\u0131c\u0131 ad\u0131n\u0131z\u0131 yaz\u0131n<\/code><\/pre>\n<p>4.  <strong>G\u00fcvenlik Duvar\u0131 (Firewall):<\/strong> Gerekli portlar\u0131n (HTTP i\u00e7in 80, HTTPS i\u00e7in 443, SSH i\u00e7in 22) a\u00e7\u0131k oldu\u011fundan emin olun. <code>ufw<\/code> kullan\u0131yorsan\u0131z:<\/p>\n<pre><code class=\"language-bash\">sudo ufw allow OpenSSH\n    sudo ufw allow 'Nginx HTTP' # E\u011fer Nginx kullan\u0131yorsan\u0131z\n    sudo ufw enable<\/code><\/pre>\n<h4>Ad\u0131m 2: SSH Anahtar\u0131 Olu\u015fturma ve Yap\u0131land\u0131rma<\/h4>\n<p>GitHub Actions&#8217;\u0131n Droplet&#8217;inize g\u00fcvenli bir \u015fekilde ba\u011flanabilmesi i\u00e7in \u00f6zel bir SSH anahtar \u00e7ifti olu\u015fturaca\u011f\u0131z. Bu anahtar sadece GitHub Actions taraf\u0131ndan kullan\u0131lacak ve Droplet&#8217;inize eri\u015fim sa\u011flayacak.<\/p>\n<p>1.  <strong>Anahtar \u00c7ifti Olu\u015fturma:<\/strong> Yerel makinenizde (veya GitHub Actions&#8217;\u0131n \u00e7al\u0131\u015faca\u011f\u0131 herhangi bir g\u00fcvenli ortamda) a\u015fa\u011f\u0131daki komutu \u00e7al\u0131\u015ft\u0131r\u0131n. Parola sormazsa Enter&#8217;a bas\u0131n (parola korumal\u0131 anahtarlar GitHub Actions ile daha karma\u015f\u0131k olabilir).<\/p>\n<pre><code class=\"language-bash\">ssh-keygen -t rsa -b 4096 -C \"github-actions-deploy-key\" -f id_rsa_github_actions<\/code><\/pre>\n<p>    Bu komut, <code>id_rsa_github_actions<\/code> (\u00f6zel anahtar) ve <code>id_rsa_github_actions.pub<\/code> (genel anahtar) ad\u0131nda iki dosya olu\u015fturacakt\u0131r.<br \/>\n2.  <strong>Genel Anahtar\u0131 Droplet&#8217;e Ekleme:<\/strong> <code>id_rsa_github_actions.pub<\/code> dosyas\u0131n\u0131n i\u00e7eri\u011fini kopyalay\u0131n. Droplet&#8217;inize ba\u011flan\u0131n ve bu i\u00e7eri\u011fi <code>\/home\/your_user\/.ssh\/authorized_keys<\/code> dosyas\u0131na ekleyin. E\u011fer dosya veya dizin yoksa olu\u015fturun:<\/p>\n<pre><code class=\"language-bash\">mkdir -p ~\/.ssh\n    chmod 700 ~\/.ssh\n    echo \"ssh-rsa AAAAB3NzaC...\" >> ~\/.ssh\/authorized_keys # Kopyalad\u0131\u011f\u0131n\u0131z genel anahtar\u0131 buraya yap\u0131\u015ft\u0131r\u0131n\n    chmod 600 ~\/.ssh\/authorized_keys<\/code><\/pre>\n<p>3.  <strong>\u00d6zel Anahtar\u0131 Kopyalama:<\/strong> <code>id_rsa_github_actions<\/code> dosyas\u0131n\u0131n i\u00e7eri\u011fini kopyalay\u0131n. Bu \u00f6zel anahtar, GitHub Secrets&#8217;ta kullan\u0131lacakt\u0131r.<\/p>\n<h4>Ad\u0131m 3: GitHub Repository Secrets Yap\u0131land\u0131rmas\u0131<\/h4>\n<p>GitHub deponuzda, hassas bilgileri g\u00fcvenli bir \u015fekilde saklamak i\u00e7in &#8220;Secrets&#8221; kullan\u0131n.<\/p>\n<p>1.  GitHub deponuza gidin.<br \/>\n2.  <code>Settings<\/code> (Ayarlar) sekmesine t\u0131klay\u0131n.<br \/>\n3.  Sol men\u00fcden <code>Secrets and variables<\/code> (S\u0131rlar ve de\u011fi\u015fkenler) alt\u0131nda <code>Actions<\/code> se\u00e7ene\u011fini t\u0131klay\u0131n.<br \/>\n4.  <code>New repository secret<\/code> (Yeni depo s\u0131rr\u0131) butonuna t\u0131klayarak a\u015fa\u011f\u0131daki s\u0131rlar\u0131 ekleyin:<br \/>\n    *   <strong><code>SSH_PRIVATE_KEY<\/code><\/strong>: <code>id_rsa_github_actions<\/code> dosyas\u0131n\u0131n t\u00fcm i\u00e7eri\u011fini yap\u0131\u015ft\u0131r\u0131n (ba\u015f\u0131nda <code>-----BEGIN OPENSSH PRIVATE KEY-----<\/code> ile ba\u015flay\u0131p sonunda <code>-----END OPENSSH PRIVATE KEY-----<\/code> ile biten k\u0131s\u0131m).<br \/>\n    *   <strong><code>SSH_HOST<\/code><\/strong>: Droplet&#8217;inizin genel IP adresi.<br \/>\n    *   <strong><code>SSH_USER<\/code><\/strong>: Droplet&#8217;inizdeki kullan\u0131c\u0131 ad\u0131 (genellikle <code>root<\/code> veya \u00f6zel olu\u015fturdu\u011funuz kullan\u0131c\u0131).<\/p>\n<h4>Ad\u0131m 4: GitHub Actions Workflow Dosyas\u0131 Olu\u015fturma (<code>.github\/workflows\/deploy.yml<\/code>)<\/h4>\n<p>Deponuzun k\u00f6k dizininde <code>.github\/workflows\/<\/code> ad\u0131nda bir dizin olu\u015fturun ve i\u00e7ine <code>deploy.yml<\/code> ad\u0131nda bir dosya ekleyin. Bu dosya, da\u011f\u0131t\u0131m i\u015f ak\u0131\u015f\u0131n\u0131z\u0131 tan\u0131mlayacakt\u0131r.<\/p>\n<pre><code class=\"language-yaml\">name: Deploy to DigitalOcean Droplet\n\non:\n  push:\n    branches:\n      - main # main branch'ine yap\u0131lan her push'ta tetiklenir\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest # \u0130\u015fin \u00e7al\u0131\u015faca\u011f\u0131 runner tipi\n\n    steps:\n    - name: Checkout code\n      uses: actions\/checkout@v4 # Depo kodunu runner'a kopyalar\n\n    - name: Set up SSH agent\n      uses: webfactory\/ssh-agent@v0.9.0 # SSH \u00f6zel anahtar\u0131n\u0131 SSH agent'a ekler\n      with:\n        ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} # GitHub Secret'tan \u00f6zel anahtar\u0131 al\u0131r\n\n    - name: Add SSH host key\n      run: |\n        mkdir -p ~\/.ssh # .ssh dizinini olu\u015fturur (varsa atlar)\n        ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~\/.ssh\/known_hosts # Droplet'in host key'ini known_hosts'a ekler\n        chmod 600 ~\/.ssh\/known_hosts # known_hosts dosyas\u0131n\u0131n izinlerini ayarlar\n      # Bu ad\u0131m, ilk kez ba\u011flan\u0131rken 'Are you sure you want to continue connecting (yes\/no)?' sorusunu atlamak i\u00e7in gereklidir.\n\n    - name: Deploy to Droplet\n      run: |\n        # SSH ile Droplet'e ba\u011flan ve komutlar\u0131 \u00e7al\u0131\u015ft\u0131r\n        ssh -o StrictHostKeyChecking=no ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} \"\n          cd \/var\/www\/your-app-directory && # Uygulama dizinine git\n          git pull origin main && # En son kodu \u00e7ek\n          npm install && # Ba\u011f\u0131ml\u0131l\u0131klar\u0131 y\u00fckle (\u00f6rnek: Node.js i\u00e7in)\n          npm run build && # Uygulamay\u0131 derle (e\u011fer build ad\u0131m\u0131 varsa)\n          pm2 restart your-app-name # Uygulamay\u0131 PM2 ile yeniden ba\u015flat (veya systemctl restart your-service)\n        \"\n      env:\n        # E\u011fer uygulaman\u0131z\u0131n ortam de\u011fi\u015fkenlerine ihtiyac\u0131 varsa, burada tan\u0131mlayabilirsiniz.\n        # \u00d6rne\u011fin: NODE_ENV: production\n        # Ancak hassas bilgiler i\u00e7in DigitalOcean Droplet'inde .env dosyas\u0131 kullanmak daha iyidir.<\/code><\/pre>\n<p>Bu YAML dosyas\u0131, <code>main<\/code> branch&#8217;ine her <code>push<\/code> yap\u0131ld\u0131\u011f\u0131nda \u00e7al\u0131\u015facak bir i\u015f ak\u0131\u015f\u0131 tan\u0131mlar.<br \/>\n*   <code>Checkout code<\/code>: Depodaki kodu GitHub Actions runner&#8217;\u0131na \u00e7eker.<br \/>\n*   <code>Set up SSH agent<\/code>: SSH \u00f6zel anahtar\u0131n\u0131z\u0131 runner&#8217;\u0131n SSH agent&#8217;\u0131na ekler, b\u00f6ylece SSH komutlar\u0131 anahtar\u0131 kullanabilir.<br \/>\n*   <code>Add SSH host key<\/code>: Droplet&#8217;in SSH parmak izini <code>known_hosts<\/code> dosyas\u0131na ekleyerek g\u00fcvenli ba\u011flant\u0131 sa\u011flar ve manuel onay\u0131 atlar.<br \/>\n*   <code>Deploy to Droplet<\/code>: SSH \u00fczerinden Droplet&#8217;e ba\u011flan\u0131r ve uygulaman\u0131z\u0131n g\u00fcncellenmesi, ba\u011f\u0131ml\u0131l\u0131klar\u0131n y\u00fcklenmesi, derlenmesi ve yeniden ba\u015flat\u0131lmas\u0131 gibi da\u011f\u0131t\u0131m ad\u0131mlar\u0131n\u0131 tetikler. <code>your-app-directory<\/code> ve <code>your-app-name<\/code> k\u0131s\u0131mlar\u0131n\u0131 kendi uygulaman\u0131z\u0131n ad\u0131yla de\u011fi\u015ftirmeniz gerekmektedir.<\/p>\n<p>Kodunuzu GitHub&#8217;a <code>main<\/code> branch&#8217;ine push etti\u011finizde, GitHub Actions otomatik olarak tetiklenecek ve uygulaman\u0131z\u0131 Droplet&#8217;inize da\u011f\u0131tacakt\u0131r.<\/p>\n<h3>GitHub Actions ile DigitalOcean App Platform&#8217;a Da\u011f\u0131t\u0131m Ad\u0131m Ad\u0131m Rehber<\/h3>\n<p>DigitalOcean App Platform, uygulamalar\u0131 daha az altyap\u0131 y\u00f6netimiyle da\u011f\u0131tmak i\u00e7in harika bir se\u00e7enektir. GitHub Actions ile bu s\u00fcreci daha da otomatikle\u015ftirebilirsiniz.<\/p>\n<h4>Ad\u0131m 1: DigitalOcean App Platform Projesi Olu\u015fturma (Manuel)<\/h4>\n<p>1.  <strong>Uygulama Olu\u015fturma:<\/strong> DigitalOcean kontrol panelinize gidin ve sol men\u00fcden <code>Apps<\/code> se\u00e7ene\u011fini t\u0131klay\u0131n. <code>Create App<\/code> (Uygulama Olu\u015ftur) butonuna t\u0131klay\u0131n.<br \/>\n2.  <strong>Kaynak Ba\u011flama:<\/strong> GitHub deponuzu se\u00e7in ve da\u011f\u0131tmak istedi\u011finiz branch&#8217;i (\u00f6rne\u011fin, <code>main<\/code>) belirtin. DigitalOcean, deponuzu analiz edecek ve uygulaman\u0131z i\u00e7in uygun bir yap\u0131land\u0131rma \u00f6nerecektir.<br \/>\n3.  <strong>Yap\u0131land\u0131rma:<\/strong> Uygulaman\u0131z\u0131n bile\u015fenlerini (web hizmetleri, veritabanlar\u0131 vb.) yap\u0131land\u0131r\u0131n. Ortam de\u011fi\u015fkenlerini, build komutlar\u0131n\u0131 ve run komutlar\u0131n\u0131 ayarlay\u0131n.<br \/>\n4.  <strong>\u0130lk Da\u011f\u0131t\u0131m:<\/strong> \u0130lk da\u011f\u0131t\u0131m\u0131 manuel olarak tetikleyin ve uygulaman\u0131z\u0131n ba\u015far\u0131l\u0131 bir \u015fekilde \u00e7al\u0131\u015ft\u0131\u011f\u0131ndan emin olun. Bu ad\u0131m, App Platform&#8217;un GitHub deponuzla do\u011fru \u015fekilde entegre oldu\u011fundan emin olman\u0131z\u0131 sa\u011flar.<\/p>\n<h4>Ad\u0131m 2: DigitalOcean API Token Olu\u015fturma<\/h4>\n<p>GitHub Actions&#8217;\u0131n DigitalOcean App Platform ile etkile\u015fim kurabilmesi i\u00e7in bir API token&#8217;\u0131na ihtiyac\u0131 vard\u0131r.<\/p>\n<p>1.  DigitalOcean kontrol panelinize gidin.<br \/>\n2.  Sol men\u00fcden <code>API<\/code> se\u00e7ene\u011fini t\u0131klay\u0131n.<br \/>\n3.  <code>Generate New Token<\/code> (Yeni Token Olu\u015ftur) butonuna t\u0131klay\u0131n.<br \/>\n4.  Token&#8217;a a\u00e7\u0131klay\u0131c\u0131 bir isim verin (\u00f6rne\u011fin, <code>github-actions-app-deploy<\/code>).<br \/>\n5.  <code>Write<\/code> (Yazma) eri\u015fimi verdi\u011finizden emin olun, bu GitHub Actions&#8217;\u0131n da\u011f\u0131t\u0131m tetikleyebilmesi i\u00e7in gereklidir.<br \/>\n6.  Olu\u015fturulan token&#8217;\u0131 kopyalay\u0131n. Bu token sadece bir kez g\u00f6sterilecektir, bu y\u00fczden g\u00fcvenli bir yere kaydedin.<\/p>\n<h4>Ad\u0131m 3: GitHub Repository Secrets Yap\u0131land\u0131rmas\u0131<\/h4>\n<p>GitHub deponuzda, DigitalOcean API token&#8217;\u0131n\u0131 g\u00fcvenli bir \u015fekilde saklamak i\u00e7in &#8220;Secrets&#8221; kullan\u0131n.<\/p>\n<p>1.  GitHub deponuza gidin.<br \/>\n2.  <code>Settings<\/code> (Ayarlar) sekmesine t\u0131klay\u0131n.<br \/>\n3.  Sol men\u00fcden <code>Secrets and variables<\/code> (S\u0131rlar ve de\u011fi\u015fkenler) alt\u0131nda <code>Actions<\/code> se\u00e7ene\u011fini t\u0131klay\u0131n.<br \/>\n4.  <code>New repository secret<\/code> (Yeni depo s\u0131rr\u0131) butonuna t\u0131klayarak a\u015fa\u011f\u0131daki s\u0131rr\u0131 ekleyin:<br \/>\n    *   <strong><code>DIGITALOCEAN_ACCESS_TOKEN<\/code><\/strong>: Olu\u015fturdu\u011funuz DigitalOcean API token&#8217;\u0131n\u0131 yap\u0131\u015ft\u0131r\u0131n.<br \/>\n    *   <strong><code>DIGITALOCEAN_APP_ID<\/code> (iste\u011fe ba\u011fl\u0131 ama \u00f6nerilir)<\/strong>: App Platform uygulaman\u0131z\u0131n benzersiz ID&#8217;si. Bu ID&#8217;yi, DigitalOcean kontrol panelinde uygulaman\u0131z\u0131n URL&#8217;sinden (\u00f6rne\u011fin, <code>https:\/\/cloud.digitalocean.com\/apps\/YOUR_APP_ID<\/code>) veya <code>doctl apps list<\/code> komutu ile alabilirsiniz.<\/p>\n<h4>Ad\u0131m 4: GitHub Actions Workflow Dosyas\u0131 Olu\u015fturma (<code>.github\/workflows\/deploy-app-platform.yml<\/code>)<\/h4>\n<p>Deponuzun k\u00f6k dizininde <code>.github\/workflows\/<\/code> ad\u0131nda bir dizin olu\u015fturun ve i\u00e7ine <code>deploy-app-platform.yml<\/code> ad\u0131nda bir dosya ekleyin.<\/p>\n<pre><code class=\"language-yaml\">name: Deploy to DigitalOcean App Platform\n\non:\n  push:\n    branches:\n      - main # main branch'ine yap\u0131lan her push'ta tetiklenir\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest # \u0130\u015fin \u00e7al\u0131\u015faca\u011f\u0131 runner tipi\n\n    steps:\n    - name: Checkout code\n      uses: actions\/checkout@v4 # Depo kodunu runner'a kopyalar\n\n    - name: Install doctl\n      uses: digitalocean\/action-doctl@v2 # DigitalOcean CLI (doctl) kurar ve API token'\u0131 ile kimlik do\u011frulamas\u0131 yapar\n      with:\n        token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} # GitHub Secret'tan API token'\u0131 al\u0131r\n\n    - name: Trigger DigitalOcean App Platform Deployment\n      run: doctl apps create-deployment ${{ secrets.DIGITALOCEAN_APP_ID }}\n      # E\u011fer DIGITALOCEAN_APP_ID s\u0131rr\u0131n\u0131 kullanm\u0131yorsan\u0131z ve depo zaten App Platform'a ba\u011fl\u0131ysa,\n      # a\u015fa\u011f\u0131daki gibi uygulaman\u0131n ad\u0131yla ID'yi dinamik olarak bulabilirsiniz:\n      # run: doctl apps create-deployment $(doctl apps list --format ID,Spec.Name --no-header | grep 'your-app-name' | awk '{print $1}')\n      # \"your-app-name\" k\u0131sm\u0131n\u0131 uygulaman\u0131z\u0131n ad\u0131yla de\u011fi\u015ftirin.<\/code><\/pre>\n<p>Bu YAML dosyas\u0131, <code>main<\/code> branch&#8217;ine her <code>push<\/code> yap\u0131ld\u0131\u011f\u0131nda \u00e7al\u0131\u015facak bir i\u015f ak\u0131\u015f\u0131 tan\u0131mlar.<br \/>\n*   <code>Checkout code<\/code>: Depodaki kodu GitHub Actions runner&#8217;\u0131na \u00e7eker.<br \/>\n*   <code>Install doctl<\/code>: DigitalOcean taraf\u0131ndan sa\u011flanan <code>action-doctl<\/code> eylemini kullanarak <code>doctl<\/code> CLI arac\u0131n\u0131 kurar ve sa\u011flanan <code>DIGITALOCEAN_ACCESS_TOKEN<\/code> ile kimlik do\u011frulamas\u0131 yapar.<br \/>\n*   <code>Trigger DigitalOcean App Platform Deployment<\/code>: <code>doctl apps create-deployment<\/code> komutunu kullanarak App Platform&#8217;da yeni bir da\u011f\u0131t\u0131m tetikler. Bu komut, App Platform&#8217;a GitHub deponuzdaki en son kodu \u00e7ekmesini ve yeni bir da\u011f\u0131t\u0131m ba\u015flatmas\u0131n\u0131 s\u00f6yler. E\u011fer <code>DIGITALOCEAN_APP_ID<\/code> kullan\u0131yorsan\u0131z, do\u011frudan uygulama ID&#8217;sini belirtirsiniz. Aksi takdirde, uygulaman\u0131n ad\u0131n\u0131 kullanarak ID&#8217;yi dinamik olarak bulman\u0131z gerekebilir.<\/p>\n<p>Bu yap\u0131land\u0131rma ile, kodunuzu <code>main<\/code> branch&#8217;ine push etti\u011finizde, GitHub Actions otomatik olarak DigitalOcean App Platform&#8217;da yeni bir da\u011f\u0131t\u0131m ba\u015flatacakt\u0131r.<\/p>\n<h3>Geli\u015fmi\u015f Da\u011f\u0131t\u0131m Teknikleri ve En \u0130yi Uygulamalar<\/h3>\n<p>CI\/CD s\u00fcre\u00e7lerinizi daha sa\u011flam, g\u00fcvenli ve verimli hale getirmek i\u00e7in baz\u0131 geli\u015fmi\u015f teknikler ve en iyi uygulamalar mevcuttur.<\/p>\n<h4>Ortam De\u011fi\u015fkenleri ve S\u0131rlar Y\u00f6netimi<\/h4>\n<p>Uygulamalar genellikle veritaban\u0131 ba\u011flant\u0131 dizeleri, API anahtarlar\u0131 gibi hassas bilgilere ihtiya\u00e7 duyar.<br \/>\n*   <strong>GitHub Secrets:<\/strong> Da\u011f\u0131t\u0131m s\u00fcrecinde kullan\u0131lan hassas bilgiler (SSH anahtarlar\u0131, API token&#8217;lar\u0131) i\u00e7in GitHub Secrets&#8217;\u0131 kullan\u0131n.<br \/>\n*   <strong>Uygulama Ortam De\u011fi\u015fkenleri:<\/strong> Uygulaman\u0131z\u0131n kendisi i\u00e7in gereken ortam de\u011fi\u015fkenlerini do\u011frudan Droplet \u00fczerinde (\u00f6rne\u011fin, <code>.env<\/code> dosyalar\u0131 veya sistem ortam de\u011fi\u015fkenleri olarak) veya DigitalOcean App Platform&#8217;un kendi ortam de\u011fi\u015fkeni y\u00f6netim aray\u00fcz\u00fc \u00fczerinden ayarlay\u0131n. Bu, s\u0131rlar\u0131n kod deposunda veya GitHub Actions loglar\u0131nda g\u00f6r\u00fcnmesini engeller.<\/p>\n<h4>Testler ve Kalite Kontrolleri<\/h4>\n<p>Da\u011f\u0131t\u0131mdan \u00f6nce otomatik testlerin \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131, hatal\u0131 kodun \u00fcretime gitmesini engeller.<br \/>\n*   <strong>Unit\/Integration Tests:<\/strong> Kodunuzu test etmek i\u00e7in i\u015f ak\u0131\u015f\u0131n\u0131zda <code>npm test<\/code>, <code>pytest<\/code>, <code>php artisan test<\/code> gibi komutlar\u0131 \u00e7al\u0131\u015ft\u0131r\u0131n.<br \/>\n*   <strong>Linting\/Static Analysis:<\/strong> Kod stilini ve potansiyel hatalar\u0131 kontrol etmek i\u00e7in linting ara\u00e7lar\u0131n\u0131 kullan\u0131n.<br \/>\n*   <strong>G\u00fcvenlik Tarama:<\/strong> Ba\u011f\u0131ml\u0131l\u0131k g\u00fcvenlik a\u00e7\u0131klar\u0131n\u0131 taramak i\u00e7in ara\u00e7lar entegre edin.<br \/>\nDa\u011f\u0131t\u0131m i\u015fi, ancak t\u00fcm testler ba\u015far\u0131l\u0131 olursa devam etmelidir.<\/p>\n<pre><code class=\"language-yaml\">jobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions\/checkout@v4\n    - name: Set up Node.js\n      uses: actions\/setup-node@v4\n      with:\n        node-version: '20'\n    - name: Install dependencies\n      run: npm install\n    - name: Run tests\n      run: npm test\n\n  deploy:\n    needs: test # Da\u011f\u0131t\u0131m i\u015fi, test i\u015fi ba\u015far\u0131l\u0131 olursa \u00e7al\u0131\u015f\u0131r\n    runs-on: ubuntu-latest\n    # ... da\u011f\u0131t\u0131m ad\u0131mlar\u0131 ...<\/code><\/pre>\n<h4>Rollback Stratejileri<\/h4>\n<p>Her da\u011f\u0131t\u0131m ba\u015far\u0131l\u0131 olmayabilir. H\u0131zl\u0131 ve g\u00fcvenli bir geri alma (rollback) mekanizmas\u0131 kritik \u00f6neme sahiptir.<br \/>\n*   <strong>Droplet:<\/strong> <code>git<\/code> commit ge\u00e7mi\u015fini kullanarak \u00f6nceki kararl\u0131 bir s\u00fcr\u00fcme geri d\u00f6nmek veya \u00f6nceki bir uygulama imaj\u0131n\u0131 geri y\u00fcklemek. PM2 gibi s\u00fcre\u00e7 y\u00f6neticileri, uygulamalar\u0131n farkl\u0131 s\u00fcr\u00fcmlerini y\u00f6netme yetene\u011fine sahip olabilir.<br \/>\n*   <strong>App Platform:<\/strong> DigitalOcean App Platform, \u00f6nceki da\u011f\u0131t\u0131mlar\u0131 otomatik olarak saklar ve kontrol panelinden kolayca geri al\u0131m yapman\u0131z\u0131 sa\u011flar.<\/p>\n<h4>Bildirimler<\/h4>\n<p>Da\u011f\u0131t\u0131m durumunu (ba\u015far\u0131l\u0131\/ba\u015far\u0131s\u0131z) ilgili ekiplere bildirmek \u00f6nemlidir.<br \/>\n*   <strong>Slack\/Email Bildirimleri:<\/strong> GitHub Actions&#8217;da da\u011f\u0131t\u0131m durumuna g\u00f6re Slack veya e-posta bildirimleri g\u00f6ndermek i\u00e7in \u00fc\u00e7\u00fcnc\u00fc taraf eylemleri kullanabilirsiniz (\u00f6rne\u011fin, <code>rtCamp\/action-slack-notify<\/code>).<\/p>\n<h4>\u00c7oklu Ortamlar (Environments)<\/h4>\n<p>Geli\u015ftirme, haz\u0131rl\u0131k (staging) ve \u00fcretim (production) gibi farkl\u0131 ortamlar i\u00e7in ayr\u0131 da\u011f\u0131t\u0131m i\u015f ak\u0131\u015flar\u0131 veya ko\u015fullar tan\u0131mlamak yayg\u0131n bir pratiktir.<br \/>\n*   <strong>Branch Bazl\u0131 Da\u011f\u0131t\u0131m:<\/strong> <code>main<\/code> branch&#8217;ine push yap\u0131ld\u0131\u011f\u0131nda \u00fcretime, <code>develop<\/code> branch&#8217;ine push yap\u0131ld\u0131\u011f\u0131nda haz\u0131rl\u0131k ortam\u0131na da\u011f\u0131t\u0131m yapabilirsiniz.<br \/>\n*   <strong>GitHub Environments:<\/strong> GitHub, ortamlar\u0131 y\u00f6netmek ve her ortam i\u00e7in \u00f6zel kurallar (manuel onaylar, korumal\u0131 s\u0131rlar) belirlemek i\u00e7in &#8220;Environments&#8221; \u00f6zelli\u011fini sunar.<\/p>\n<pre><code class=\"language-yaml\">on:\n  push:\n    branches:\n      - main\n      - develop\n\njobs:\n  deploy-staging:\n    if: github.ref == 'refs\/heads\/develop'\n    environment: staging # GitHub Environment kullan\u0131r\n    runs-on: ubuntu-latest\n    steps:\n      # ... haz\u0131rl\u0131k ortam\u0131na da\u011f\u0131t\u0131m ad\u0131mlar\u0131 ...\n\n  deploy-production:\n    if: github.ref == 'refs\/heads\/main'\n    environment: production # GitHub Environment kullan\u0131r\n    runs-on: ubuntu-latest\n    # Bu ortama da\u011f\u0131t\u0131m i\u00e7in manuel onay gerektirebilir\n    steps:\n      # ... \u00fcretim ortam\u0131na da\u011f\u0131t\u0131m ad\u0131mlar\u0131 ...<\/code><\/pre>\n<h4>G\u00fcvenlik \u0130pu\u00e7lar\u0131<\/h4>\n<p>*   <strong>Least Privilege (En Az Yetki Prensibi):<\/strong> SSH anahtarlar\u0131 ve API token&#8217;lar\u0131na yaln\u0131zca ihtiya\u00e7 duyduklar\u0131 minimum izinleri verin. \u00d6rne\u011fin, Droplet da\u011f\u0131t\u0131m\u0131 i\u00e7in sadece da\u011f\u0131t\u0131m kullan\u0131c\u0131s\u0131n\u0131n home dizinine eri\u015fim izni olan bir SSH anahtar\u0131 kullan\u0131n.<br \/>\n*   <strong>Anahtar Rotasyonu:<\/strong> D\u00fczenli aral\u0131klarla SSH anahtarlar\u0131n\u0131z\u0131 ve API token&#8217;lar\u0131n\u0131z\u0131 de\u011fi\u015ftirin.<br \/>\n*   <strong>GitHub Secrets:<\/strong> Hassas bilgileri asla kod deposunda saklamay\u0131n, her zaman GitHub Secrets&#8217;\u0131 kullan\u0131n.<\/p>\n<h4>Downtime&#8217;\u0131 Azaltma (Zero-Downtime Deployments)<\/h4>\n<p>\u00d6zellikle \u00fcretim ortamlar\u0131nda, da\u011f\u0131t\u0131m s\u0131ras\u0131nda hizmet kesintisini en aza indirmek \u00f6nemlidir.<br \/>\n*   <strong>Blue\/Green Deployments:<\/strong> Yeni s\u00fcr\u00fcm\u00fc ayr\u0131 bir ortamda (green) da\u011f\u0131t\u0131n, test edin ve ard\u0131ndan trafi\u011fi bu yeni ortama y\u00f6nlendirin. Eski ortam (blue) bir geri alma stratejisi olarak haz\u0131r tutulur.<br \/>\n*   <strong>Rolling Updates:<\/strong> Yeni s\u00fcr\u00fcmleri ad\u0131m ad\u0131m da\u011f\u0131tarak, her seferinde sunucular\u0131n sadece bir k\u0131sm\u0131n\u0131 g\u00fcncelleyin. Y\u00fck dengeleyicilerle birlikte kullan\u0131ld\u0131\u011f\u0131nda, trafik her zaman g\u00fcncel sunuculara y\u00f6nlendirilir.<\/p>\n<h3>S\u0131k Kar\u015f\u0131la\u015f\u0131lan Sorunlar ve \u00c7\u00f6z\u00fcmleri<\/h3>\n<p>GitHub Actions ile DigitalOcean&#8217;a da\u011f\u0131t\u0131m yaparken kar\u015f\u0131la\u015fabilece\u011finiz baz\u0131 yayg\u0131n sorunlar ve bunlar\u0131n \u00e7\u00f6z\u00fcmleri:<\/p>\n<p>1.  <strong>SSH Ba\u011flant\u0131 Sorunlar\u0131:<\/strong><br \/>\n    *   <strong>Hata:<\/strong> <code>Permission denied (publickey).<\/code><br \/>\n        *   <strong>\u00c7\u00f6z\u00fcm:<\/strong> SSH \u00f6zel anahtar\u0131n\u0131z\u0131n do\u011fru \u015fekilde GitHub Secret&#8217;a kopyaland\u0131\u011f\u0131ndan ve Droplet&#8217;teki <code>~\/.ssh\/authorized_keys<\/code> dosyas\u0131nda do\u011fru genel anahtar\u0131n bulundu\u011fundan emin olun. Dosya izinlerini kontrol edin (<code>chmod 600 ~\/.ssh\/authorized_keys<\/code>, <code>chmod 700 ~\/.ssh<\/code>).<br \/>\n    *   <strong>Hata:<\/strong> <code>Host key verification failed.<\/code><br \/>\n        *   <strong>\u00c7\u00f6z\u00fcm:<\/strong> <code>ssh-keyscan<\/code> ad\u0131m\u0131n\u0131 i\u015f ak\u0131\u015f\u0131n\u0131za ekledi\u011finizden emin olun veya SSH komutuna <code>-o StrictHostKeyChecking=no<\/code> parametresini ekleyin (ancak bu g\u00fcvenlik riskleri ta\u015f\u0131yabilir, dikkatli kullan\u0131n).<br \/>\n    *   <strong>Hata:<\/strong> Ba\u011flant\u0131 zaman a\u015f\u0131m\u0131na u\u011frad\u0131.<br \/>\n        *   <strong>\u00c7\u00f6z\u00fcm:<\/strong> Droplet&#8217;inizin IP adresinin do\u011fru oldu\u011fundan ve g\u00fcvenlik duvar\u0131n\u0131n SSH portuna (22) eri\u015fimi engellemedi\u011finden emin olun.<\/p>\n<p>2.  <strong>Ortam De\u011fi\u015fkeni Eksiklikleri:<\/strong><br \/>\n    *   <strong>Hata:<\/strong> Uygulaman\u0131z bir ortam de\u011fi\u015fkenini bulam\u0131yor.<br \/>\n        *   <strong>\u00c7\u00f6z\u00fcm:<\/strong> Ortam de\u011fi\u015fkenlerinin GitHub Secrets&#8217;ta do\u011fru tan\u0131mland\u0131\u011f\u0131ndan ve i\u015f ak\u0131\u015f\u0131n\u0131zda <code>env:<\/code> blo\u011fu i\u00e7inde veya SSH komutlar\u0131 arac\u0131l\u0131\u011f\u0131yla uygulamaya iletildi\u011finden emin olun. Hassas uygulama s\u0131rlar\u0131 i\u00e7in Droplet&#8217;te <code>.env<\/code> dosyalar\u0131n\u0131 veya App Platform&#8217;un kendi ortam de\u011fi\u015fkeni y\u00f6netimini tercih edin.<\/p>\n<p>3.  <strong>Build veya Ba\u011f\u0131ml\u0131l\u0131k Sorunlar\u0131:<\/strong><br \/>\n    *   <strong>Hata:<\/strong> <code>npm install<\/code>, <code>composer install<\/code> veya <code>pip install<\/code> gibi komutlar ba\u015far\u0131s\u0131z oluyor.<br \/>\n        *   <strong>\u00c7\u00f6z\u00fcm:<\/strong> Droplet&#8217;e gerekli \u00e7al\u0131\u015fma zamanlar\u0131n\u0131n (Node.js, PHP, Python) ve paket y\u00f6neticilerinin y\u00fcklendi\u011finden emin olun. <code>.bashrc<\/code> veya <code>.profile<\/code> dosyalar\u0131ndaki PATH de\u011fi\u015fkenlerinin do\u011fru ayarland\u0131\u011f\u0131n\u0131 kontrol edin. GitHub Actions runner&#8217;\u0131 \u00fczerinde de ba\u011f\u0131ml\u0131l\u0131klar\u0131 y\u00fcklemek i\u00e7in ad\u0131mlar\u0131n\u0131z\u0131n oldu\u011fundan emin olun.<\/p>\n<p>4.  <strong>DigitalOcean API \u0130zin Hatalar\u0131 (App Platform i\u00e7in):<\/strong><br \/>\n    *   <strong>Hata:<\/strong> <code>doctl<\/code> komutlar\u0131 yetkilendirme hatas\u0131 veriyor.<br \/>\n        *   <strong>\u00c7\u00f6z\u00fcm:<\/strong> <code>DIGITALOCEAN_ACCESS_TOKEN<\/code> s\u0131rr\u0131n\u0131n do\u011fru ve ge\u00e7erli oldu\u011fundan emin olun. Token&#8217;\u0131n <code>Write<\/code> (Yazma) izinlerine sahip olmas\u0131 gerekti\u011fini kontrol edin.<\/p>\n<p>5.  <strong>GitHub Actions Loglar\u0131n\u0131 \u0130nceleme:<\/strong><br \/>\n    *   <strong>Genel \u00c7\u00f6z\u00fcm:<\/strong> Herhangi bir sorunla kar\u015f\u0131la\u015ft\u0131\u011f\u0131n\u0131zda, GitHub Actions aray\u00fcz\u00fcndeki i\u015f ak\u0131\u015f\u0131 \u00e7al\u0131\u015ft\u0131rmas\u0131n\u0131n loglar\u0131n\u0131 dikkatlice inceleyin. Hata mesajlar\u0131 genellikle sorunun k\u00f6k nedenini g\u00f6sterir. Ad\u0131m ad\u0131m \u00e7\u0131kt\u0131lar\u0131 kontrol ederek hangi ad\u0131m\u0131n ba\u015far\u0131s\u0131z oldu\u011funu ve nedenini anlayabilirsiniz.<\/p>\n<h3>Sonu\u00e7<\/h3>\n<p>GitHub Actions ve DigitalOcean&#8217;\u0131n birle\u015fimi, modern yaz\u0131l\u0131m geli\u015ftirme s\u00fcre\u00e7lerinde CI\/CD&#8217;nin g\u00fcc\u00fcn\u00fc parmaklar\u0131n\u0131z\u0131n ucuna getirir. Bu makalede ele ald\u0131\u011f\u0131m\u0131z Droplet&#8217;e SSH \u00fczerinden da\u011f\u0131t\u0131m ve DigitalOcean App Platform&#8217;a entegre da\u011f\u0131t\u0131m senaryolar\u0131, uygulamalar\u0131n\u0131z\u0131 buluta otomatik olarak da\u011f\u0131tmak i\u00e7in size esnek ve g\u00fc\u00e7l\u00fc \u00e7\u00f6z\u00fcmler sunar.<\/p>\n<p>CI\/CD pratikleri, kod kalitesini art\u0131r\u0131r, hata oranlar\u0131n\u0131 d\u00fc\u015f\u00fcr\u00fcr, geli\u015ftirici verimlili\u011fini y\u00fckseltir ve uygulamalar\u0131n\u0131z\u0131n pazara sunulma s\u00fcresini \u00f6nemli \u00f6l\u00e7\u00fcde h\u0131zland\u0131r\u0131r. GitHub Actions&#8217;\u0131n esnekli\u011fi ve DigitalOcean&#8217;\u0131n kullan\u0131c\u0131 dostu bulut altyap\u0131s\u0131 sayesinde, manuel da\u011f\u0131t\u0131m s\u00fcre\u00e7lerinin getirdi\u011fi operasyonel y\u00fck\u00fc azaltabilir, geli\u015ftiricilerin daha \u00e7ok inovasyona odaklanmas\u0131n\u0131 sa\u011flayabilirsiniz.<\/p>\n<p>Geli\u015fmi\u015f teknikler ve en iyi uygulamalar (testler, rollback stratejileri, ortam y\u00f6netimi, g\u00fcvenlik) ile CI\/CD hatt\u0131n\u0131z\u0131 daha sa\u011flam ve g\u00fcvenli hale getirebilirsiniz. Unutmay\u0131n ki otomasyon, sadece tekrarlayan g\u00f6revleri ortadan kald\u0131rmakla kalmaz, ayn\u0131 zamanda yaz\u0131l\u0131m geli\u015ftirme ya\u015fam d\u00f6ng\u00fcs\u00fcn\u00fcn her a\u015famas\u0131nda g\u00fcvenilirli\u011fi ve tutarl\u0131l\u0131\u011f\u0131 da art\u0131r\u0131r. Bu entegrasyonu projelerinize dahil ederek, daha h\u0131zl\u0131, daha g\u00fcvenilir ve daha verimli bir geli\u015ftirme deneyimi elde edeceksiniz.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"GitHub Actions ile DigitalOcean&#8217;a Otomatik Da\u011f\u0131t\u0131m: Kapsaml\u0131 Bir Rehber\nGiri\u015f\nModern yaz\u0131l\u0131m geli\u015ftirme s\u00fcre\u00e7lerinde h\u0131z, g\u00fcvenilirlik ve","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":[1401],"tags":[],"class_list":{"0":"post-31631","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-git","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>GitHub Actions ile DigitalOcean&#039;a Otomatik Da\u011f\u0131t\u0131m: Kapsaml\u0131 Bir Rehber - 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\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"GitHub Actions ile DigitalOcean&#039;a Otomatik Da\u011f\u0131t\u0131m: Kapsaml\u0131 Bir Rehber\" \/>\n<meta property=\"og:description\" content=\"GitHub Actions ile DigitalOcean&#039;a Otomatik Da\u011f\u0131t\u0131m: Kapsaml\u0131 Bir Rehber Giri\u015f Modern yaz\u0131l\u0131m geli\u015ftirme s\u00fcre\u00e7lerinde h\u0131z, g\u00fcvenilirlik ve\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-12T00:41:00+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=\"23 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"GitHub Actions ile DigitalOcean&#8217;a Otomatik Da\u011f\u0131t\u0131m: Kapsaml\u0131 Bir Rehber\",\"datePublished\":\"2025-10-12T00:41:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/\"},\"wordCount\":3884,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Git\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/\",\"name\":\"GitHub Actions ile DigitalOcean'a Otomatik Da\u011f\u0131t\u0131m: Kapsaml\u0131 Bir Rehber - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-12T00:41:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"GitHub Actions ile DigitalOcean&#8217;a Otomatik Da\u011f\u0131t\u0131m: Kapsaml\u0131 Bir Rehber\"}]},{\"@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":"GitHub Actions ile DigitalOcean'a Otomatik Da\u011f\u0131t\u0131m: Kapsaml\u0131 Bir Rehber - 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\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/","og_locale":"tr_TR","og_type":"article","og_title":"GitHub Actions ile DigitalOcean'a Otomatik Da\u011f\u0131t\u0131m: Kapsaml\u0131 Bir Rehber","og_description":"GitHub Actions ile DigitalOcean'a Otomatik Da\u011f\u0131t\u0131m: Kapsaml\u0131 Bir Rehber Giri\u015f Modern yaz\u0131l\u0131m geli\u015ftirme s\u00fcre\u00e7lerinde h\u0131z, g\u00fcvenilirlik ve","og_url":"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-12T00:41:00+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"23 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"GitHub Actions ile DigitalOcean&#8217;a Otomatik Da\u011f\u0131t\u0131m: Kapsaml\u0131 Bir Rehber","datePublished":"2025-10-12T00:41:00+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/"},"wordCount":3884,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Git"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/","url":"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/","name":"GitHub Actions ile DigitalOcean'a Otomatik Da\u011f\u0131t\u0131m: Kapsaml\u0131 Bir Rehber - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-12T00:41:00+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/github-actions-ile-digitaloceana-otomatik-dagitim-kapsamli-bir-rehber\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"GitHub Actions ile DigitalOcean&#8217;a Otomatik Da\u011f\u0131t\u0131m: Kapsaml\u0131 Bir Rehber"}]},{"@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\/31631","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=31631"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31631\/revisions"}],"predecessor-version":[{"id":31632,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31631\/revisions\/31632"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=31631"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=31631"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=31631"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}