Blog
İzole, Tekrarlanabilir Web Barındırma için Docker Compose'ta Ustalaşmak
Dağıtım sorunlarını çözen izole, tekrarlanabilir ve kolayca yönetilebilir web barındırma ortamları oluşturmak için Docker Compose'tan nasıl yararlanacağınızı öğrenin.
Özet
"Benim makinemde çalışıyor" sorunu, web geliştiricileri ve sistem yöneticileri için sürekli bir derttir. Konteynerleştirme teknolojisine sahip Docker, uygulamaları ve bağımlılıklarını izole edilmiş ortamlara paketleyerek sağlam bir çözüm sunar. Ancak, bir web sunucusu, veritabanı ve önbellekleme katmanı gibi birden çok birbirine bağlı hizmeti yönetmek karmaşık hale gelebilir. Bu makale, çoklu konteyner Docker uygulamalarının tanımını ve yönetimini basitleştiren güçlü bir araç olan Docker Compose'a derinlemesine dalmaktadır. Tüm web barındırma yığınınızı tek bir yapılandırma dosyasında nasıl tanımlayacağınızı, geliştirme, hazırlık ve üretim ortamlarında tutarlılığı sağlayacağınızı ve sonuç olarak daha güvenilir ve tekrarlanabilir dağıtımlara yol açacağınızı inceleyeceğiz.
"Benim Makinemde Çalışıyor"nun Ötesinde: Docker Compose ile Web Barındırma Yığınınızı Yönetmek
Korkulan "benim makinemde çalışıyor" sendromu, yazılım geliştirmede evrensel bir acı noktasıdır. Bir geliştiricinin yerel ortamı ile üretim sunucusu arasındaki bir kopukluğu ifade eder, bu da sinir bozucu hata ayıklama oturumlarına ve güvenilmez dağıtımlara yol açar. Docker, konteynerleştirme teknolojisi aracılığıyla, tutarlı yürütme ortamları vaat eden güçlü bir panzehir olarak ortaya çıkmıştır. Peki ya web uygulamanız yalnızca tek bir işlem değil de, bir web sunucusu, bir veritabanı, bir önbellekleme katmanı, belki bir mesaj kuyruğu gibi karmaşık bir hizmet ekosistemi olduğunda ne olur?
Bu birbirine bağlı bileşenleri farklı ortamlarda manuel olarak yönetmek hızla kaosa dönüşebilir. İşte Docker Compose'un parladığı yer burasıdır. Basit bir YAML dosyasıyla çoklu konteyner Docker uygulamalarını tanımlamanıza ve çalıştırmanıza olanak tanır. Bireysel konteyner komutlarıyla uğraşmak yerine, uygulamanızın tüm hizmetlerini, ağlarını ve birimlerini tanımlarsınız ve Docker Compose bunları sizin için düzenleme işini üstlenir.
Bu makale, izole, tekrarlanabilir ve yönetilebilir web barındırma ortamları oluşturmak için Docker Compose'un pratik uygulamasında size rehberlik edecektir. Temel Docker kullanımının ötesine geçerek, dağıtım sürtünmesini en aza indiren ve güvenilirliği en üst düzeye çıkaran sağlam bir barındırma kurulumu oluşturmayı göstereceğiz.
Sorun: Modern Web Yığınlarının Karmaşıklığı
Modern web uygulamaları nadiren boşlukta var olur. Tipik bir kurulum şunları içerebilir:
- Bir Web Sunucusu: Uygulamanızın ön yüzünü sunar (örneğin, Nginx, Apache).
- Bir Uygulama Sunucusu/Çalışma Zamanı: Arka uç kodunuzu çalıştırır (örneğin, Node.js, Python/Gunicorn, PHP-FPM).
- Bir Veritabanı: Kalıcı verileri depolar (örneğin, PostgreSQL, MySQL, MongoDB).
- Bir Önbellek: Sık erişilen verileri depolayarak performansı artırır (örneğin, Redis, Memcached).
- Diğer Hizmetler: Mesaj kuyrukları, arama motorları veya arka plan işi işlemcileri gibi.
Bu bileşenlerin her birinin kendi bağımlılıkları, yapılandırma gereksinimleri ve ağ ihtiyaçları vardır. Her birini yeni bir sunucuda, hatta bir geliştiricinin dizüstü bilgisayarında manuel olarak kurmak ve yapılandırmak zaman alıcı, hataya açık ve tutarlı bir şekilde tekrarlanması zordur. Bu şunlara yol açar:
-
Tutarsız Ortamlar: Geliştirme, hazırlık ve üretim ortamları arasındaki farklılıklar.
-
Bağımlılık Cehennemi: Farklı kitaplık veya sistem paketi sürümleri arasındaki çakışmalar.
-
Manuel Yapılandırma Hataları: Kurulum sırasında yazım hataları veya kaçırılan adımlar.
-
Zor İşe Alım: Yeni ekip üyeleri geliştirme ortamını çalıştırmakta zorlanıyor.
-
Yavaş Dağıtım Döngüleri: Kodu geliştirmeden üretime alma süreci zahmetlidir.
Çözüm: Bildirimsel Altyapı için Docker Compose
Docker Compose, tüm uygulama yığınınızı tek bir docker-compose.yml dosyasında tanımlamanıza olanak tanıyarak bu zorlukların üstesinden gelir. Bu dosya, her hizmeti, görüntüsünü, bağlantı noktalarını, birimlerini, ortam değişkenlerini ve hizmetlerin birbirine nasıl bağlanması gerektiğini belirten bir plan görevi görür.
docker-compose.yml İçindeki Temel Kavramlar:
version: Compose dosya biçimi sürümünü belirtir. Yakın tarihli bir sürüm kullanmak iyi bir uygulamadır.services: Uygulamanızın her konteynerleştirilmiş bileşenini tanımladığınız ana bölümdür.image: Hizmet için kullanılacak Docker görüntüsü (örneğin,nginx:latest,postgres:14). Özel görüntüler için bir Dockerfile belirtmek üzerebuildde kullanabilirsiniz.ports: Ana makine bağlantı noktalarını konteynere eşler (örneğin,80:80ana makine bağlantı noktası 80'i konteyner bağlantı noktası 80'e eşler).volumes: Kalıcı veriler veya yapılandırma için ana makine dizinlerini veya adlandırılmış birimleri konteynere bağlar (örneğin,./html:/usr/share/nginx/html).environment: Konteyner içinde ortam değişkenlerini ayarlar (örneğin,POSTGRES_USER=myuser).depends_on: Hizmetler arasındaki bağımlılıkları belirtir, belirli bir sırada başlamalarını sağlar (ancak hazır olduklarını garanti etmez).networks: Hizmetlerinizin iletişim kurması için özel ağlar tanımlar.
networks: Hizmetlerinizin katılabileceği özel ağları tanımlar.volumes: Kalıcı veri depolama için adlandırılmış birimler tanımlar.
Pratik Adımlar: Örnek Bir Web Barındırma Yığını Oluşturma
Yaygın bir web barındırma senaryosu oluşturalım: Nginx tarafından sunulan statik bir web sitesi ve dinamik içerik için bir PostgreSQL veritabanı. Performans için bir Redis önbelleği de ekleyeceğiz.
1. Proje Yapısı:
Projeniz için bir dizin oluşturun, örneğin my-web-app. İçinde şunlar olacaktır:
my-web-app/
├── docker-compose.yml
├── nginx/
│ └── default.conf
└── html/
└── index.html
2. nginx/default.conf (Temel Nginx Yapılandırması):
Bu dosya Nginx'e statik dosyalarınızı nasıl sunacağını ve potansiyel olarak istekleri bir uygulama sunucusuna nasıl yönlendireceğini söyler (ancak basitlik için burada statik dosyalara odaklanacağız).
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
3. html/index.html (Web Sitesi İçeriğiniz):
Test etmek için basit bir HTML dosyası.
<!DOCTYPE html>
<html>
<head>
<title>Dockerize Edilmiş Siteme Hoş Geldiniz!</title>
</head>
<body>
<h1>Docker Compose'tan Merhaba!</h1>
<p>Bu site bir konteynerdeki Nginx tarafından sunulmaktadır.</p>
</body>
</html>
4. docker-compose.yml (Kurulumun Kalbi):
Bu dosya üç hizmetimizi tanımlar: Nginx, PostgreSQL ve Redis.
version: '3.8'
services:
webserver:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- db
- cache
networks:
- app-network
db:
image: postgres:14
environment:
POSTGRES_DB: mydatabase
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mysecretpassword
volumes:
- db_data:/var/lib/postgresql/data
networks:
- app-network
cache:
image: redis:latest
networks:
- app-network
networks:
app-network:
driver: bridge
volumes:
db_data:
docker-compose.yml Açıklaması:
webserverhizmeti: Resmi Nginx görüntüsünü kullanır. Ana makine bağlantı noktası 80'i konteyner bağlantı noktası 80'e eşler. Web sitesi içeriği için yerelhtmldizinimizi ve Nginx yapılandırması için özelnginx/default.confdosyamızı bağlar. Önemli olarak,dbvecachehizmetlerinedepends_onile bağlıdır, bu da bu hizmetlerin web sunucusundan önce başlatılması gerektiğini gösterir. Özelapp-networkağımıza bağlıdır.dbhizmeti: Resmi PostgreSQL görüntüsünü kullanır. Veritabanı oluşturma, kullanıcı ve şifre için temel ortam değişkenlerini ayarlarız.db_dataadında bir birim, konteyner kaldırılıp yeniden oluşturulsa bile veritabanı verilerinin kalıcı olmasını sağlamak için kullanılır. Ayrıcaapp-networkağına bağlanır.cachehizmeti: Resmi Redis görüntüsünü kullanır. Bu örnek için kalıcı veriye ihtiyaç duymayan basit bir hizmettir veapp-networkağına bağlanır.networks:app-networkadında tek bir köprü ağı tanımlarız. Bu, izolasyon ve iletişim için önemlidir. Varsayılan olarak Docker Compose bir ağ oluşturur, ancak bunu açıkça tanımlamak bize daha fazla kontrol ve netlik sağlar. Aynı özel ağdaki hizmetler, hizmet adlarını ana bilgisayar adları olarak kullanarak birbirleriyle iletişim kurabilir (örneğin, web sunucusulocalhost:5432veya yapılandırmaya ve bağlama bağlı olarakdb:5432üzerindendb'ye bağlanabilir).volumes:db_dataadlandırılmış birimini tanımlarız. Docker, bu birimlerin yaşam döngüsünü yönetir.
5. Yığınınızı Çalıştırma:
Terminalinizde proje dizininize (my-web-app/) gidin ve şunu çalıştırın:
docker compose up -d
docker compose: Docker Compose komutunu çağırır.up:docker-compose.ymldosyasında tanımlanan konteynerleri oluşturur ve başlatır.-d: Konteynerleri ayrılmış modda (arka planda) çalıştırır.
6. Doğrulama:
Web tarayıcınızı açın ve http://localhost adresine gidin. index.html dosyanızın içeriğini görmelisiniz.
Veritabanı ve önbelleğin çalıştığını görmek için konteynerleri inceleyebilirsiniz:
docker compose ps
Bu, webserver, db ve cache konteynerlerinizin durumunu gösterecektir.
7. Yığınınızı Durdurma:
İşiniz bittiğinde, konteynerleri, ağları ve birimleri durdurun ve kaldırın (isteğe bağlı):
docker compose down
Adlandırılmış birimleri de kaldırmak için (bu, veritabanı verilerinizi silecektir), şunu kullanın:
docker compose down -v
İzolasyon ve Tekrarlanabilirlik Uygulamada
İzolasyon:
Docker Compose birkaç yolla izolasyon sağlar:
- İşlem İzolasyonu: Her hizmet, kendi dosya sistemine, işlem alanına ve ağ arayüzlerine sahip kendi konteynerinde, ana makineden ve diğer konteynerlerden izole edilmiş olarak çalışır.
- Ağ İzolasyonu: Özel bir ağ (
app-network) tanımlayarak, hizmetlerin nasıl iletişim kuracağını kontrol ederiz. Varsayılan olarak, farklı ağlardaki konteynerler iletişim kuramaz. Aynı ağdaki hizmetler yalnızca açıkça izin verilirse veya bağlantı noktalarını açarlarsa iletişim kurabilir. Örneğimizde,webserverhizmet adlarını kullanarakdbvecachehizmetlerine ulaşabilir, ancak veritabanı ve önbellek bağlantı noktalarına dış erişim varsayılan olarak açık değildir, bu da güvenliği artırır. - Bağımlılık Yönetimi:
depends_on, bir hizmetin henüz başlamamış bir bağımlılığa bağlanmaya çalışması sorununu önleyerek başlatma sırasını yönetmeye yardımcı olur.
Tekrarlanabilirlik:
docker-compose.yml dosyası, uygulamanızın ortamı için tek doğruluk kaynağıdır. Docker ve Docker Compose yüklü olan herkes projenizi klonlayabilir, docker compose up -d komutunu çalıştırabilir ve aynı, çalışan bir ortama sahip olabilir. Bu, ortamın kendisinin sürüm kontrollü olmasını ve tutarlı bir şekilde dağıtılmasını sağlayarak "benim makinemde çalışıyor" sorununu ortadan kaldırır.
Gelişmiş Hususlar ve Uyarılar
depends_onvs. Hizmet Hazırlığı:depends_onyalnızca bir konteynerin başladığını garanti eder. Konteyner içindeki uygulamanın bağlantıları kabul etmeye hazır olduğunu garanti etmez. Veritabanları için bu yaygın bir sorundur. Uygulama kodunuzda sağlık kontrolleri veya yeniden deneme mekanizmaları uygulamanız veya giriş noktanız içindewait-for-it.shbetikleri gibi araçlar kullanmanız gerekebilir.- Üretim Dağıtımları: Docker Compose geliştirme ve hazırlık için harika olsa da, üretim için daha sağlam bir düzenleme isteyeceksiniz. Kubernetes veya Docker Swarm gibi araçlar, yük dengeleme, kendi kendini iyileştirme ve yuvarlanan güncellemeleri ele alarak konteynerleştirilmiş uygulamaları ölçekte yönetmek için tasarlanmıştır. Ancak, Docker Compose dosyaları genellikle bu daha gelişmiş düzenleyiciler için uyarlanabilir veya bir temel olarak kullanılabilir.
- Görüntü Yönetimi: Üretim için, öngörülebilir dağıtımlar sağlamak üzere belirli görüntü etiketleri (örneğin,
postgres:14.5) kullanmaklatestyerine en iyi uygulamadır. Uygulama kodunuz için Dockerfile'lar kullanarak kendi özel görüntülerinizi de oluşturabilirsiniz. - Güvenlik: Veritabanı şifreleri gibi hassas bilgilere her zaman dikkat edin. Ortam değişkenlerini kullanın ve
docker-compose.ymldosyasına doğrudan kodlamak yerine üretim ortamları için Docker sırları veya harici sır yönetimi araçlarını kullanmayı düşünün. - Kaynak Limitleri: Üretim için, bir hizmetin ana makinede bulunan tüm kaynakları tüketmesini önlemek üzere konteynerleriniz için kaynak limitleri (CPU, bellek) tanımlamak isteyeceksiniz.
- Ağ Karmaşıklığı: Uygulamanız büyüdükçe karmaşık ağ yapılandırmalarını yönetmek zorlayıcı olabilir. Docker'ın ağ yetenekleri güçlüdür ancak dikkatli planlama gerektirir.
Sonuç
Docker Compose, web uygulamalarını dağıtma ve yönetme şeklimizi dönüştürür. Tüm yığınınızı docker-compose.yml dosyasında bildirimsel olarak tanımlamanıza olanak tanıyarak, geliştirme ve dağıtım iş akışlarınıza benzersiz bir tutarlılık, izolasyon ve tekrarlanabilirlik getirir. Yalnızca uygulamanızı değil, tüm işletim ortamını paketleyerek "benim makinemde çalışıyor" sorununu doğrudan ele alır. Kişisel bir projeyi kuran tek bir geliştirici olun veya daha büyük bir ekibin parçası olun, Docker Compose'ta ustalaşmak daha güvenilir, sürdürülebilir ve verimli web barındırma çözümleri oluşturma yolunda kritik bir adımdır. Daha gelişmiş konteyner düzenleme teknolojilerini anlama konusunda sağlam bir temel oluşturur ve sonuçta daha sorunsuz geliştirme döngülerine ve daha sağlam üretim sistemlerine yol açar.