Docker File Nedir ve Docker Image Nasıl Oluşturulur?
Docker nedir ve temel komutlar nelerdir? ve Docker volume mapping nedir ve temel komutlar#2 nelerdir? içeriklerinden sonra Dockerfile nedir ve docker image nasıl yaratabiliriz gibi konulara detaylı değinip çeşitli örnekler yapacağız.
Docker File Nedir?
Bir önceki içeriklerimizde official ve non-official image’ları Docker Hub’dan(remote docker registry) download edip kullanabildiğimizden çeşitli örneklerle bahsetmiştik. Peki ya kendimiz bir docker image oluşturmak istersek, bu durumda ne yapmalıyız? Sorumuzun cevabı:Dockerfile
DockerFile, temelde herhangi bir uzantısı/extension’ı olmayan bir dosyadır. Dockerfile sayesinde projemizin docker image’ini yaratabilir ve projemizi container olarak ayağa kaldırabiliriz.
Kendi oluşturduğumuz basit bir SpringBoot projesinin örnek Dockerfile’ı üzerinden daha detaylı anlatım gerçekleştirelim.
FROM adoptopenjdk/openjdk11
WORKDIR /app
EXPOSE 8080
ADD target/DockerizeSpringBootSample-1.0-SNAPSHOT.jar DockerizeSpringBootSample-1.0-SNAPSHOT.jar
ENTRYPOINT ["java", "-jar", "DockerizeSpringBootSample-1.0-SNAPSHOT.jar"]
FROM: Bu komut sayesinde base image’i referans alabilirsin şeklinde komut vermiş oluyoruz. Her Dockerfile’da en az 1 adet bu komutun olması gerekir. Bunu projemizi çalıştıracak komutları kullanmadan önce bir işletim sistemi kuruyormuşuz gibi düşünebiliriz.
Örneğin bilgisayarımızda java uygulaması çalıştırabilmek için en basitinden JRE’nin kurulu olması gerekir. İşte biz de aslında Dockerfile’da “FROM” komutuna baseimage vererek, bunu sağlamış oluyoruz.
WORKDIR: Docker container içerisinde bu komut ile dizin değiştirebiliriz.(cd komutunun karşılığı gibi düşünülebilir) WORKDIR’den sonra belirtilen path, docker container içerisinde yaratılır ve CLI’da aslında o path’e girmiş oluruz. Biz uygulamamızı “app” klasörü altına atıp, buradan çalıştırmak istiyoruz.
EXPOSE: Container çalıştığında hangi portu dinleyeceğini bu komut sayesinde belirtebiliriz.
ADD/COPY: WORKDIR komutu ile içine girdiğimiz dizine, ADD komutu ile executable proje dosyamızı(bu uygulama için jar dosyası) kopyalayabiliriz. ADD yerine COPY komutu da tercih edilebilir. 1. parametre olarak hali hazırda kopyalacak source file’ın nerede olduğunu, 2. parametre olarak ise docker container içerisinde yer alacak dizin ve dosya adını belirtiriz.
ENTRYPOINT/CMD: Container çalıştığı anda bu komuta parametre olarak spesifik komutlar verebilir ve container’ımız çalıştığı anda burada parametre olarak verilen tüm komutlar çalıştırılır. ENTRYPOINT yerine CMD komutunu da kullanabilirsiniz. Örnek kullanım:
ENTYPOINT [“java”, “-jar”,”DockerizeSpringBootSample-1.0-SNAPSHOT.jar”]
Projemizin Docker Image’ini Nasıl Oluşturabilir ve Container Olarak Nasıl Çalıştırabiliriz?
Adım adım ilerlememiz gerekirse, öncelikle ilk olarak docker image yaratmamız gerekir sonrasında ise bu image’i container olarak ayağa kaldırmamız gerekir.
Image yaratmak için aşağıdaki komutu kullanırız.
docker build . -t docker-spring-boot-sample:0.1
Docker image yaratmak için build komutunu kullanırız. Bu komut satırında belirtilen “.” işaretiyle, bulunulan dizindeki “dockerfile” dosyasını build edeceğimizi belirtiriz. “-t “ ise oluşturulacak image’e bir tag vermemizi sağlar. Eğer bu parametreyi kullanmazsak, docker engine bizim yerimize random bir tag atayacaktır. Bunu kullanmamızın nedeni; oluşturduğumuz image’i diğerlerinden kolaylıkla ayırt etmektir. “-t docker-spring-boot-sample:01” komutunda tag adını ve “:” işaretinden sonraysa image’imizin versiyonunu vermiş oluruz. Eğer biz bu versiyonu vermezsek, docker engine bu image için versiyonu “latest” olarak işaretleyecektir.
Docker Image Container Olarak Nasıl Çalıştırılır?
Yarattığımız image’i aşağıdaki komut sayesinde container olarak ayağa kaldırabiliriz.
docker run -d — name docker-spring-boot-sample -p 8080:8080 docker-spring-boot-sample
Yukarıdaki komutta belirtilen “run” sayesinde image’i çalıştır demiş oluruz. “-d” parametresi ile de bu container’ın detach mode’da çalıştırılmasını istediğimizi belirtiyoruz. Böylelikle log vs. görmeyeceğiz bu container tamamen arka planda çalışacaktır.
“ — name docker-spring-boot-sample” parametresiyle de container’ımıza docker engine tarafından otomatik atanacak ismi override ederek, kendi container’ımıza isim vermiş oluruz.(eğer bu parametreyi kullanmazsak, docker kendisi random bir name atayacaktır.)
“-p 8080:8080” parametresi ile de port binding işlemimizi gerçekleştiririz. Docker Host içerisinde spring boot projemiz 8080 portundan ayağa kalkıyor fakat biz direkt olarak bu porttan localhost üzerinden bu uygulamanın endpoint’lerine erişim sağlayamayız. Çünkü bu port container’ın docker host içerisindeki portudur. Bunu dışarı expose etmemiz gerekir. Bunun için de port binding yaparak yine aynı port üzerinden(8080 ya da daha farklı bir port numarasını da verilebilir), localhost üzerinden up durumundaki container’a erişerek uygulamamızın endpoint’lerinin ulaşılabilir olduğunu görmüş oluruz.
Docker Ignore Dosyası Nedir?
“.dockerignore” dosyasını “.gitignore” dosyasına benzetebiliriz. Eğer docker image’imizi build ederken, gereksiz dosyaları docker container’ına kopyalamak istemiyorsak “.dockerignore” dosyamızda bu dizinleri-dosyaları belirtebiliriz. Docker engine, image build ederken öncelikle “.dockerignore” dosyasını arar ve eğer ilgili dizinde bu dosyayı bulursa, içindeki dizin ve file’ların imajımıza kopyalanmasını önler.
Örnek bir .dockerignore dosyası yaratalım:
.idea/
*.iml
*.iws
target/
.sonar/
.sonarlint/
İçerikte geliştirdiğimiz basit spring boot projesine ve docker dosyalarına buradaki repo üzerinden erişebilir ve kendi local’inizde container olarak ayağa kaldırabilirsiniz.