# Spring Boot Docker ###### tags: `Tag(docker)` `Tag(Spring Boot)` ### 前文 這是一篇練習心得筆記 本來用tomcat+war檔包成docker([該篇筆記](https://hackmd.io/@CqRN13XlTXynDVuQ6clCkw/rydHC81Ot)),但同事說應該是用Spring Boot,所以找了相關資源,主要參考Vincent Zheng的系列文章,作者寫的內容讓我容易理解,超感恩~ - [【Spring Boot】第1課-從建立專案到啟動程式](https://chikuwa-tech-study.blogspot.com/2021/05/spring-boot-create-project.html) - [【Spring Boot】第2課-認識 RESTful API 的設計方式](https://chikuwa-tech-study.blogspot.com/2021/05/spring-boot-restful-api.html) - [【Spring Boot】第3課-在 Controller 實作 API(一)](https://chikuwa-tech-study.blogspot.com/2021/05/spring-boot-controller-1.html) - [【Spring Boot】第4課-在 Controller 實作 API(二)](https://chikuwa-tech-study.blogspot.com/2021/05/spring-boot-controller-2.html) 成功做出用IntellJ 產生Spring Boot 專案,並用postman測試 Restful API。就以這樣的服務,開始容器化。 ### 服務 必須強力稱讚, Spring initializr 是好物 [https://start.spring.io/](https://start.spring.io/) ![Spring initializr](https://i.imgur.com/V1xnRAg.png) 如上圖,我選用Maven Project, Java Language, SpringBoot 2.5.6, Packaging Jar, Java 8, Dependencies: Spring Web後按Generate,就下載了檔案 ![](https://i.imgur.com/SBCjhmh.png) 解開後,直接用IntellJ 新增專案的方式開啟這個目錄,選用Trust Project ,就自動下載相依套件。 依照第一課的做法就可以啟動服務, 接著實作第二課~第四課產生Restful API 實作的過程就不再贅述。 ![](https://i.imgur.com/LJY5j1A.png) 透過postman確實驗證可以呼叫 ex: GET ![](https://i.imgur.com/xvAQFGL.png) ex: POST ![](https://i.imgur.com/5lCjGKn.png) ### 容器化 新增一個目錄springdocker ``` springdocker ├── Dockerfile ├── docker-compose.yml └── helloSpring-0.0.1-SNAPSHOT.jar ``` - Dockerfile ``` From openjdk:8-jdk-alpine Label springboot_app_image:1 COPY helloSpring-0.0.1-SNAPSHOT.jar app.jar ENTRYPOINT ["java","-jar","/app.jar"] EXPOSE 8080 ``` - docker-compose.yml ``` version: '3.7' services: web: container_name: springboot_app build: . image: springboot_app_image ports: - 8080:8080 ``` - helloSpring-0.0.1-SNAPSHOT.jar 將Spring專案目錄下Target/helloSpring-0.0.1-SNAPSHOT.jar 複製到此。 建立 image 並啟動 container ``` docker-compose up -d ``` Docker Dashboard 啟動的 container 如下 ![](https://i.imgur.com/kPvGkXU.png) 透過Postman API可運作。 ### 優化在IntellJ 包裝docker image 並定義版號 雖然IntelJ有plug-in Docker, 但我覺得沒有必要,IntellJ已經結合terminal容易下命令。 在專案目錄下新增springdocker 並在該目錄下放置Dockerfile 與 docker-compose.yml, 增加一個 rundockerbuild.sh 專案結構如下圖 ![](https://i.imgur.com/KMoJwcs.png) - Dockerfile ``` FROM openjdk:8-jdk-alpine COPY helloSpring-*.jar app.jar ENTRYPOINT ["java","-jar","/app.jar"] EXPOSE 8080 ``` - docker-compose.yml ``` version: '3.7' services: web: # build: . # image: dancyu/springboot_app_image image: 192.168.64.6:5000/dancyu/springboot_app_image ports: - 8080:8080 ``` - rundockerbuild.sh ``` version=1.0.5-`date '+%Y%m%d%H%M'` echo $version rm -rf app.jar cp ../target/helloSpring-*.jar . docker build \ -t dancyu/springboot_app_image:${version} \ -t dancyu/springboot_app_image:latest \ -t 192.168.64.6:5000/dancyu/springboot_app_image:latest \ -t 192.168.64.6:5000/dancyu/springboot_app_image:${version} . docker push 192.168.64.6:5000/dancyu/springboot_app_image:${version} docker push 192.168.64.6:5000/dancyu/springboot_app_image:latest``` ``` 說明:因為在本機有swarm實作,定義private registry server在192.168.64.6:5000([可參考這篇](https://hackmd.io/@dancyu/BJNAUOdOY)),因此build時直接加上一組private registry tag,並利用shell在產生鏡像之後,直接push到private registry 執行時rundockerbuild.sh時如下 ![](https://i.imgur.com/H49JR2Y.png) - Application版號修改時,有兩個地方記得改 1. pom.xml ![](https://i.imgur.com/pe1Xh8S.png) 2. rundockerbuild.sh 的version --- ## 部署在swarm上 把1.0.5版在管理節點上執行前先調整docker-compose.yml ``` version: '3.7' services: web: # build: . # image: dancyu/springboot_app_image image: 192.168.64.6:5000/dancyu/springboot_app_image:1.0.5 ports: - 8080:8080 ``` 預設都是latest,看不出更版效果 部署指令: ``` sudo docker stack deploy --compose-file docker-compose.yml springdocker ``` ![](https://i.imgur.com/oikzdTU.png) 啟動後使用postman測試API,確認work.