Docker Üzerine Genel Bakış-Kalıcı Veri (Volume, Bind Mount) ve Docker Compose Kullanımı

Serkan Bingöl
AWS Certified User Group Turkey
7 min readDec 27, 2018

Merhabalar bir önceki yazılarımızda docker imajları,containerları ve docker network ile ilgili teorik bilgiler verip bunlar üzerine pratik uygulamalar geliştirmeye çalıştık. Bu bölümde ise docker mimarisini kullanırken kalıcı veriyi nasıl oluşturabiliriz ve birbiri ile ilişkili docker containerlardan oluşan bir sistemi nasıl yönetebiliriz gibi konulara değineceğiz. Bu yazıda kullanılan tanımlamalar ve detaylı ön bilgi için Gökhan Şengün ’ün docker yazı dizisi 3. yazısını okumanızı tavsiye ederim.

Şu ana kadar yapmış olduğumuz tüm çalışmalarda bir çok docker image üzerinden bir çok container ile işlem gerçekleştirdik. Ve daha sonra ilgili kullanımları tamamlayıp bu containerları, docker engine üzerinden silerek işlemlerimizi tamamladık. Peki docker kullanarak geliştirmekte olduğumuz sistemlerde senaryo bu şekilde mi işliyor ?

Docker ile çalışırken veri tabanı kayıtları, üretilen log dosyaları, konfigürasyon dosyaları gibi bir çok yönetilmesi gereken işlemlerimiz olabilir. Her container ile çalışmamız bittikten sonra bu yapılan R/W işlemlerine ait verileri bir alanda tutmadı isek tüm işlemleri, ayarları tekrardan yapmak durumunda kalırdık.Dolayısı ile her defasında kullanılması gereken ihtiyacımız olan verilerin bir şekilde bir alanda tutuluyor olması gerekmektedir.

Burada aslında “VOLUME” ve “MOUNT” kavramları karşımıza çıkıyor.

Docker Volume Nedir ?

Her container çalıştırıldığı sırada , biz tanımlamasak bile kendine bir alan oluşturuyor ve işlem yaptığımız verileri bu oluşturduğu alan üzerinde tutuyor. Bu oluşturulan alana “docker volume” deniliyor. Docker containerın verileri için host üzerinde bir alan belirleyip bu alanı işaretliyor. Aşağıdaki örnek üzerine çalıştırdığımız docker uygulamaları ile birlikte volume kavramını biraz daha detaylı inceleyebiliriz.

Öncelikli olarak aslında tüm imajların oluşturulmasını sağlayan Dockerfile içinde kalıcı veriyi bir şekilde konumlandırmak için VOLUME tanımı yapılmıştır. Docker hub üzerinden imajların içinden Dockerfile ları inceleyerek bu tanımlamalara ulaşabiliriz.

Aşağıdaki resimde docker hub üzerinden offical postgre docker imajını seçtiğimizde Dockerfile kısmında dokümanı incelediğimizde aslında Dockerfile ile oluşturulan her bir postgre container’ında “/data” dizininin host’ta bir dizine eşitlendiğini görüyoruz. Bu işlemi Dockerfile üzerinde “VOLUME /va/lib/postgres/data” komut satırı ile sağlıyoruz

İndirmiş olduğumuz imajı önceki yazılarımızda üzerinden geçtiğimiz docker image inspect [imaj_ismi] komutu ile incelediğimizde oluşan çıktıda volume satırında bu eşleşmenin Dockerfile üzerinden verildiğini ve ilgili imajın artık container oluşturulurken bu alanı kullanması gerektiğini bildiğini görüyoruz.

Bu imaj üzerinden PostgreDB adını vererek bir imaj oluşturuyoruz. Ve docker container inspect [imaj_ismi] komutu ile oluşturduğumuz container içinde bir inceleme yapmayı planlıyoruz.

Devam eden satırlar üzerinde baktığımızda artık oluşan postgre containerımız üzerinde kalıcı veriyi tutmak üzere host üzerinde ilişkilendirilen alanı görmekteyiz.

Devam eden satırların üzerinde “Mounts” kısmı ile karşılaşıyoruz. Bu kısma yazının ilerleyen bölümlerinde biraz daha detaylı değinmiş olacağız. Ama aslında bu kısımda hangi alanları bu container üzerinde kullanma isteğimizi yani volumlerimizin detaylarını görebiliyoruz.

Oluşturmuş olduğumuz docker containerı stop hale getirdiğimizde docker volume ls komutu ile bu veri alanlarını inceleyebiliriz. docker volume inspect [volume_ismi] komutu ile istenilen volume için detaylara ulaşabiliriz.

