Docker Compose Nedir? Nasıl Kullanılır?

Berkehan Bendivar
6 min readDec 22, 2022

Merhabalar bugün sizlere Docker Compose’un ne olduğunu ve nasıl kullanılabileceğini anlatmak istiyorum. Bu yazı hem kendime not değeri taşıyor hemde bildiklerimi sizinle paylaşmak istedim.

Öncelikle belirtmek isterim. Docker, kendisinden istenilenleri yapabilmek için dört ana araca sahiptir. Bu yazım üzerinde Docker Compose’u anlatmaya çalışacağım.

  • Docker Engine (https://docs.docker.com/engine/)
  • Docker Compose (https://docs.docker.com/compose/overview/)
  • Docker Machine* (https://docs.docker.com/machine/overview/)
  • Docker Swarm (https://docs.docker.com/engine/swarm/)

Docker Compose Nedir?

Docker Compose, Docker daemon’ını kullanarak birden fazla container’ı yönetmek için kullanılan bir araçtır. Docker Compose dosyası, Docker Container’larının nasıl yapılandırılacağını ve nasıl birlikte çalıştırılacağını belirtir. Bu sayede, bir uygulamanız için gerekli olan tüm container’ları tek bir dosya aracılığıyla yönetebilirsiniz. docker-compose.yml, gerekli olan tüm servisleri tek bir yerden konfigüre etmemize ve hepsini tek bir komut ile oluşturup, çalıştırmamızı sağlar.

Örneğin, bir web uygulamasının çalışması için gerekli olan bir web sunucusu, bir veritabanı ve diğer hizmetler gibi Container’ları bir arada çalıştırabilir ve yönetebilirsiniz.

Öncelikle YAML Nedir ?

YAML (Yet Another Markup Language) aslında bir metin tabanlı veri serileştirme dilidir. YAML, sıkça bir çoklu platform ve dil arasında veri aktarımı için kullanılır ve genellikle yapılandırma dosyalarında kullanılır. YAML, okunabilirliği yüksek ve kolay anlaşılır bir sözdizimiye sahip olması nedeniyle sıkça tercih edilir aynı yazılımcıların JSON’ı sıkça kullandıkları gibi.

YAML dosyaları genellikle .yaml veya .yml uzantılarıyla kaydedilir ve bir dizi keyword/value çiftlerinden oluşur. Örneğin:

kisisel_bilgiler:
ad: Berkehan
soyad: Bendivar
meslek: Devops

İkinci bir örnekte ise şöyle olsun

alisveris:
meyve:
— elma
— armut
— karpuz
sebze:
— domates
— fasulye

Docker Compose CLI Nedir?

Bu CLI aracı, Docker Compose dosyasını kullanarak container’ları başlatmak, durdurmak ve yönetmek gibi işlemleri gerçekleştirmek için kullanılır.

Docker Compose CLI, aşağıdaki gibi çeşitli komutları destekler:

  • docker-compose up: Docker Compose dosyasında belirtilen container'ları başlatır.
  • docker-compose down: Docker Compose dosyasında belirtilen container'ları durdurur ve siler.
  • docker-compose ps: Docker Compose dosyasında belirtilen container'ların durumunu gösterir.
  • docker-compose exec: Docker Compose dosyasında belirtilen bir container'ın içinde bir komut çalıştırır.
  • docker-compose logs: Docker Compose dosyasında belirtilen container'ların log dosyalarını gösterir.

Bunlar sadece CLI dan bir kaç örnek. Docker Compose CLI çok daha fazla komut sunar.

Yukarıdaki kullanımlara ek olarak anlatmaya başlarsam;

docker-compose run

Docker Compose dosyasında belirtilen bir container’ın içinde bir komut çalıştırmak için kullanılır. Bu komut, container’ı önceden başlatmaz, ancak komut çalıştırıldıktan sonra container otomatik olarak durdurulur.

docker-compose run komutu şu şekilde kullanılır:

docker-compose run <service> <command>
  • <service>: Çalıştırılacak komutun çalıştırılacağı container'ın adıdır.
  • <command>: Container'ın içinde çalıştırılacak komuttur.

Örneğin, aşağıdaki komut bir web sunucusu olarak hizmet veren bir container’ın içinde ls komutunu çalıştırır:

docker-compose run web ls

Not: Eğer container zaten çalışıyorsa ve docker-compose run komutu kullanılırsa, komut container'ın içinde çalıştırılır ve container durdurulmaz. Bu durumda, docker-compose exec komutunu kullanarak container'ın içinde komut çalıştırabilirsiniz.

docker-compose start

Docker Compose dosyasında belirtilen bir veya birden fazla container’ı başlatmak için kullanılır. Bu komut, container’ların zaten çalıştırılmış olması durumunda bir hata vermez; ancak container zaten çalışıyorsa, bir hata mesajı döndürür ve hiçbir işlem yapılmaz.

docker-compose start komutu şu şekilde kullanılır:

docker-compose start <service>

Örnek olarak tüm Container’ları başlatmak istersek aşaıdaki komutu kullanabiliriz:

docker-compose start

İkinci bir örnek ile bir hizmeti başlatmak istersek:

docker-compose start db

“docker-compose.yml” Dosyasının Yapısı ve Konfigürasyonları

Uzantısından da belli olacağı gibi docker compose yaml formatındadır. YAML, JSON ve XML tarzında bir data serializasyon formatıdır.

Docker Compose yapısının en temel üç ana bölümününde Service, Volume ve Network konfigürasyonudur. (Bu özellikler versiyon 2 ye aittir.)

Service Konfigürasyonu

Bir docker compose yazarken service konfigurasyonu service: ile belirtilir. Çalışan ve çalışacak olan her bir servisin tanımı Container’ların detaylarını belirler.

build

Belirtilen service’in hangi Dockerfile a göre build edileceği bu tag ile konfigüre edilir.

build: ./NewApp

Bu örnekte sadece build’de kullanılacak Dockerfile‘ın relatif path’inin verilmesi yeterlidir. NewApp dizininde bir dockerfile olmalıdır.

build:
context: ./NewApp
dockerfile: Dockerfile-NewApp

Yukarıdaki örnekte ise dockerfile build context ile yine relatif olarak Dockerfile’ın bulunduğu path yazılır. “dockerfile” kısmında ise Dockerfile dosyasının adı yazılır.

command

Belirtilen servis için kullanılan Image’ın sağladığı komuttan farklı bir komut kullanılmak istendiğinde bu konfigürasyon komutundan faydalanılır.

command: ping -c 4 www.google.com

container_name

Adından da anlaşılacağı şekilde Container’ın adını belirtiyor. Basit senaryolarda yazılmaya gerek olmaz ama karmaşık senaryo yazılıyor ise çok işe yarayan bir parametredir.

container_name: new-container

depends_on

Servislerin birbirleri ile olan ilişkileri bu parametre ile belirlenir. docker-compose up birden fazla service tanımının olduğu compose dosyalarındaki servisleri birbirlerine olan bağımlılıklarına göre sırası ile başlatır. Bu parametre de servis içinde servisi tetikler aslında. Ama burada şuna dikkat etmek lazım burada rabbitmq-service ve redis-service birbirinin ayağa kalkmasını beklemeksizin ayağa kalkar. Eğer birbirlerini bekleyip ayağa kalkmasını istiyorsanız bunun için 3. parti bir mekanizmaya ihtiyacınız var.

Örnek olarak bakarsak;

version: '2'

services:
nginx-service:
build: WebSite
depends_on:
- rabbitmq-service

rabbitmq-service:
build: WebApp
depends_on:
- redis-service

redis-service:
image: redis

dns

Aslında adından da belli olacağı gibi service üzerinden oluşturulacak Container’lar tarafından kullanılacak ddns veya sunucuları bu komut ile belirleyebiliriz.

environment

En ama en sevdiğim ve kullandığım parametredir kendisi. Service’ten oluşturulacak Container’lara Environment Variable eklemenize yarıyor.

environment:
- MODE=PROD
- DEBUG=true
- PASSWORD=secret

expose

Container’lar arasında port açmaya yarayan bir arkadaştır kendileri severiz. Bu aslında Dockerfile üzerindeki EXPOSE komutu ile aynı işe yarar.

expose:
- "1453"

extra_hosts

DNS sunucuları üzerinde tanımlı olmayan ama Container içerisinden erişilmesini istediğiniz IP adreslerinin Container’lar üzerindeki hosts dosyasına yazılması için kullanılan bir parametredir.

extra_hosts:
- "local.server:10.10.8.24"

image

Service üzerinden oluşturulacak Container’ların başlangıç Image’ını belirler.

image: nginx

networks

Service üzerinden oluşturulacak Container’ların dahil olacağı Network’leri belirlemeye yardımcı olur.

new-secret-service:
networks:
- nosql-network

ports

Container’lar dan Host’a map’lenecek portları belirler.

ports:
- "1453:1453"

volumes

Bu aslında beni 1–2 ay uğraştıran hatta deliye çeviren ama sonrasında kullanmaya başlayınca bir çok sorunumu çözen bir arkadaştır. Bu arkadaş ile tanışmadan önce Dockerfile üzerinde mount komutu ile işimi çözmeye çalışıyordum. Bu arkadaş 3 farklı şekilde kullanılabiliyor.

1 — Benim en çok kullandığım: Host üzerindeki bir klasörün Container’a mount edilmesi.

services:
new-service:
volumes:
- /Users/berkehan/Desktop/evraklar:/var/lib/app/evraklar

Burada “/Users/berkehan/Desktop/evraklar” dizin verilerek evraklar klasörünün /var/lib/app/evraklar klasörüne mount edilmiştir.

2 — Container üzerinde volume yaratılması

Container durdurulduktan sonra manuel şekilde silinmedikçe ulaşılabilecek bir Volume yaratmak için aşağıdaki örnek kullanılabilir.

services:
new-service:
volumes:
- /var/lib/app

3 — Bu da aslında Volumes konfigürasyonunda tanımlanan bir Volume’un Container tarafından görünmesini sağlar.

 services:
new-service:
volumes:
- my-volume:/var/lib/app

volumes:
new-my-volume:
driver: local

Eğer Rancher benzeri bir tool kullanıyorsanız onun yardımı ile de bu işlemi yapabilirsiniz.

Ben ilk etapta Volume için Dockerfile ile yürümüştüm ama Rancher ile bu işlemin deneme sürüşünü yapmıştım. Bir çok yöntemi var aslında nasıl kullanılacağı sizin tercihinize bağlı.

Evet son sözlere gelirsek bu yazımda hem kendime not düştüm hemde sizlere bildiklerimiz anlatmak istedim. Docker hayatıma girdiği zaman hayatıma renk gelmişti bir linux aşığı olarak bu tarz şeyler benim ilgimi çok çekiyor. Bu sıralar Docker’a dair bir çok yazı paylaşmayı düşünüyorum.

Sürçülisan ettiysem affola. Herkese iyi kodlar diliyorum.

--

--