Spring Boot serimizin 5. yazısına hoşgeldiniz 🙂
Bu yazımızda bir Spring Boot uygulamasının Docker container’ı haline getirilmesi ve deploy edilmesini işleyeceğiz. Aslında yapacağımız işlemler gayet basit. Eğer docker hakkında bilgi sahibi değilseniz kısaca ne olduğundan biraz bahsedeyim. Docker işletim sistemi seviyesinde sanallaştırma sağlayan bir konteyner yönetim aracı olarak tanımlanabilir. Yani bilgisayarınızda oluşturacağınız ve belirli amaçlar uğruna yapılandırılmış sanal makinelerdir. Ancak bildiğimiz standart sanal makinelerin aksine bir docker konteyneri oluşturmak birkaç saniyemizi alır. Birazdan hep birlikte bunu yapacağız.
Başlayalım
Öncelikle bu yazıya devam etmeden önce eğer docker sisteminizde yoksa öncelikle onu kurmanız gerekmekte. IDE olarak her zaman olduğu gibi IntelliJ kullanacağım. Şimdi IDE’miz ile yeni bir Spring projesi oluşturuyorum. Bağımlılık olarak Spring Web seçmemiz yeterli. Bu yazımızdan itibaren ek olarak Lombok kütüphanesini de seçeceğim. Lombok ile alakalı bu yazıyı okumanızı tavsiye ederim. Bağımlıklarımızı bu şekilde seçtikten sonra projemizi oluşturalım. JDK sürümü olarak ise 1.8 seçerek ilerliyorum.
pom.xml dosyamız ise bu şekilde:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.0</version> <relativePath/> </parent> <groupId>com.codingbytime</groupId> <artifactId>docker</artifactId> <version>0.0.1-SNAPSHOT</version> <name>docker</name> <description>Docker container project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Basit Bir Controller Oluşturalım
Basit derken cidden basit bir controller oluşturmayı hedefliyorum. DockerController adında yeni bir sınıf oluşturarak bu java dosyasının içerisine @GetMapping notasyonu ile bir String metodu yazacağım. Sınıfı ise @RestController streotype ile notasyonunu vereceğim. Controller sınıfımız bu şekilde olsun.
package com.codingbytime.docker; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class DockerController { @GetMapping("/") public String docker() { return "İlk Docker Uygulaması!"; } }
JAR Dosyamızı Oluşturalım
İlk yöntem terminalden bu kodu çalıştırmak :
mvn clean package spring-boot:repackage
İkinci yöntem ise IntelliJ IDEA üzerinden solda bulunan Maven sekmesinden, Lifecycle metodları içerisinde bulunan package’a çift tıklamanız.
Hangi yöntemle yaptığınız önemli değil. Sadece target klasörünün altında jar dosyasının oluşturulduğundan emin olmanız yeterli.
Deploy Ne Demek?
Deploy, yazılım geliştirme sürecinin önemli bir aşamasını ifade eden bir terimdir. Bu aşama, geliştirilen bir yazılım uygulamasının, geliştirme ve test aşamalarından sonra gerçek kullanıcılar veya sunucular üzerinde çalışabilecek hale getirilmesini içerir.
Yazılım geliştirme süreci boyunca, geliştiriciler uygulamalarını kendi yerel makinelerinde veya test sunucularında geliştirirler. Ancak, bu aşamada uygulama genellikle sınırlı bir kullanıcı kitlesi veya sınırlı bir test ortamı içinde çalışır. Gerçek kullanıcılar veya büyük ölçekli üretim sunucuları üzerinde çalışmaya başlamadan önce, uygulamanın deploy edilmesi gerekmektedir.
Sonuç olarak, deploy işlemi yazılım uygulamalarının kullanıcılar tarafından erişilebilir hale getirilmesini sağlar. Bu süreç, yazılım geliştirme sürecinin son aşamasıdır ve başarılı bir deploy, kullanıcıların güvenilir ve sorunsuz bir deneyim yaşamalarını sağlar.
Dockerfile Oluşturalım
Yazımızın temel amacı olaran Docker kısmına gelmiş bulunmaktayız. Belki de bu yazı boyunca yapacağımız en rahat iş bu bölüm olabilir. Docker file oluştururken dikkat etmemiz gereken bazı noktalar mevcut. Bunlardan ilki Dockerfile’ı oluşturduğumuz path. Dockerfile dosyamızı Spring projemizin root folder’ına koyuyoruz. Yani pom.xml ile aynı yerde durmalılar diyebiliriz. Gelelim Dockerfile dosyamızın içeriğine. Neyin ne olduğunu birazdan anlatacağım. Bunları Dockerfile adında bir dosya oluşturarak içerisine kaydedelim.
FROM openjdk:8-jdk-alpine ADD ./target/*.jar /usr/src/app.jar WORKDIR /usr/src ENTRYPOINT ["java","-jar", "app.jar"]
FROM ifadesi container’ımızın hangi docker image’ı ile çalışacağını ifade eder.
ADD ifadesi build edilen Spring projemizin jar dosyasını container içerisine kopyalar.
WORKDIR ifadesi container içerisinde ki folder’ımızı belirlemede kullanılır.
ENTRYPOINT ifadesi container çalıştığı anda execute edilecek komutu belirtir.
Dockerfile ile Build Alalım
docker build -t docker-spring .
Burada verdiğimiz docker-spring ismi oluşturacağımız docker image ismine denk gelmekte ve nokta ise bulunduğumuz konumdaki Dockerfile dosyanını kullanmak için.
docker run --name spring-docker-cont -p 8080:8080 docker-spring -d
Bu komut ile de docker-spring ismini vermiş olduğumuz docker image’ı ile, spring-docker-cont isminde yeni bir docker container’ı oluşturduk. -p 8080:8080 ifadesi ile de container içerisinde kullanılan 8080 portunu kendi bilgisayarımızdan da erişilebilir hale getirdik. Şimdi çıktılarımıza bir bakalım 🙂 (Ekrana sığması için biraz kırptım.)
$ codingbytime@asus run --name docker-spring-example -p 8080:8080 docker-spring . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.4.0) c.codingbytime.docker.DockerApplication : Starting DockerApplication v0.0.1-SNAPSHOT using Java 1.8.0_212 on d233f9e6b1d2 with PID 1 c.codingbytime.docker.DockerApplication : No active profile set, falling back to default profiles: default o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) o.apache.catalina.core.StandardService : Starting service [Tomcat] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.39] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1447 ms o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' c.codingbytime.docker.DockerApplication : Started DockerApplication in 2.973 seconds (JVM running for 3.624) o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
Tarayıcımızdan da kontrollerimizi yapalım.