Bu kısımda önemli bir husus olarak volume lar biz istemedikçe kalıcı olarak tutulmaktadır. Yani aslında containerı host üzerinden silsek bile bu container’ın kullandığı volume silinmez.

Bizler aslında bir çok docker container ile çalışmalarımızı sürdüreceğimizden bazı zamanlar oluşan volumlara ait benzersiz değerleri okumak zor olacaktır. Burada istenir ise container çalıştırılırken runtime üzerinde Dockerfile üzerinden belirtilmiş olan volume için bir isim ataması yapabiliriz. Bu işleme “Named Volume” işlemi denmektedir. Bu işlemi yapmak için ilgili çalıştırma komutumuz içine -v [takma isim]:[volume_dosya_yolu] kısmının eklenmesi yeterli olacaktır.

Aşağıdaki örnekte postgre imajından arkada çalışmaya devam eden (-d) , postgreDB adında (-name postgreDB) ve volume oluşturulurken postgre-db üzerinden oluşturulmasına (-v postgre-db:/var/lib/postgresql/data postgres) olanak tanıyan docker container run -d -name postgreDB -v postgre-db:/var/lib/postgresql/data postgres komutunu kullandık

Aşağıdaki resimde ise aynı named volume’ a bağlı 4 adet postgre containerı oluşturduğumuzda başka volumelar oluşturulmadığını görmekteyiz.

Docker Bind Mount Nedir ?

Daha önceden bahsettiğimiz “bind mount” kavramı aslında temel olarak Volume kavramının yetenekleri kısıtlanmış hali olarak tanımlanabilmektedir. Sadece runtime zamanında kullanılabilmektedir. Ve aslında host üzerinde bulunan bir alanın containera bağlanması anlamına gelmektedir. ( Volume kavramnda containerın host üzerindeki bir alana bağlanma yaklaşımı bulunmaktadır. )

Bu konu ile ilgili küçük bir örnek yapmamız gerekir ise daha önceden yapmış olduğumuz bir örnek üzerinden yararlanarak işlemi gerçekleştireceğiz.Örneğimizde offical docker nginx imajı üzerinden türetilen 2 adet docker container ile çalışacağız. Burada ikinci çalıştırdığımız container üzerinde default karşılama sayfasını container çalıştırılma zamanında host üzerinde bulunan başka bir dosya üzerinden yayınlayacağız.

Öncelikle olarak localhost üzerinden 8000 ve 8001 portlarından yayında olan herhangi bir uygulamamız bulunmamaktadır.

Offical nginx imajı üzerinden docker container run -d -p 8000:80 nginx komutu ile değişiklik olmayan nginx web yayınını 8000 portundan sağlıyoruz.Aynı komutu birde -v //C/Users/serkan.bingol/source/DockerRepos/nginx-html-test:/usr/share/nginx/html bloğunu ekleyerek çalıştırıyoruz.

Kısaca burada yapılan işlemi anlatmak gerekir ise host üzerinde bulunan C/Users/serkan.bingol/source/DockerRepos/nginx-html-test” dosya yolunda bulunan bir klasörümüzün içindeki index.html dosyasını runtime ile birlikte “usr/share/nginx/html” içine bağlayarak aslında host üzerinde bulunan bir dosyadan okuma gerçekleştirdik.

Oluşan çıktılara baktığımız takdirde aslında çalışma zamanında gerekli değişikliği yaparak host üzerinde bulunan bir dosyadan gerekli okuma işlemini tamamlayıp yayın sayfasını değiştirmeyi başardık.

Volume ve Bind Mount Kullanımı: https://1drv.ms/b/s!AskWoAU3NqUug_dZREqYA2cW4vu3VA

Docker Compose Nedir ?

Docker Compose , container içinde çalışabilen uygulamaların, tek bir komutla ayaklandırılıp durdurulabilmesine olanak sağlayan “yml” tabanlı bir dosyadır. “version”,”services”,”networks” ve “volumes” olarak tanımlanan 4 ana parçacıktan oluşur.

Version ile ilgili compose dosyasının sürümü , service ile yürütülmesi gereken servislerin tanımları , networks ile kullanılan subnet/gateway ve network tipi tanımları ve volumes ile veri yığını alanı için kullanılacak tanımlamalar belirlenir.

$ docker-compose up komutu ile gerekli dosya çalıştırılarak containerlar ayağa kaldırılır. $ docker-compose down ile sistem durdurulur. Aşağıdaki örnek üzerinde bir drupal yönetim sitesini ve buna bağlı veri tabanını docker compose üzerinden tanımlayarak çalıştıracağız.

