Docker Compose ile Çok Kapsayıcılı Uygulamaları Çalıştırma Rehberi
Günümüzün modern uygulama mimarileri, genellikle birden fazla bileşenin bir araya gelmesiyle oluşur. Bir web uygulaması, bir veritabanı, bir önbellek servisi veya bir mesaj kuyruğu gibi farklı servislerin birlikte çalışması gerektiğinde, bu bileşenleri yönetmek karmaşık bir hal alabilir. İşte tam da bu noktada Docker Compose devreye girerek, çok kapsayıcılı uygulamaların tanımlanmasını, çalıştırılmasını ve yönetilmesini basitleştiren güçlü bir araç sunar. Bu makalede, Docker Compose’un ne olduğunu, nasıl kurulduğunu ve çok kapsayıcılı uygulamaları onunla nasıl kolayca çalıştıracağınızı adım adım inceleyeceğiz.
Docker Compose Nedir ve Neden Kullanmalıyız?
Docker Compose, birden fazla Docker kapsayıcısını içeren uygulamaları tanımlamak ve çalıştırmak için kullanılan bir araçtır. Tek bir YAML dosyası kullanarak uygulamanızın tüm servislerini, ağlarını ve birimlerini yapılandırabilir, ardından tek bir komutla tüm uygulamayı ayağa kaldırabilirsiniz. Bu, geliştirme, test ve hatta küçük ölçekli üretim ortamlarında büyük kolaylık sağlar.
Docker ve Kapsayıcılaştırma Temelleri
Docker, uygulamaları ve bağımlılıklarını izole edilmiş, taşınabilir birimler olan kapsayıcılar (containers) içinde paketlemeyi sağlayan bir platformdur. Her kapsayıcı, uygulamanın çalışması için gereken her şeyi (kod, çalışma zamanı, sistem araçları, kütüphaneler vb.) içerir. Bu sayede “benim makinemde çalışıyordu” sorunları ortadan kalkar ve uygulamalar farklı ortamlarda tutarlı bir şekilde çalışır. Dockerfile ile kapsayıcı imajları oluşturulur, bu imajlardan da kapsayıcılar çalıştırılır.
Çok Kapsayıcılı Uygulamaların Zorlukları
Tek bir kapsayıcıyı yönetmek nispeten kolay olsa da, birbiriyle etkileşimde olan birden fazla kapsayıcıyı (örneğin, bir web sunucusu ve bir veritabanı) manuel olarak yönetmek karmaşık ve hataya açık olabilir. Her bir kapsayıcıyı ayrı ayrı başlatmak, ağlarını yapılandırmak, bağımlılıkları yönetmek ve doğru sırada çalıştırmak zaman alıcıdır. Bu durum, özellikle mikroservis mimarileri benimsendiğinde veya geliştirme ortamlarında hızlı iterasyonlar gerektiğinde büyük bir engel teşkil eder.
Docker Compose’un Avantajları
Docker Compose, bu zorlukları aşmak için tasarlanmıştır. Temel avantajları şunlardır:
- Basit Tanımlama: Tüm uygulama yığını tek bir
docker-compose.ymldosyası ile tanımlanır. - Kolay Yönetim: Tek bir komutla tüm uygulamayı başlatma, durdurma ve yeniden oluşturma imkanı sunar.
- İzolasyon ve Taşınabilirlik: Servisler birbirinden izole edilmiş kapsayıcılarda çalışır ve Compose dosyası ile her ortamda tutarlı bir şekilde dağıtılabilir.
- Hızlı Geliştirme Döngüsü: Değişiklikler yapıldığında uygulamayı hızlıca yeniden başlatma ve test etme olanağı sunar.
- Ağ Yönetimi: Servisler arasında otomatik ağ oluşturur ve DNS tabanlı servis keşfi sağlar.
Docker Compose Kurulumu ve Temel Bileşenleri
Docker Compose’u kullanmaya başlamak oldukça basittir. Genellikle Docker Desktop ile birlikte gelir veya ayrı olarak kurulabilir. Temel olarak, uygulamanızın yapılandırmasını tanımlayan docker-compose.yml dosyasına odaklanacağız.
Docker Compose Kurulumu
Eğer Docker Desktop kullanıyorsanız (Windows veya macOS), Docker Compose genellikle otomatik olarak kurulmuş olacaktır. Linux kullanıcıları için ise genellikle aşağıdaki komutlarla kurulum yapılabilir:
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
Kurulumu doğrulamak için terminalde docker compose version komutunu çalıştırabilirsiniz.
docker-compose.yml Dosyası: Kalp Atışı
docker-compose.yml dosyası, uygulamanızın kalbidir. Bu YAML dosyası, uygulamanızdaki her bir servisi, bu servislerin nasıl oluşturulacağını (bir Dockerfile'dan veya bir imajdan), hangi portları kullanacağını, hangi ağlara bağlanacağını ve hangi birimleri (volumes) kullanacağını tanımlar.
Örnek bir docker-compose.yml yapısı:
version: '3.8' # Compose dosyasının versiyonu
services:
web: # Servis adı
build: . # Mevcut dizindeki Dockerfile'dan imaj oluştur
ports:
- "80:80" # Host portu:Container portu
depends_on:
- db # db servisine bağımlılık
db: # İkinci servis adı
image: postgres:13 # Docker Hub'dan imaj kullan
environment:
POSTGRES_DB: mydatabase
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- db-data:/var/lib/postgresql/data # Veri kalıcılığı için birim
volumes:
db-data: # Tanımlanmış birim
Servisler, Ağlar ve Birimler
- Servisler (Services): Uygulamanızın her bir bileşenini temsil eder (örneğin,
websunucusu,dbveritabanı). Her servis, bir Docker imajından veya bir Dockerfile'dan oluşturulur. - Ağlar (Networks): Docker Compose, servisler arasında iletişimi sağlamak için varsayılan olarak bir köprü ağı (bridge network) oluşturur. Servisler, bu ağ içinde birbirlerinin isimleriyle erişebilirler. İsterseniz özel ağlar da tanımlayabilirsiniz.
- Birimler (Volumes): Kapsayıcılar silindiğinde bile verilerin kalıcı olmasını sağlar. Veritabanları gibi durumlu uygulamalar için kritik öneme sahiptir.
db-data:/var/lib/postgresql/dataörneğinde,db-dataisimli bir Docker birimi, PostgreSQL kapsayıcısının veri dizinine bağlanır.
Basit Bir Çok Kapsayıcılı Uygulama Oluşturma (Örnek)
Şimdi, basit bir Python Flask web uygulaması ve bir PostgreSQL veritabanından oluşan çok kapsayıcılı bir uygulama oluşturalım.
Uygulama Senaryosu: Web Uygulaması ve Veritabanı
Senaryomuzda, kullanıcıların ziyaret sayısını kaydeden basit bir Flask uygulaması olacak. Bu uygulama, verilerini bir PostgreSQL veritabanında saklayacak.
Dockerfile Oluşturma
İlk olarak, Flask uygulamamız için bir Dockerfile oluşturalım. Uygulama kodumuz app.py ve bağımlılıklarımız requirements.txt dosyalarında olacak.
app.py:
from flask import Flask
import psycopg2
import os
app = Flask(__name__)
# Veritabanı bağlantı bilgileri
DB_HOST = os.environ.get('DB_HOST', 'db')
DB_NAME = os.environ.get('POSTGRES_DB', 'mydatabase')
DB_USER = os.environ.get('POSTGRES_USER', 'user')
DB_PASSWORD = os.environ.get('POSTGRES_PASSWORD', 'password')
def get_db_connection():
conn = psycopg2.connect(
host=DB_HOST,
database=DB_NAME,
user=DB_USER,
password=DB_PASSWORD
)
return conn
@app.route('/')
def hello():
conn = get_db_connection()
cur = conn.cursor()
cur.execute('CREATE TABLE IF NOT EXISTS visits (id SERIAL PRIMARY KEY, count INTEGER);')
cur.execute('INSERT INTO visits (count) VALUES (1);')
cur.execute('SELECT SUM(count) FROM visits;')
total_visits = cur.fetchone()[0]
conn.commit()
cur.close()
conn.close()
return f"Bu sayfayı ziyaret eden toplam kişi sayısı: {total_visits}"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
requirements.txt:
Flask
psycopg2-binary
Dockerfile:
FROM python:3.9-slim-buster
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]
docker-compose.yml Dosyasını Yazma
Şimdi, web (Flask uygulaması) ve db (PostgreSQL) servislerini tanımlayan docker-compose.yml dosyasını oluşturalım:
version: '3.8'
services:
web:
build: .
ports:
- "5000:5000"
environment:
# Ortam değişkenleri ile veritabanı bağlantı bilgileri sağlanır
DB_HOST: db # Servis adı üzerinden erişim
POSTGRES_DB: mydatabase
POSTGRES_USER: user
POSTGRES_PASSWORD: password
depends_on:
- db # 'db' servisi başlamadan 'web' servisi başlamaz
volumes:
- ./app:/app # Geliştirme için kod senkronizasyonu
db:
image: postgres:13
environment:
POSTGRES_DB: mydatabase
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- db_data:/var/lib/postgresql/data # Veri kalıcılığı için birim
volumes:
db_data: # Tanımlanmış birim
Bu yapılandırma ile:
* web servisi, mevcut dizindeki Dockerfile'dan oluşturulur.
* db servisi, postgres:13 imajından çekilir.
* web servisi, db servisine DB_HOST: db ile erişebilir çünkü aynı ağ üzerindeler ve Compose otomatik DNS sağlar.
* depends_on: - db ile web servisi başlamadan önce db servisinin başlatılması sağlanır.
* db_data birimi, PostgreSQL verilerinin kalıcı olmasını sağlar.
Docker Compose Komutları ve Yönetimi
docker-compose.yml dosyamızı oluşturduktan sonra, uygulamamızı yönetmek için birkaç temel Docker Compose komutu bilmemiz gerekir.
Uygulamayı Başlatma ve Durdurma
Uygulamayı başlatmak için, docker-compose.yml dosyasının bulunduğu dizinde aşağıdaki komutu çalıştırın:
docker compose up -d
* up: Tüm servisleri oluşturur ve başlatır.
* -d (detach): Kapsayıcıları arka planda çalıştırır, terminali serbest bırakır.
Uygulamanın çalışıp çalışmadığını kontrol etmek için tarayıcınızdan http://localhost:5000 adresine gidebilirsiniz.
Uygulamayı durdurmak ve kapsayıcıları kaldırmak için:
docker compose down
* down: up ile başlatılan tüm servisleri durdurur ve kaldırır. Varsayılan olarak birimleri (volumes) kaldırmaz, bu sayede verileriniz güvende kalır. Birimleri de kaldırmak isterseniz docker compose down --volumes kullanabilirsiniz.
Servisleri Yönetme ve Güncelleme
* Servisleri Listeleme: Çalışan servisleri ve durumlarını görmek için:
docker compose ps
* Belirli Bir Servisi Yeniden Başlatma: Sadece web servisini yeniden başlatmak için:
docker compose restart web
* Servisleri Yeniden Oluşturma: Eğer Dockerfile'ınızda veya docker-compose.yml dosyanızda değişiklik yaptıysanız, servisleri yeniden oluşturmanız gerekebilir:
docker compose up --build -d
--build bayrağı, imajların yeniden oluşturulmasını sağlar.
Logları Görüntüleme ve Sorun Giderme
Kapsayıcıların çıktılarını (loglarını) görmek, sorun giderme için çok önemlidir.
* Tüm servislerin loglarını görmek için:
docker compose logs
* Belirli bir servisin (örneğin web) loglarını takip etmek için:
docker compose logs -f web
-f (follow) bayrağı, yeni logları gerçek zamanlı olarak gösterir.
Gelişmiş Docker Compose Özellikleri
Docker Compose, basit uygulamaların ötesine geçerek daha karmaşık senaryolar için de güçlü özellikler sunar.
Ortam Değişkenleri ve .env Dosyaları
Hassas bilgileri (veritabanı şifreleri gibi) docker-compose.yml dosyasına doğrudan yazmak yerine ortam değişkenleri kullanmak daha güvenlidir. Docker Compose, .env dosyasını otomatik olarak okur ve burada tanımlanan değişkenleri docker-compose.yml dosyasında kullanmanıza olanak tanır.
.env dosyası örneği:
POSTGRES_DB=myprod_db
POSTGRES_USER=prod_user
POSTGRES_PASSWORD=secure_password
docker-compose.yml dosyasında bu değişkenleri $VARIABLE_NAME veya ${VARIABLE_NAME} şeklinde kullanabilirsiniz:
db:
image: postgres:13
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
Bağımlılıklar ve Servis Sıralaması
depends_on anahtarı, servisler arasındaki başlangıç sırasını belirtir. Ancak, bu sadece kapsayıcıların başlatılma sırasını garanti eder, servisin tamamen hazır olmasını değil. Bir veritabanının başlatılması ve sorgu kabul etmeye başlaması zaman alabilir. Bu tür durumlarda, uygulamalarınızın veritabanına bağlanmadan önce bir "sağlık kontrolü" veya bekleme mekanizması uygulaması gerekebilir (örneğin, bir bekleme script'i kullanmak).
Ölçeklendirme ve Profil Kullanımı
* Ölçeklendirme: Bir servisin birden fazla kopyasını çalıştırmak için docker compose up komutuna --scale bayrağını ekleyebilirsiniz:
docker compose up --scale web=3 -d
Bu, web servisinin 3 kopyasını çalıştırır.
* Profiller (Profiles): Farklı ortamlar (geliştirme, test) veya özellikler için farklı servis setlerini tanımlamak için profilleri kullanabilirsiniz. Örneğin, geliştirme ortamında ek bir hata ayıklama servisi çalıştırmak isteyebilirsiniz.
version: '3.8'
services:
web:
# ...
db:
# ...
debug_tool:
profiles: ["dev"] # Sadece 'dev' profili aktifken çalışır
image: some_debug_image
# ...
debug_tool servisini çalıştırmak için:
docker compose --profile dev up -d
En İyi Uygulamalar ve İpuçları
Docker Compose'u verimli ve güvenli bir şekilde kullanmak için bazı en iyi uygulamaları takip etmek önemlidir.
Üretim Ortamında Dikkat Edilmesi Gerekenler
Docker Compose, geliştirme ve test ortamları için harika bir araç olsa da, büyük ölçekli üretim ortamları için genellikle Docker Swarm veya Kubernetes gibi orkestrasyon araçları tercih edilir. Ancak, küçük ve orta ölçekli uygulamalar için veya tek sunuculu dağıtımlarda Compose hala kullanılabilir. Üretimde kullanırken şunlara dikkat edin:
- Güvenlik: Hassas bilgileri
.envdosyalarıyla veya Docker Secret'lar ile yönetin. - Kalıcılık: Veri kalıcılığı için birimleri doğru şekilde yapılandırın ve yedeklemeyi unutmayın.
- Kaynak Yönetimi: Servisler için CPU ve bellek limitleri belirleyin (
deployanahtarı altında). - Sağlık Kontrolleri: Servislerin gerçekten hazır olup olmadığını kontrol etmek için sağlık kontrolleri ekleyin.
Güvenlik İpuçları
* Minimum Yetki Prensibi: Kapsayıcıları root kullanıcısı yerine mümkünse ayrıcalıksız bir kullanıcı ile çalıştırın.
* İmaj Güvenliği: Güvenilir ve güncel temel imajlar kullanın. Bilinen güvenlik açıklarını tarayan araçlar kullanın.
* Port Yönetimi: Sadece gerekli portları dışarıya açın.
* Ortam Değişkenleri: Hassas verileri docker-compose.yml içinde açıkça belirtmeyin, .env dosyaları veya daha iyisi Docker Secret'lar kullanın.
Versiyon Kontrolü ile Entegrasyon
docker-compose.yml dosyası ve ilgili Dockerfile'lar, uygulamanızın kod tabanının bir parçası olarak kabul edilmeli ve Git gibi bir versiyon kontrol sistemiyle yönetilmelidir. Bu, uygulamanızın farklı versiyonları arasında tutarlılık sağlar ve takım çalışmasını kolaylaştırır. .env dosyaları genellikle versiyon kontrolüne dahil edilmez, bunun yerine örnek bir .env.example dosyası sağlanır.
Sonuç
Docker Compose, çok kapsayıcılı uygulamaların geliştirme ve yönetim süreçlerini önemli ölçüde basitleştiren vazgeçilmez bir araçtır. Tek bir YAML dosyası ile karmaşık uygulama mimarilerini tanımlama, tek komutla tüm yığını başlatma ve kolayca yönetme yeteneği, geliştiricilere büyük esneklik ve verimlilik sağlar. Bu rehberde öğrendiğiniz temel bilgilerle, kendi çok kapsayıcılı Docker uygulamalarınızı başarıyla oluşturabilir ve yönetebilirsiniz. Docker Compose'u projelerinize entegre ederek, uygulama geliştirme süreçlerinizde zaman ve emekten tasarruf edin, daha tutarlı ve taşınabilir ortamlar yaratın.
Sık Sorulan Sorular (SSS)
- Docker Compose ile Dockerfile arasındaki fark nedir?
- Dockerfile, tek bir Docker imajının nasıl oluşturulacağını adım adım tanımlayan bir betiktir. Docker Compose ise, birden fazla Docker imajını (servisi) bir araya getirerek çok kapsayıcılı bir uygulamanın nasıl çalıştırılacağını (ağlar, birimler, bağımlılıklar vb.) tanımlayan bir YAML dosyasıdır.
- Docker Compose üretim ortamında kullanılabilir mi?
- Evet, küçük ve orta ölçekli uygulamalar veya tek sunuculu dağıtımlar için üretimde kullanılabilir. Ancak, yüksek kullanılabilirlik, otomatik ölçeklendirme ve karmaşık orkestrasyon gerektiren büyük ölçekli üretim ortamları için genellikle Docker Swarm veya Kubernetes gibi daha gelişmiş araçlar tercih edilir.
- Veri kalıcılığını Docker Compose ile nasıl sağlarım?
- Veri kalıcılığı için
volumesanahtarını kullanırsınız.docker-compose.ymldosyanızda adlandırılmış birimler (named volumes) tanımlayarak veya host makinenizdeki bir dizini kapsayıcıya bağlayarak (bind mounts) verilerin kapsayıcılar silinse bile korunmasını sağlayabilirsiniz. - Servisler arasında bağımlılıkları nasıl yönetirim?
depends_onanahtarını kullanarak servisler arasındaki başlangıç sırasını belirleyebilirsiniz. Ancak bu, sadece kapsayıcının başlatılmasını garanti eder, servisin tamamen hazır olmasını değil. Daha sağlam bağımlılık yönetimi için, uygulamanızın veritabanı gibi bağımlılıkların hazır olmasını bekleyen bir mekanizma (örneğin, bir başlangıç betiği) eklemeniz önerilir.- Farklı ortamlar için (geliştirme, üretim) farklı yapılandırmalarım varsa ne yapmalıyım?
- Bunun için birkaç yöntem vardır:
.envdosyaları: Ortam değişkenlerini.envdosyalarında tanımlayarak farklı değerler sağlayabilirsiniz.- Birden fazla Compose dosyası:
docker-compose.yml(temel yapılandırma) vedocker-compose.override.yml(ortama özgü eklemeler/geçersiz kılmalar) gibi dosyalar kullanabilirsiniz. Compose,upkomutunda otomatik olarak bu dosyaları birleştirir. - Profiller (Profiles):
profilesanahtarını kullanarak belirli servisleri sadece belirli profiller aktifken çalışacak şekilde tanımlayabilirsiniz.
