Azure App Service ile Web Uygulama Dağıtımı
Bulut tabanlı uygulama dağıtımı söz konusu olduğunda Azure App Service, karmaşık altyapı yönetimini ortadan kaldırarak geliştiricilerin ve sistem yöneticilerinin doğrudan uygulamaya odaklanmasını sağlıyor. Sunucu kurmak yok, işletim sistemi yamalaması yok, web sunucusu konfigürasyonu yok. Kulağa güzel geliyor, değil mi? Ama bu kadar basit değil tabii. App Service’i gerçekten etkin kullanabilmek için biraz derine inmek gerekiyor. Bu yazıda sıfırdan başlayarak production ortamına kadar tüm süreci pratik örneklerle ele alacağız.
Azure App Service Nedir ve Ne Zaman Kullanmalısınız
App Service özünde Microsoft’un yönettiği bir PaaS (Platform as a Service) çözümüdür. Uygulamanızı çalıştırmak için gereken işletim sistemi, çalışma zamanı, yük dengeleyici ve ölçeklendirme altyapısı sizin yerinize yönetilir. .NET, Node.js, Python, PHP, Java ve Ruby gibi popüler çalışma zamanlarını destekler. Docker container desteği de mevcut.
Peki ne zaman App Service tercih etmeli, ne zaman etmemeli? Şöyle düşünün: Eğer özel kernel parametreleri ayarlamanız, düşük seviyeli ağ konfigürasyonu yapmanız ya da egzotik bir çalışma zamanı kullanmanız gerekiyorsa App Service sizin için değil. Ama standart bir web uygulaması, API servisi ya da arka plan işleri çalıştırıyorsanız App Service oldukça mantıklı bir seçim.
Ortam Hazırlığı ve Azure CLI Kurulumu
Başlamadan önce Azure CLI’ın kurulu ve güncel olduğundan emin olmanız gerekiyor. Neredeyse her şeyi Azure portalından yapabilirsiniz ama komut satırı üzerinden çalışmak hem tekrar edilebilir hem de otomasyon için çok daha kullanışlı.
# Azure CLI kurulumu (Ubuntu/Debian)
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
# macOS için Homebrew ile
brew update && brew install azure-cli
# Kurulum doğrulama
az --version
# Azure hesabına giriş
az login
# Mevcut subscription'ları listele
az account list --output table
# Çalışmak istediğiniz subscription'ı ayarla
az account set --subscription "Subscription-ID-veya-Adi"
Giriş yaptıktan sonra hangi subscription üzerinde çalıştığınızı her zaman kontrol edin. Birden fazla subscription’ınız varsa yanlış ortamda kaynak oluşturmak çok kolay. Bunu defalarca yaşadım, inanın.
Resource Group ve App Service Plan Oluşturma
Her şey bir resource group ile başlar. Resource group, ilgili Azure kaynaklarını mantıksal olarak bir arada tutan bir konteynerdir. Temiz bir yapı için her proje ya da ortam için ayrı resource group kullanmanızı tavsiye ederim.
# Resource group oluştur
az group create
--name rg-myapp-production
--location westeurope
# Mevcut lokasyonları görmek için
az account list-locations --output table
# App Service Plan oluştur (Linux tabanlı, B2 SKU)
az appservice plan create
--name asp-myapp-production
--resource-group rg-myapp-production
--location westeurope
--is-linux
--sku B2
# Mevcut SKU seçeneklerini görmek için
az appservice plan list-skus --location westeurope --output table
App Service Plan seçimi kritik bir karardır. SKU’lar şu şekilde sıralanır:
- F1 (Free): Geliştirme ve test için, günde 60 dakika CPU sınırı var, production için kesinlikle kullanmayın
- B1-B3 (Basic): Küçük production uygulamaları için uygun, auto-scale yok
- S1-S3 (Standard): Auto-scale desteği var, staging slot’ları mevcut, çoğu production senaryosu için ideal
- P1v3-P3v3 (Premium v3): Yüksek performans gerektiren durumlar için, daha iyi donanım, daha hızlı scale-out
- I1-I3 (Isolated): App Service Environment içinde çalışır, VNet isolation gerektiğinde
Production ortamı için en az S1 kullanmanızı öneririm. Deployment slot özelliği S1 ve üzerinde geliyor ve bu özellik olmadan blue-green deployment yapmak çok zorlaşıyor.
Web Uygulaması Oluşturma ve İlk Dağıtım
App Service Plan hazır olduğunda web uygulamasını oluşturabilirsiniz. Burada çalışma zamanını doğru seçmek önemli.
# Mevcut çalışma zamanlarını listele
az webapp list-runtimes --os-type linux
# Node.js uygulaması için web app oluştur
az webapp create
--name myapp-production-webapp
--resource-group rg-myapp-production
--plan asp-myapp-production
--runtime "NODE:18-lts"
# Python uygulaması için
az webapp create
--name myapp-production-webapp
--resource-group rg-myapp-production
--plan asp-myapp-production
--runtime "PYTHON:3.11"
# .NET 7 için
az webapp create
--name myapp-production-webapp
--resource-group rg-myapp-production
--plan asp-myapp-production
--runtime "DOTNET:7.0"
Web uygulaması oluşturulduktan sonra otomatik olarak https://myapp-production-webapp.azurewebsites.net adresinden erişilebilir hale gelir. Şimdi uygulamamızı bu platforma nasıl dağıtacağımıza bakalım.
Dağıtım Yöntemleri
Azure App Service birden fazla dağıtım yöntemini destekliyor. Her birinin avantajları ve kullanım senaryoları farklı.
Git ile Dağıtım (Local Git Deployment)
Küçük ekipler ve hızlı prototipleme için kullanışlı bir yöntem. Doğrudan Azure’a push yaparsınız.
# Local Git dağıtımını etkinleştir
az webapp deployment source config-local-git
--name myapp-production-webapp
--resource-group rg-myapp-production
# Deployment credentials ayarla
az webapp deployment user set
--user-name mydeployuser
--password "G3rce!S1freP@ssw0rd"
# Komutu çalıştırdıktan sonra dönen Git URL'ini not edin
# Örnek: https://[email protected]/myapp-production-webapp.git
# Projenizin dizininde
git remote add azure https://[email protected]/myapp-production-webapp.git
git push azure main:master
ZIP Dağıtımı
CI/CD pipeline içinde sıkça kullandığım yöntemlerden biri. Hızlı ve güvenilir.
# Uygulamayı zip'e sıkıştır (Node.js örneği)
cd /path/to/your/app
npm install --production
zip -r deployment.zip . -x "*.git*" -x "node_modules/.cache/*"
# ZIP dağıtımını gerçekleştir
az webapp deployment source config-zip
--name myapp-production-webapp
--resource-group rg-myapp-production
--src deployment.zip
# Dağıtım durumunu kontrol et
az webapp deployment list-publishing-credentials
--name myapp-production-webapp
--resource-group rg-myapp-production
Docker Container Dağıtımı
Uygulamanız container olarak paketlenmişse bu yaklaşım en temiz çözümü sunuyor. Ortam tutarlılığı açısından da en güvenilir yöntem.
# Container Registry bilgilerini ayarla
az webapp config container set
--name myapp-production-webapp
--resource-group rg-myapp-production
--docker-custom-image-name myregistry.azurecr.io/myapp:latest
--docker-registry-server-url https://myregistry.azurecr.io
--docker-registry-server-user myregistryuser
--docker-registry-server-password "RegistryPassword123!"
# Azure Container Registry ile managed identity kullanımı (önerilen)
az webapp identity assign
--name myapp-production-webapp
--resource-group rg-myapp-production
# ACR pull yetkisi ver
az role assignment create
--assignee <webapp-principal-id>
--scope /subscriptions/<sub-id>/resourceGroups/rg-myapp-production/providers/Microsoft.ContainerRegistry/registries/myregistry
--role AcrPull
Uygulama Ayarları ve Ortam Değişkenleri
Uygulama konfigürasyonu için connection string’leri ve ortam değişkenlerini doğrudan kaynak koduna gömmek en büyük güvenlik hatalarından biri. App Service, bu değerleri güvenli şekilde saklamak için uygulama ayarları mekanizması sunuyor.
# Tek bir uygulama ayarı ekle
az webapp config appsettings set
--name myapp-production-webapp
--resource-group rg-myapp-production
--settings NODE_ENV=production
# Birden fazla ayarı aynı anda ekle
az webapp config appsettings set
--name myapp-production-webapp
--resource-group rg-myapp-production
--settings
NODE_ENV=production
API_BASE_URL=https://api.internal.company.com
MAX_CONNECTIONS=100
LOG_LEVEL=warn
# Connection string ekle (veritabanı bağlantıları için)
az webapp config connection-string set
--name myapp-production-webapp
--resource-group rg-myapp-production
--connection-string-type SQLAzure
--settings "MainDB=Server=myserver.database.windows.net;Database=mydb;User Id=dbuser;Password=DbP@ss123;"
# Mevcut ayarları listele
az webapp config appsettings list
--name myapp-production-webapp
--resource-group rg-myapp-production
--output table
Hassas değerler için Key Vault referansı kullanmak çok daha güvenli. Örneğin @Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/DbPassword/) formatında bir değer yazabilirsiniz. Managed Identity ile bu referanslar otomatik olarak çözümlenir.
Deployment Slot’ları ile Blue-Green Deployment
Deployment slot’ları App Service’in en güçlü özelliklerinden biri. Production’ı etkilemeden yeni sürümü test edip sonra tek tıkla (ya da komutla) geçiş yapabilirsiniz. Sıcak swap olduğu için kullanıcılar kesinti yaşamaz.
# Staging slot oluştur
az webapp deployment slot create
--name myapp-production-webapp
--resource-group rg-myapp-production
--slot staging
# Staging slot'a dağıtım yap
az webapp deployment source config-zip
--name myapp-production-webapp
--resource-group rg-myapp-production
--slot staging
--src deployment-v2.zip
# Staging slot'a ait URL'yi doğrula
# https://myapp-production-webapp-staging.azurewebsites.net
# Staging'i test ettikten sonra production ile swap yap
az webapp deployment slot swap
--name myapp-production-webapp
--resource-group rg-myapp-production
--slot staging
--target-slot production
# Swap sonrası eski production staging'e geçer
# Sorun olursa geri almak için tekrar swap yap
az webapp deployment slot swap
--name myapp-production-webapp
--resource-group rg-myapp-production
--slot staging
--target-slot production
Slot ayarlarını “slot sticky” yapabilirsiniz. Bu, swap sırasında o ayarın slot ile birlikte geçmediği anlamına gelir. Örneğin NODE_ENV=staging değerinin her zaman staging slot’unda kalmasını isteyebilirsiniz.
Otomatik Ölçeklendirme Konfigürasyonu
Trafik ani artışlarında uygulamanızın ayakta kalması için auto-scale kuralları oluşturmanız gerekiyor. Standart ve üzeri planlarda bu özellik mevcut.
# Auto-scale profili oluştur
az monitor autoscale create
--resource-group rg-myapp-production
--resource myapp-production-webapp
--resource-type Microsoft.Web/sites
--name autoscale-myapp
--min-count 2
--max-count 10
--count 2
# CPU yüksekse scale-out kuralı ekle
az monitor autoscale rule create
--resource-group rg-myapp-production
--autoscale-name autoscale-myapp
--condition "CpuPercentage > 70 avg 5m"
--scale out 2
# CPU düşükse scale-in kuralı ekle
az monitor autoscale rule create
--resource-group rg-myapp-production
--autoscale-name autoscale-myapp
--condition "CpuPercentage < 30 avg 10m"
--scale in 1
Loglama ve Monitoring
Production uygulamasında neyin döndüğünü görmek hayati önem taşıyor. App Service’in yerleşik loglama özellikleri başlangıç için yeterli, ama büyük sistemlerde Application Insights entegrasyonu şart.
# Web sunucusu loglarını etkinleştir
az webapp log config
--name myapp-production-webapp
--resource-group rg-myapp-production
--web-server-logging filesystem
--docker-container-logging filesystem
--application-logging filesystem
--level warning
--detailed-error-messages true
--failed-request-tracing true
# Gerçek zamanlı log streaming
az webapp log tail
--name myapp-production-webapp
--resource-group rg-myapp-production
# Application Insights entegrasyonu
az monitor app-insights component create
--app myapp-insights
--location westeurope
--resource-group rg-myapp-production
--application-type web
# Instrumentation key'i uygulama ayarlarına ekle
az webapp config appsettings set
--name myapp-production-webapp
--resource-group rg-myapp-production
--settings APPINSIGHTS_INSTRUMENTATIONKEY="your-instrumentation-key"
Log streaming son derece kullanışlı. Bir sorun yaşandığında direkt terminal üzerinden gerçek zamanlı logları takip edebilirsiniz. Özellikle deployment sonrası ilk birkaç dakikada bu özellik hayat kurtarıcı.
Özel Domain ve SSL Sertifikası
Production uygulamaları için azurewebsites.net adresi yeterli değil. Özel domain ve SSL sertifikası bağlamak gerekiyor.
# Özel domain ekle (DNS kayıtlarını önce oluşturmanız gerekiyor)
az webapp config hostname add
--webapp-name myapp-production-webapp
--resource-group rg-myapp-production
--hostname www.mycompany.com
# App Service Managed Certificate (ücretsiz SSL) ekle
az webapp config ssl create
--hostname www.mycompany.com
--name myapp-production-webapp
--resource-group rg-myapp-production
# SSL bağla
az webapp config ssl bind
--certificate-thumbprint <thumbprint>
--ssl-type SNI
--name myapp-production-webapp
--resource-group rg-myapp-production
# HTTPS'i zorunlu kıl
az webapp update
--name myapp-production-webapp
--resource-group rg-myapp-production
--https-only true
Gerçek Dünya Senaryosu: CI/CD Pipeline ile Tam Otomasyon
Şimdi tüm bunları bir araya getirelim. Çoğu ekipte uygulamalar GitHub Actions ya da Azure DevOps üzerinden otomatik olarak dağıtılıyor. İşte basit ama işlevsel bir GitHub Actions workflow’u:
# GitHub Actions için gerekli secrets'ları ayarla
# AZURE_WEBAPP_PUBLISH_PROFILE değerini almak için:
az webapp deployment list-publishing-profiles
--name myapp-production-webapp
--resource-group rg-myapp-production
--xml
Bu komutu çalıştırdığınızda dönen XML’i GitHub repository Settings > Secrets > Actions kısmına AZURE_WEBAPP_PUBLISH_PROFILE adıyla eklemeniz gerekiyor. Ardından .github/workflows/deploy.yml dosyasında şu yapıyı kullanabilirsiniz:
# workflow dosyasını oluşturmak için dizin hazırla
mkdir -p .github/workflows
# Temel workflow içeriğini oluştur (bash heredoc ile)
cat > .github/workflows/deploy.yml << 'EOF'
name: Deploy to Azure App Service
on:
push:
branches: [main]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm ci --production
- name: Run tests
run: npm test
- name: Create deployment package
run: zip -r deployment.zip . -x "*.git*" "*.github*"
- name: Deploy to staging slot
uses: azure/webapps-deploy@v2
with:
app-name: myapp-production-webapp
slot-name: staging
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
package: deployment.zip
- name: Swap staging to production
uses: azure/CLI@v1
with:
azcliversion: latest
inlineScript: |
az webapp deployment slot swap
--name myapp-production-webapp
--resource-group rg-myapp-production
--slot staging
--target-slot production
EOF
echo "Workflow dosyasi olusturuldu."
Sık Karşılaşılan Sorunlar ve Çözümleri
Uygulama 503 Service Unavailable döndürüyor: Bu genellikle uygulamanın başlayamaması anlamına gelir. İlk yapılacak iş log akışını açmak.
az webapp log tailkomutunu çalıştırın- Uygulama ayarlarında eksik environment variable olup olmadığını kontrol edin
- Startup komutu doğru ayarlanmış mı denetleyin
Deployment başarısız oluyor: ZIP dağıtımında en sık karşılaşılan sorunlardan biri çok büyük paket boyutu ya da eksik bağımlılıklar.
node_modulesiçindeki gereksiz dosyaları.zipignoreile hariç tutun- SCM endpoint’ini kontrol edin:
https://myapp.scm.azurewebsites.net - Kudu konsoluna erişerek deployment loglarını inceleyin
Auto-scale beklendiği gibi çalışmıyor: Scale kurallarının metric toplaması birkaç dakika sürebilir.
- Scale kurallarında cooldown sürelerini kontrol edin
- Min ve max instance sayılarının mantıklı değerlerde olduğunu doğrulayın
- Platform sınırlamalarına dikkat edin: S planında maksimum 10 instance
Memory leak şüphesi: Uygulamanız giderek yavaşlıyor ve restart sonrası düzeliyor mu?
- Application Insights ile memory kullanımını izleyin
- Otomatik restart kuralı tanımlayabilirsiniz
- Proactive auto-heal özelliğini aktif edin
Maliyet Optimizasyonu İpuçları
App Service maliyetleri kontrol altında tutmak için birkaç pratik yöntem var:
- Dev/test ortamları için B1 kullanın: Staging ortamları için premium plan şart değil
- Aynı App Service Plan’da birden fazla uygulama çalıştırın: Plan ücreti sabittir, ek uygulama eklemenin ek maliyeti yoktur (kaynak paylaşımlı)
- Kullanılmayan slot’ları silin: Her slot ayrı kaynak tüketir
- Reserved Instance satın alın: 1 ya da 3 yıllık commitment ile %40-55 indirim alabilirsiniz
- Scale-down kurallarını agresif tutun: Gece trafiği düşükse instance sayısını azaltın
Sonuç
Azure App Service, doğru kullanıldığında gerçekten işinizi kolaylaştıran bir platform. Altyapı yönetimi yerine uygulama kalitesine odaklanabilmek büyük bir avantaj. Ama “yönetilen platform” demek “sihirli platform” anlamına gelmiyor. Deployment stratejinizi iyi planlamanız, monitoring kurmanız ve maliyet optimizasyonunu göz ardı etmemeniz gerekiyor.
Deployment slot’larını kullanmadan production’a doğrudan dağıtım yapmayın. Managed Certificate ile ücretsiz SSL kullanma imkanını kaçırmayın. Uygulama ayarlarını ve connection string’leri mutlaka App Service konfigürasyonundan yönetin, kaynak koduna gömmeyin. Application Insights’ı kurmayı ertelemeyin, sorun çıktığında elimizde veri olmadığı için ne kadar zaman harcadığımızı yaşayarak öğrendim.
Bu yazıdaki komutları doğrudan production’a uygulamadan önce bir test ortamında denemenizi şiddetle tavsiye ederim. Azure’un hızlı değişen bir platform olduğunu da unutmayın; bazı komut parametreleri zaman içinde değişebilir, az --help her zaman en güncel bilgiyi sunar.