Docker Compose Test Senaryosu

Test senaryosunun yönetimi VS Code üzerinde terminal olarak git bash kullanarak yapmak istiyorum. VS Code üzerinde terminal değişikliği yapmak adına “C:\Users\[Kullanici_Adi]\AppData\Roaming\Code\User\settings.json” dosyası içine aşağıdaki satırları ekleyerek istediğiniz terminal için istediğiniz satırı yorumdan çıkarak kullanabilirsiniz.

// Command Prompt
//"terminal.integrated.shell.windows": "C:\\Windows\\System32\\cmd.exe",
// PowerShell
//"terminal.integrated.shell.windows": "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
// Git Bash
//"terminal.integrated.shell.windows": "C:\\Program Files\\Git\\bin\\bash.exe"
// Bash on Ubuntu (on Windows)
//"terminal.integrated.shell.windows": "C:\\Windows\\System32\\bash.exe"

Ayrıca VS Code üzerinde extensions ile docker eklentisini indirerek yazım konusunda intellisense’den yararlanacağız.

Repolarım içinde bir Docker-Compose-1 dosyası açarak içine docker-compose.yml dosyası ekliyorum ve yukarıda bahsettiğimiz services ve volume tanımlamalarını yaparak dosyamı oluşturuyorum. Genel olarak services ile 2 adet imaj kullanacağımı belirtiyorum.

Services: altındaki drupal: ve postgre: alt nodları içinde kullanılacak containerlar için gerekli tanımlamaları yapıyorum.Alt node olan image: ile hangi image sürümünü kullanmamız gerektiğini tanımlıyoruz. Burada bir sürüm belirtilmediği için hem drupal hemde postgre için latest sürümler kullanılacak. volumes: alt node ‘unu kullanarak named volume’larımı oluşturuyorum. Burada postgre için extradan enviroment: node ile ön tanımlı bir password işlemi belirliyorum ayrıca drupal içinde ports: nodu üzerinden 8080 portunu dinleyerek içeride 80 portuna yönlendirme yaparak yayında olacağını belirtiyorum.

Tüm gerekli tanımlamaları bitirdikten sonra terminal üzerinden docker-compose up komutunu kullanarak containerları belirlediğimiz sırada çalıştırmayı sağlıyoruz.

Artık http://localhost:8080 üzerinden drupal içerik yönetimi sistemine ulaşabiliriz.

Gerekli adımları geçtikten sonra bizden hangi veritabanını kullanacağımıza dair bilgileri istiyor. Burada dikkat edilmesi gereken bir detay docker-compose up sırası ile drupal container’ını ve postgre container’ını ayaklandırdığı için ilgili veritabanı bağlantısını yapabiliyoruz.

Tüm kurulumları bitirdik ve artık drupal yönetim uygulamamızı ayaklandırdık.

Terminal üzerinden docker container ls -a komutu ile tüm containerlarımızı , docker volume ls ile oluşan named volumelarımızı kontrol ediyoruz. docker network ls ile network ayarlarımıza baktığımız takdirde aslında bir networ ayarlaması yapmasak bile arkada docker compose’un bizim için bu işi hallettiğini görebilmekteyiz.

Bu kısımda docker-compose down komutu ile tüm sistemimizi bir tek komut satırı sayesinde kapatabiliyoruz. Sistemi kontrol ederken docker volume ls komutunu çalıştırınca aslında tüm named volumlarımızın sistem üzerinden kaldırılmadığını görebilmekteyiz.

Eğer tüm volume’ları docker-compose ile kaldırmak istersek docker-compose down -v komutu ile bu işlemi gerçekleştirebiliriz.

Bir yazımızın daha sonuna geldiğimizde artık development ortamında kullanılmak üzere yönetilebilir bir docker mimarisi için gereken alt bileşenleri uygulamalı olarak öğrenmiş bulunmaktayız.

Bir daha ki yazımızda görüşmek dileği ile.

Uygulama Dosyaları : https://1drv.ms/u/s!AskWoAU3NqUug_d4o77Z0viypqdN4Q

Test Senaryosu aşamaları :https://1drv.ms/b/s!AskWoAU3NqUug_dYbTe-3HN_WvFzOw

--

--

Serkan Bingöl
AWS Certified User Group Turkey

Muzur bir oğlan babası, hayvan sever, Harry Potter hayranı, bazen maceracı düz yazılımcı.