簡單的學習下怎麼在 Spring Boot 中使用 Docker 進行構建,發佈一個鏡像,如今咱們經過遠程的 docker api 構建鏡像,運行容器,發佈鏡像等操做。css
這裏只介紹兩種方式:java
開啓 docker api 遠程操做的功能,
例如,centos 7 中在 /usr/lib/systemd/system/docker.service
,文件中,修改 ExecStart
的參數:mysql
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
端口自定義設置便可。git
重載全部修改過的配置文件,而且重啓 docker,github
systemctl daemon-reload systemctl restart docker.service
須要注意的是,因爲沒有密碼登錄任何權限驗證,外網或者生產環境須要上證書使用。web
這種方式其實很是簡單,就是須要懂得 docker 命令,才能操做。spring
通過上面開啓 Docker Api 後,咱們可使用網絡環境操做 Docker 引擎了。sql
新建 Dockerfile
構建鏡像文件,新建立一個文件夾,專門放構建鏡像須要的文件,我建立的是 /src/docker/
docker
FROM java:8
EXPOSE 8080
VOLUME /tmp
ADD springboot-docker.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
執行 maven 命令 ,將項目打包 mvn clean package --DskipTests
,而後將打好的 jar 包,也放入到 Dockerfile
項目目錄中。shell
而後進入 src/docker
目錄下執行 :
docker -H tcp://xxx.xxx.xxx.xxx:2375 build -t test .
開始構建鏡像:
Sending build context to Docker daemon 31.74MB
Step 1/5 : FROM java:8
---> d23bdf5b1b1b
Step 2/5 : EXPOSE 8080
---> Using cache
---> 060a43a42146
Step 3/5 : VOLUME /tmp
---> Using cache
---> b4f88fde6181
Step 4/5 : ADD springboot-docker.jar app.jar
---> 3a40188825b0
Step 5/5 : ENTRYPOINT ["java","-jar","/app.jar"]
---> Running in ab093916fc4c
Removing intermediate container ab093916fc4c
---> 45a3966feb60
Successfully built 45a3966feb60
Successfully tagged test:latest
docker-maven-plugin
<!--打包docker插件相關參數的配置-->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.14</version>
<configuration>
<!--打包的鏡像名-->
<imageName>${project.groupId}/${project.artifactId}</imageName>
<!--Dockerfile文件位置,以項目的 root 目錄爲根節點,建議到單獨創建一個目錄-->
<dockerDirectory>./src/docker/</dockerDirectory>
<!--Docker 遠程的 API 地址及端口-->
<dockerHost>http://xxx.xxx.xxx.199:2375</dockerHost>
<imageTags>
<imageTag>latest</imageTag>
</imageTags>
<!--執行構建docker鏡像的時候須要哪些文件,springboot項目指定 打包好的jar 鏡像就好-->
<resources>
<resource>
<!--這裏指定的文件是target中的jar文件-->
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
須要跟pom.xml
上面配置的路徑保持一致,因此個人路徑是 ${baseProjectFolder}/src/docker
的文件夾下新建一個文件 Dockerfile
,添加構建 docker 相關命令參數:
FROM java:8
EXPOSE 8080
VOLUME /tmp
ADD springboot-docker.jar app.jar # 根據打包的jar 包文件名進行修改
ENTRYPOINT ["java","-jar","/app.jar"]
在應用的根目錄下執行命令(打包加 dokcer build):
$ mvn clean package docker:build -DskipTests
好比使用個人工程,進行打包後完成了 docker 的構建的信息:
[INFO] Building image com.wuwii/springboot-docker
Step 1/5 : FROM java:8
---> d23bdf5b1b1b
Step 2/5 : EXPOSE 8080
---> Running in b7936baae57f
Removing intermediate container b7936baae57f
---> 060a43a42146
Step 3/5 : VOLUME /tmp
---> Running in 65e2b8ac44d3
Removing intermediate container 65e2b8ac44d3
---> b4f88fde6181
Step 4/5 : ADD springboot-docker.jar app.jar
---> aa3762cda143
Step 5/5 : ENTRYPOINT ["java","-jar","/app.jar"]
---> Running in d9f5f63b9736
Removing intermediate container d9f5f63b9736
---> 622a7d1e315c
ProgressMessage{id=null, status=null, stream=null, error=null, progress=null, progressDetail=null}
Successfully built 622a7d1e315c
Successfully tagged com.wuwii/springboot-docker:latest
進入安裝 docker 的主機中,使用命令查看鏡像(IMAGE ID
和上面是一致的):
$ docker image ls com.wuwii/springboot-docker
REPOSITORY TAG IMAGE ID CREATED SIZE
com.wuwii/springboot-docker latest 622a7d1e315c 22 minutes ago 659MB
運行容器:
$ docker run -d -p 8080:8080 --name learn com.wuwii/springboot-docker
180fe4a7ddfc10c0cf2c37649ae1628e804564bfe1594ef05840e707801e6da3
監聽 8080 端口,測試是否成功。
通常的咱們的 WEB 項目會使用到不少外部工具,例如 Redis ,MYSQL, ES等,若是一個一個啓動搭建部署,太麻煩了,還要測試若是把這個一套環境拿到別的地方還能用嗎?
使用服務編排能夠避免這些坑。
加入咱們的項目中增長了 Mysql 的數據庫,在根目錄新建一個 docker-compose.yml
:
version: '3'
services:
web:
depends_on:
- db
ports:
- "8080:8080" # 建議加上引號,若是單獨兩位數的數字,可能出現解析問題
restart: always
# build:
# context: ./src/docker # Dockerfile 文件的目錄,能夠遠程地址,絕對 or 相對
# dockerfile: Dockerfile # 若是你的 Dockerfile 重命名了,須要指定
image: test:latest
environment:
DB_HOST: db:3306
DATABASE: learn
DB_USERNAME: root # 測試用下 root
DB_PASSWORD: 123456 # # 建議使用 secret
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: learn
MYSQL_USER: kronchan
MYSQL_PASSWORD: 123456
volumes:
db_data: # 使用的數據卷必須聲明
上面我使用的是前面已經構建好的鏡像,而後執行的編排,更好的是直接使用 build
讓它本身編排服務。
系統配置文件application.yml
使用缺省值的方式,不影響開發的使用:
spring:
datasource:
url: jdbc:mysql://${DB_HOST:localhost:3306}/${DATABASE:learn}?useSSL=false&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
username: ${DB_USERNAME:root}
password: ${DB_PASSWORD:123456}
driver-class-name: com.mysql.jdbc.Driver
jpa:
show-sql: true
database: mysql
hibernate:
ddl-auto: update
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL57Dialect # 方言根據 數據庫版本選擇吧
也可使用不一樣的 spring.profiles
指定不一樣的環境,在 docker-compose.yml
中覆蓋執行命令指定環境也是常見作法的:command: mvn clean spring-boot:run -Dspring-boot.run.profiles=xxx
最後啓動,在 docker-compose.yml
目錄下執行 : docker-compose up
關閉服務 docker-compose down
docker-compose 順序的問題,這個是開始學習編排的時候須要注意的問題,若是上面的服務編排中 mysql 啓動的慢, web 項目就會啓動失敗,它啓動的時候不知道被依賴的服務是否啓動完成,就會出現這樣的問題。
解決的辦法有如下幾種:
wait-for-it.sh
或者其餘shell
腳本將當前服務啓動阻塞,直到被依賴的服務加載完畢 wait-for-it
的github地址爲:wait-for-it