Compose dosyası çoğu zaman elinizdeki en dürüst sistem tanımıdır. Dizüstü bilgisayarda, CI'da ve bazen canlı ortamda gerçekten ayağa kalkan odur. Ama aynı zamanda bir YAML duvarıdır ve yeni bir ekip arkadaşı yine de hangi servisin hangisiyle konuştuğunu sormak zorunda kalır.
Bu rehber, bir Compose dosyasını güvenebileceğiniz bir mimari diyagrama dönüştürüyor: Compose'un gerçekten çalıştırdığı dosyayı render edin, her anahtarı bir diyagram öğesine eşleyin, dosyanın ifade edemediği çağrıları ekleyin ve çizimi dosyayla senkron tutun. Sonunda ilk taslağı saniyeler içinde almak için Archboard'un ücretsiz aracını kullanıyoruz.
Örnek: küçük bir shop stack'i
Çizeceğimiz compose.yaml aşağıda. Kısa ama tipik tuzakların hepsini barındırıyor: iki ağa bağlı bir servis, yalnızca bir yapılandırma dosyasında var olan bir bağımlılık ve sadece geliştirmede kullanılan bir araç.
name: shop
services:
web:
image: nginx:1.27
ports:
- "8080:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- api
networks: [frontend]
api:
build: ./api
environment:
DATABASE_URL: postgres://shop:${POSTGRES_PASSWORD}@db:5432/shop
REDIS_URL: redis://cache:6379/0
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
networks: [frontend, backend]
worker:
build: ./api
command: ["node", "worker.js"]
environment:
DATABASE_URL: postgres://shop:${POSTGRES_PASSWORD}@db:5432/shop
REDIS_URL: redis://cache:6379/0
depends_on:
- db
deploy:
replicas: 2
networks: [backend]
db:
image: postgres:16
environment:
POSTGRES_USER: shop
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U shop"]
interval: 5s
networks: [backend]
cache:
image: redis:7
networks: [backend]
adminer:
image: adminer
ports:
- "8081:8080"
profiles: [debug]
networks: [backend]
volumes:
db-data:
networks:
frontend:
backend:
Adım 1: Compose'un gerçekte çalıştırdığı dosyayı render edin
Ekipler tek bir dosyayı nadiren yazıldığı gibi çalıştırır. Bir override dosyası port ekler, bir .env dosyası değişkenleri doldurur, extends ise başka bir servisten alan çeker. Çizmeden önce sonucu Compose'a sorun:
docker compose config > rendered.yaml
docker compose config override dosyalarını birleştirir, değişkenleri doldurur ve extends tanımlarını çözer; ardından Compose'un çalıştıracağı modeli yazdırır. Çizimi o an tesadüfen açık olan dosyaya göre değil, bu çıktıya göre yapın.
Bir uyarı: çıktı, .env içindeki gizli bilgiler dahil değişkenlerinizin gerçek değerlerini içerir. rendered.yaml dosyasını .env dosyasının kendisi gibi ele alın; commit etmeyin, paylaşmayın.
Adım 2: Compose anahtarlarını diyagram öğelerine eşleyin
Diyagramın büyük kısmı doğrudan dosyadan gelir:
| Compose anahtarı | Diyagram öğesi |
|---|---|
services.<name> |
Her servis için, anahtarındaki adı taşıyan bir kart |
image / build |
Kartın üzerinde: image tag'i ya da build bağlamı |
ports (8080:80) |
Kartın üzerinde ve dışarıdan gelen kenarda: :8080 → 80 |
deploy.replicas / scale |
Kartın üzerinde replika sayısı; fazladan kutu değil |
networks |
Her ağ için bir çerçeve; her servis ilk ağının çerçevesinde durur |
Adlı volumes |
Onu mount eden servislere bağlı bir volume düğümü |
secrets, configs |
Onları kullanan servislere bağlı, yalnızca adlarıyla gösterilen düğümler |
depends_on |
Başlatma sırası; kartın üzerine yazılır ya da kesikli kenarla çizilir |
profiles |
İsteğe bağlı servisler: dışarıda bırakın ya da isteğe bağlı olarak işaretleyin |
İki kural çizimi dürüst tutar. api gibi iki ağa katılan bir servis, bu ağlar arasındaki köprüdür; onu ilk ağının çerçevesinin kenarına yerleştirin ve bağlantılarının diğer ağa geçmesine izin verin. Replikalar ise bir sayıdır, üst üste dizilmiş kutular değil: worker ×2, beşe ölçeklediğinizde de doğru kalır.
Adım 3: Dosyanın göstermediği çağrıları ekleyin
Bu, araçların sizin yerinize yapamayacağı adımdır. depends_on başlatma sırasıyla ilgilidir: Compose, db servisini api servisinden önce başlatır ve condition: service_healthy varsa sağlık kontrolünün geçmesini bekler. Çalışma anında kimin kimi çağırdığı hakkında hiçbir şey söylemez.
Gerçek çağrılar üç yerde saklanır:
- Bağlantı dizeleri.
DATABASE_URLveREDIS_URLhost adlarını (db,cache) ve portları belirtir. Her biri bir kenardır. - Container'lara mount edilen yapılandırma dosyaları.
nginx.confdosyasındaproxy_pass http://api:3000;satırı var. Bu,webservisindenapiservisine giden kenardır ve Compose dosyasının dışında yaşar. - Kod. Bir servis, Compose'da tek satır olmadan başka bir servisi çağırabilir.
worker,REDIS_URLkullanıyor amacacheiçin birdepends_ontanımı yok. Redis geç başlarsa worker açılışta hata verir ve bu boşluğun ilk görünür olduğu yer diyagramdır.
Hızlı bir arama çoğunu bulur:
grep -rnE "://([^/@[:space:]]*@)?(api|web|db|cache)[:/]|proxy_pass" --include="*.conf" --include="*.yaml" --include="*.yml" --include="*.env" .
Ardından her servisin sahibiyle doğrulayın. Çalışma anı çağrılarını protokol ve portla etiketlenmiş kesintisiz kenarlar olarak çizin; depends_on bilgisini ise bir not ya da kesikli kenar olarak tutun ki kimse başlatma sırasını trafikle karıştırmasın.
Adım 4: Neyi dışarıda bırakacağınıza karar verin
Bir Compose dosyası, sistemle etrafındaki araçları bir arada barındırır. Genellikle şunları dışarıda bırakırsınız:
- Yalnızca geliştirme amaçlı servisler:
profilesarkasında duranadminer, mail catcher'lar ya da debug proxy'leri gibi. - Tek seferlik işler: migration ya da seed işleri gibi; diyagram dağıtımı anlatmıyorsa.
- Bind mount'lar: kaynak kod ve yapılandırma dosyaları için olanlar. Bir yapılandırma dosyasını yalnızca taşıdığı bağımlılık üzerinden gösterin; buradaki
nginx.confkaynaklıproxy_passkenarı gibi. - Ortam değişkeni değerleri. Değişken adları bir kenarı açıklayabilir; değerlerin yeri diyagram değil, secret deponuzdur.
Adım 5: Yerleşimi kurun
Trafiği soldan sağa yerleştirin: önce tarayıcı, sonra yayınlanan port, ardından onun arkasındaki servisler. Her ağı bir çerçeve olarak çizin; böylece ağlar arasında geçen bir çağrı kolayca fark edilir. Veri depolarını bir arada gruplayın ve volume'ları onları mount eden servisin altına koyun. Her kenarı protokol ve portla etiketleyin, örneğin HTTP :3000 ya da SQL :5432.
İlk taslağı ücretsiz araçla alın
Kartları elle çizmeniz gerekmez. Dosyayı (ya da render edilmiş çıktıyı; araç ortam değişkeni değerlerini okumaz) ücretsiz Docker Compose'dan diyagrama aracına yapıştırın. Görüntülemek için hesap gerekmez. Servisler image, port ve replika bilgileriyle kartlara dönüşür, ağlar çerçeve olur; adlı volume'lar, secret'lar ve config'ler onları kullanan servislere bağlanır, depends_on ise servisler arasındaki bağlantılara dönüşür.
Araç yalnızca dosyada yazanı çizer. Çalışma anı çağrılarını göstermez, ortam değişkeni değerlerini ya da env_file içeriğini okumaz, include ile eklenen dosyaları izlemez ve extends kullanan bir serviste yalnızca o serviste yazılı alanları çizer. 1. ve 3. adımların hâlâ önemli olmasının nedeni budur.
Ücretsiz bir hesapla sonucu Archboard'da yeni bir diyagram olarak açar, ardından 3. adımdaki çalışma anı kenarlarını ekler ve 4. adımdaki gürültüyü temizlersiniz. Bu düzenlemeden sonra shop stack'i şöyle görünüyor:
Diyagram içeriği
- Browser
- frontend
- backend
- web
- api
- cache
- db
- worker
- db-data
- HTTP :8080 → 80
- proxy_pass :3000
- SQL :5432
- RESP :6379
- jobs :6379
- /var/lib/postgresql/data
Kartlar Docker paketinden, tarayıcı Ağ paketinden geliyor; diyagramın tamamı da Free planın 15 diyagram düğümü sınırı içinde kalıyor. Container'lar, bir registry ve bir yük dengeleyici içeren başka bir Docker yerleşimi için Docker Runtime Mesh örneğine bakın.
Güncel tutun
Compose dosyasından çizilen bir diyagram, biri yeni bir servis eklediği gün eskir. Üç alışkanlık işe yarar:
- Pull request şablonuna bir satır ekleyin: "Bir servis, ağ, yayınlanan port ya da bağlantı dizesi mi ekleniyor? Diyagramı güncelleyin."
- İncelemelerde
docker compose configkomutunu yeniden çalıştırın ve servis listesini diyagramla karşılaştırın. - README'ye ekran görüntüsü yapıştırmak yerine canlı diyagramın bağlantısını koyun; böylece güncellenecek tek bir kopya olur.
Stack Kubernetes'e taşındığında aynı yöntem manifestlere de uygulanır; bkz. Kubernetes YAML'dan mimari diyagrama.
SSS
depends_on, bir servisin başka bir servisi çağırdığı anlamına mı gelir?
Hayır. Başlatma sırasını kontrol eder; condition: service_healthy ile bir sağlık kontrolünü de bekler. Çalışma anı çağrıları bağlantı dizelerinden, yapılandırma dosyalarından ve koddan gelir.
Birden fazla Compose dosyasını aynı anda diyagrama dökebilir miyim?
Önce docker compose config ile render edin; bu komut override dosyalarını tek bir modelde birleştirir. Ücretsiz araç her seferinde tek dosya okur.
Araç .env dosyamı okur mu?
Hayır. Değişkenler doldurulmaz: image: shop-api:${TAG} gibi değişkenle yazılmış bir image tag'i ya da port, yazıldığı gibi gösterilir; environment altındaki ve env_file içindeki değerler de okunmaz.
Her container için bir kutu mu çizmeliyim? Her servis için bir kart çizin ve replika sayısını üzerine yazın. Tek tek container'lar gelir ve gider; ekibin üzerine düşündüğü şey servistir.
compose.yaml dosyasını değiştirdiğimde diyagram güncellenir mi? Hayır. Diyagram bir başlangıç noktasıdır. Yukarıdaki alışkanlıklarla güncel tutun ya da araçla yeniden çizip çalışma anı kenarlarınızı yeni diyagrama aktarın.