Docker ile Astro Site Yayınlama: Çok Katmanlı Mimari ve Üretim Ortamı Optimizasyonu
Modern web teknolojileri arasında hız ve performans odaklı yapısıyla öne çıkan Astro sitelerini, Docker kullanarak güvenli, ölçeklenebilir ve sürdürülebilir bir şekilde canlı ortama nasıl taşıyacağınızı adım adım inceleyin.
Caner Serbest
Sistem ve Altyapı
5 dk okuma
Docker ile Astro Site Yayınlama: Çok Katmanlı Mimari ve Üretim Ortamı Optimizasyonu
Modern web geliştirme ekosisteminde performans, kullanıcı deneyimi ve arama motoru optimizasyonu (SEO) açısından statik siteler ve sunucu tarafında oluşturulan (SSR) sayfalar yeniden yükselişe geçti. Bu yükselişin arkasındaki en önemli araçlardan biri de şüphesiz Astro. Astro, bileşen tabanlı mimariyi (React, Vue, Svelte vb.) desteklerken, son aşamada sıfır istemci tarafı JavaScript felsefesiyle saf HTML ve CSS üretmesiyle bilinir.
Bir projeyi yerel geliştirme ortamından çıkarıp canlı (production) ortama taşırken en büyük önceliklerden biri, uygulamanın her ortamda aynı şekilde çalışmasını garantilemektir. İşte bu noktada konteyner teknolojileri, özellikle de Docker, operasyonel süreçlerin kurtarıcısı haline gelir. Bu rehberde, bir Astro sitesini Docker kullanarak çok katmanlı (multi-stage) build mimarisiyle nasıl paketleyeceğinizi, Nginx sunucusu üzerinde nasıl çalıştıracağınızı ve üretim ortamında dikkat etmeniz gereken pratik detayları ele alacağız.
Ön Gereksinimler ve Proje Yapısı
Bu kılavuzu takip etmek için sisteminizde Docker ve Docker Compose kurulu olmalıdır. Ayrıca temel düzeyde terminal kullanımı ve Astro projelerinin yapısına aşina olmanız işinizi kolaylaştıracaktır.
Varsayalım ki elimizde astro-blog adında standart bir projemiz var. Proje kök dizinimizde aşağıdaki temel dosyalar yer alıyor:
astro-blog/
├── src/
├── public/
├── package.json
├── astro.config.mjs
└── package-lock.json (veya yarn.lock / pnpm-lock.yaml)
Astro projeleri varsayılan olarak npm run build komutunu çalıştırdığında dist/ adında bir dizin oluşturur. Bu dizin, sunulmaya hazır saf statik dosyaları (HTML, CSS, JS, görseller) barındırır. Amacımız, bu dosyaları bir Docker imajı içine gömmek ve yüksek performanslı bir web sunucusu (Nginx) aracılığıyla dış dünyaya sunmaktır.
Çok Katmanlı (Multi-Stage) Dockerfile Hazırlama
Docker imaj boyutlarını minimumda tutmak ve güvenlik açıklarını azaltmak için en iyi pratiklerden biri multi-stage build (çok katmanlı derleme) yapısını kullanmaktır. Bu yaklaşımda, ilk aşamada bağımlılıkları indirip projeyi derler (build), ikinci aşamada ise sadece derlenmiş çıktıları ve hafif bir web sunucusunu nihai imaja dahil ederiz.
Projenizin kök dizinine Dockerfile adında bir dosya oluşturun ve aşağıdaki yapılandırmayı ekleyin:
# --- Aşama 1: Derleme (Build) Aşaması ---
FROM node:20-alpine AS builder
WORKDIR /app
# Bağımlılık dosyalarını kopyala
COPY package*.json ./
# Bağımlılıkları yükle
RUN npm ci
# Proje kaynak kodlarını kopyala
COPY . .----
# Astro projesini derle
RUN npm run build
# --- Aşama 2: Sunum (Production) Aşaması ---
FROM nginx:alpine
# Nginx varsayılan konfigürasyonunu temizle
RUN rm -rf /usr/share/nginx/html/*
# Builder aşamasından üretilen dist klasörünü Nginx sunucu dizinine kopyala
COPY --from=builder /app/dist /usr/share/nginx/html
# Özel Nginx konfigürasyonunu kopyala (İsteğe bağlı ama önerilir)
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Nginx portunu dış dünyaya aç
EXPOSE 80
# Konteyner ayağa kalkarken Nginx'i ön planda (daemon off) çalıştır
CMD ["nginx", "-g", "daemon off;"]
Bu Dockerfile iki temel adımdan oluşur. İlk adımda Node.js 20 Alpine imajı kullanılarak bağımlılıklar yüklenir ve npm run build komutuyla dist/ klasörü üretilir. İkinci adımda ise çok daha hafif olan Nginx Alpine imajı kullanılır ve sadece üretilen statik dosyalar Nginx’in yayın dizinine aktarılır. Node.js çalışma ortamı nihai imaja dahil edilmediği için hem imaj boyutu küçülür hem de olası güvenlik riskleri minimuma iner.
Nginx Yapılandırması (nginx.conf)
Statik sitelerin performansını artırmak ve güvenlik başlıklarını (security headers) ayarlamak için Nginx’i özelleştirmek önemlidir. Proje kök dizininde nginx.conf adında bir dosya oluşturun:
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html index.htm;
# Gzip sıkıştırma ile performans optimizasyonu
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+json application/javascript;
gzip_disable "MSIE [1-6]\.";
location / {
try_files $uri $uri/ =404;
}
# Statik varlıklar için önbellekleme (Caching)
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Hata sayfaları
error_page 404 /404.html;
}
Bu yapılandırma, sunulan tüm statik varlıkların (görseller, fontlar, derlenmiş JS/CSS dosyaları) tarayıcı tarafından önbelleğe alınmasını sağlayarak sonraki sayfa yükleme sürelerini ciddi oranda düşürür. Ayrıca Gzip sıkıştırmasını aktif hale getirerek bant genişliği tasarrufu sağlar.
.dockerignore Dosyası ile Gereksiz Dosyaları Hariç Tutma
Build sürecini hızlandırmak ve hassas dosyaların Docker imajına sızmasını engellemek için kök dizinde .dockerignore dosyası bulundurmak şarttır. Aşağıdaki içeriği bu dosyaya ekleyin:
node_modules
dist
.git
.gitignore
Dockerfile
docker-compose.yml
README.md
.env
Bu sayede yerel ortamdaki gereksiz dosyalar Docker daemon’ına gönderilmez ve build süreci çok daha hızlı tamamlanır.
Docker Konteynerini Yerel Ortamda Test Etme
Docker imajımızı oluşturmak ve test etmek için terminalde projenin kök dizinindeyken şu komutu çalıştırın:
docker build -t astro-site:latest .
İmaj oluşturma süreci tamamlandıktan sonra, konteyneri ayağa kaldırmak için şu komutu kullanabilirsiniz:
docker run -d -p 8080:80 --name astro-container astro-site:latest
Tarayıcınızı açıp http://localhost:8080 adresine gittiğinizde, Astro sitenizin sorunsuz bir şekilde çalıştığını görmelisiniz. Her şey yolunda gittiyse, testi sonlandırmak için şu komutlarla konteyneri durdurabilir ve silebilirsiniz:
docker stop astro-container
docker rm astro-container
Docker Compose ile Yönetimi Kolaylaştırma
Canlı ortamlarda veya çoklu konteyner senaryolarında komut satırından uzun argümanlar girmek yerine docker-compose.yml kullanmak operasyonel süreklilik sağlar. Proje kök dizininde docker-compose.yml dosyası oluşturun:
version: '3.8'
services:
web:
image: astro-site:latest
build:
context: .
dockerfile: Dockerfile
container_name: astro_production_app
restart: unless-stopped
ports:
- "80:80"
healthcheck:
test: ["CMD", "wget", "--spider", "http://localhost/"]
interval: 30s
timeout: 10s
retries: 3
Bu Docker Compose dosyası birkaç kritik özellik barındırır:
restart: unless-stopped: Sunucu yeniden başladığında veya konteyner beklenmedik bir şekilde çöktüğünde otomatik olarak yeniden başlatılmasını sağlar.healthcheck: Nginx sunucusunun ayakta olup olmadığını periyodik olarak kontrol eder, sistem sağlığını izlemek için kritik bir önlemdir.
Sistemi tek komutla ayağa kaldırmak için:
docker compose up -d --build
Canlı Ortamda Ters Vekil Sunucu (Reverse Proxy) ve SSL Entegrasyonu
Gerçek bir canlı ortamda, sitenizi doğrudan 80 numaralı porttan sunmak yerine ön planda bir Reverse Proxy (örneğin Nginx Proxy Manager, Traefik veya ana makine üzerindeki Nginx) bulundurmak ve Let’s Encrypt ile SSL (HTTPS) sertifikası entegre etmek gerekir.
Eğer ana makinenizde başka servisler de çalışıyorsa, Docker Compose dosyasındaki port yönlendirmesini dış dünyaya kapatıp sadece dahili ağa açabilir veya port numarasını değiştirebilirsiniz:
ports:
- "127.0.0.1:3000:80"
Bu yöntemle, dış dünyadan gelen tüm istekler ana makinedeki Nginx veya Traefik tarafından karşılanır, SSL sonlandırması (SSL termination) yapılır ve trafik güvenli bir şekilde Docker içindeki Astro konteynerinin 3000 numaralı portuna iletilir.
Sürekli Entegrasyon ve Dağıtım (CI/CD) Entegrasyonu
Canlı ortamda kod güncellemelerini manuel olarak yapmak yerine bir CI/CD süreci kurmak uzun vadede zaman kazandırır. GitHub Actions kullanarak her main dalına (branch) push yapıldığında imajın otomatik olarak build edilip sunucuya gönderilmesi sağlanabilir.
Basit bir GitHub Actions iş akışı örneği (.github/workflows/deploy.yml):
name: Deploy Astro Site
on:
push:
branches: [ "main" ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: kullaniciadi/astro-site:latest
Bu otomasyon sayesinde geliştirici sadece kodunu yazar ve repoya gönderir; CI/CD pipeline’ı imajı günceller. Sunucunuzda ise sadece docker compose pull && docker compose up -d komutunu çalıştırarak güncellemeyi canlıya almış olursunuz.
Sonuç
Astro projelerini Docker ile paketlemek, ortamlardan bağımsız (environment-agnostic) çalışan, güvenli ve ölçeklenebilir bir yayınlama mimarisi kurmanızı sağlar. Çok katmanlı build yaklaşımı sayesinde gereksiz bağımlılıkları ortadan kaldırarak minimum kaynak tüketimiyle maksimum performans elde edebilirsiniz. Bu yapıyı Nginx optimizasyonları ve sağlam bir ters vekil sunucu kurgusuyla desteklediğinizde, üretim ortamlarında güvenle çalışacak sürdürülebilir bir web altyapısına sahip olursunuz.
Bu yazı Gemini ile otomatik oluşturulmuştur.