Docker Üzerinde Algoritma Kodu Çalıştırmak ve Docker Debug Mode
GÖRSELDEKI QR KODU KULLANARAK ILETISIM KANALLARIMA ULASABILIRSINIZ
Geçenlerde bir akşam vakti docker ile alakalı bir şeyi araştırırken aklıma “Acaba bir algoritmayı docker üzerinde çalıştırabilir miyim” diye bir soru geldi. Aslında olay şu olacak. Mesela bir sıralama algoritmasının kodunu yazıp bu kodu docker üzerinden çalıştıracağım fakat sıralanacak sayıları konsoldan ben gireceğim. Bunu nasıl yapacağımıza geçelim.
1.ADIM
Bubble Sort algoritması ile konsoldan girilen sayıları sıralayan bir algoritma yazalım.
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("How many enter number.?");
int numberCount = input.nextInt();
int[] arr = new int[numberCount];
for (int i = 0; i < arr.length; i++) {
System.out.println("Please enter " + (i+1) + ". number" );
arr[i] = input.nextInt();
}
System.out.println("Sorted Array");
System.out.println(bubbleSort(arr));
}
public static List<Integer> bubbleSort(int[] arr) {
int n = arr.length;
int temp;
for(int i=0; i < n; i++){
for(int j=1; j < (n-i); j++){
if(arr[j-1] > arr[j]){
temp = arr[j-1];
arr[j-1] = arr[j];
arr[j] = temp;
}
}
}
return Arrays.stream(arr)
.boxed()
.collect(Collectors.toList());
}
}
Bu haliyle uygulamamızı yazdık. bubbleSort methodundan geriye liste dönderdim çünkü main methodunda bir daha for ile uğraşmak istemedim.
Aşağıda ise aslında yazdığımız bu kodun çalışır halini görebiliriz.
2.ADIM
Şimdi kodumuzu dockerize etmemiz gerekecek. Bunun için bir tane Dockerfile yazmam lazım.
FROM openjdk:21
COPY target/sortalgorithmondocker-1.0-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
Şimdi tam bu noktada projemizin terminal ekranında kök dizinin içindeyken mvn package
komutunu çalıştırmamız lazım.
Tabi es geçmememiz gereken bir nokta şu. Docker file içerisindeki mavi yuvarlak içindeki yer, görselin sol tarafındaki siyah kutu ile isim olarak eşleşmeli.
FROM openjdk:21
Bu satır, Dockerfile’ın hangi temel image’dan başlayacağını belirtir. Burada openjdk:21
kullanılmış, yani OpenJDK'nin 21. sürümünü içeren resmi bir Java geliştirme kitini içeren bir Docker image’ı. Bu, Java uygulamalarını çalıştırmak için gereken tüm bağımlılıkları sağlar.
COPY target/sortalgorithmondocker-1.0-SNAPSHOT.jar app.jar
Bu satır, yerel dosya sisteminizdeki target/sortalgorithmondocker-1.0-SNAPSHOT.jar
adlı dosyayı Docker containerin içine app.jar
adı altında kopyalar. Genellikle bu .jar
dosyası, Java ile yazılmış ve Maven veya Gradle gibi bir araçla paketlenmiş bir uygulamanın derlenmiş halidir.
ENTRYPOINT ["java","-jar","/app.jar"]
Bu satır, Docker container’ı başlatıldığında çalıştırılacak komutu belirler. Burada java -jar /app.jar
komutu kullanılmış. Bu, app.jar
adındaki Java uygulamasını çalıştırır. ENTRYPOINT
komutu, containerin başlatılmasını takip eden varsayılan komutu belirler ve genellikle containerin amacına yönelik ana işlemi başlatmak için kullanılır.
3.ADIM
Oluşturduğumuz dockerfile üzerinden artık bir image oluşturmamız lazım.
docker image build -t container-name .
komutu bile bu işlemi yapabiliriz.
scripti çalıştırdığımız zaman yukarıdaki görsel ile birlikte image’ımız hazır oldu.
Docker Desktop üzerinde ise bubble-sort-docker adlı image’ımız çalıştı. Şimdi mavi yuvarlak içerisindeki run butonuna basarak neler olacağına bakalım.
How many enter number.? Yazısını yazdıktan sonra direkt olarak hata verdi. Çünkü bir parametre bekledi ve bu parametreyi bulamayınca bu hatayı fırlattı.
Peki bu kodu nasıl çalıştıracağız.?
docker run -it imageName
`şeklinde terminal üzerinden bu kodu çalıştıracağız.
- -it komutu -i ve -t komutlarının bir kombinasyonudur.
-i komutu
, containerin standart girişi ile etkileşimli bir bağlantı sağlar. Yani, container çalışırken kullanıcı girişini kabul eder. Örneğin, bir shell işlemi başlatıldığında kullanıcının terminalden komut girmesini sağlar.-t komutu
, container için bir pseudo-TTY (sanal terminal) aygıtı tahsis eder. Bu, containerin terminal gibi davranmasını ve terminal tabanlı uygulamaların (örneğin, Bash shell) düzgün bir şekilde çalışmasını sağlar.
Uygulamamızı yeniden terminal üzerinden çalıştırırsak;
Terminal üzerinde uygulamamız istediğimiz şekilde çalıştı. Peki docker logs’ta durumlar nedir.?
Docker logs’ta da istediğimiz değerleri gördük.
Peki bu uygulamayı debug modda nasıl çalıştırırım.?
1.ADIM
Bunun için öncelik olarak bilgisayarlarımızda bazı ayarlar yapmamız lazım. Ben mac kullandığım için buradaki adımları macbook’a göre yapacağız.
Bunu yapmamızın sebebi, aslında tamamen güvenlik önlemlerinden kaynaklı.
- Mac için; System Settings -> privacy and security -> Full Disk Access
Buraya kadar geldikten sonra, en aşağıdaki + butonu ile docker’ı ekleyip izin vermeniz lazım.
2.ADIM
Intellij IDE ekranında bazı ayarlamalar yapmamız lazım.
Kırmızı ile işaretlediğim yere tıklayıp en aşağıdaki Edit Configurations
seçeneğine tıklamamız lazım.
Buradaki kırmızı kutu içerisinden Remote JVM Debug
seçeneğini bulmamız lazım. Direkt olarak klavyeden yazıp bulabiliriz.
Kırmızı kutu içerisindeki konfigürasyonu almamız lazım. Ayrıca görselin yukarısında name kısmında yer alan yerede isteğimize göre bir isim verebiliriz.
3.ADIM
Şimdi 2. adımda kopyaladığımız konfigürasyonu kullanma zamanı. Dockerfile
dosyamıza gelip bu konfigürasyonu yapıştırıyoruz.
FROM openjdk:21
COPY target/sortalgorithmondocker-1.0-SNAPSHOT.jar app.jar
ENV JAVA_TOOL_OPTIONS -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
ENTRYPOINT ["java","-jar","/app.jar"]
4.ADIM
Artık projemizi test edebiliriz.
Bunun için öncelik olarak bu kodlama için oluşturduğum docker image’larını sileceğim. Sonrasında ise;
docker build -t docker-bubblesort:v001 .
yukarıdaki docker build komutu ile tekrardan build alıyıroum.
Akabinde ise;
docker run -it -p 5005:5005 --name=sort-docker docker-bubblesort:v001
Bu komutu çalıştırarak işlemimi gerçekleştireceğim. -p ile 5005 portunu export ettim çünkü debug mode 5005 portundan ayağa kalkıyor.
Artık docker üzerinde komutum çalıştı ve istediğim değerler ekrana geldi.
5.ADIM
Şimdi tam bu noktada Intellij IDE’ye gidip projemi debug modda çalıştırmam lazım.
Kırmızı yuvarlak içinde görüldüğü gibi Remote Conf ismiyle tanımladığım Remote JVM Mode seçili ve 2 tane de breakpoint attım. Artık terminal ekranından devam edebiliriz.
Görüldüğü üzere remote debug mod çalıştı. Ama bunu yapmadan önce container’ın çalışır olması lazım. Bu önemli bir detay. Yoksa buradaki kodumuz ayağa kalkmaz.
7 tane sayı girdik ve tam bu noktada intellij ide’de breakpointlerimize düştü.
Okuduğunuz için teşekkür ederim.
Projenin kaynak kodlarına buradan ulaşabilirsiniz.