使用Spring Boot編寫了一個微服務后,如何將構建應用並打包成docker鏡像,推送到docker倉庫,以供測試環境測試。
docker-maven-plugin插件可以完成這項任務。
最近使用了docker-maven-plugin插件,想寫一篇關於使用總結的文章,但發現它在github上的README.md寫的很好了,決定對它翻譯一下。
docker-maven-plugin的Github地址:https://github.com/spotify/docker-maven-plugin
該插件是基於maven插件,用來構建docker鏡像,當然也可以通過在系統中配置Dockerfile的方式構建鏡像。
目的
你可以使用該插件在你的maven項目中創建一個Docker鏡像,比方說,build 過程可以為java服務輸出一個可以運行該服務的Docker鏡像。
步驟
dockerfile提供了兩種配置方式,一種是通過Dockerfile文件,一種是直接在pom.xml配置。
你可以直接在pom.xml文件中指定base image,entry point, cmd, maintainer 和files,而不用通過Dockerfile的方式。
當然通過pom.xml文件的方式支持一些簡單的命令,如果你需要VOLUMN
命令(或者其他pom.xml不支持使用的命令),還是需要通過將命令寫入Dockerfile,並通過在pom中配置dockerDirectory
來引入該Dockerfile
默認情況下,該插件通過訪問localhost:2375來連接本地docker,可以通過設置DOCKER_HOST 環境變量來連接docker.
DOCKER_HOST=tcp://<host>:2375
在POM中聲明構建信息
下面的代碼示例是創建了名為example
的新鏡像,將項目編譯的jar包拷貝到鏡像中,並設置了一個entrypoint
去運行這個jar,在下面的代碼中可以改變VERSION GOES HERE
改變插件的版本,目前最新的版本是1.0.0
<build> <plugins> ... <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>VERSION GOES HERE</version> <configuration> <imageName>example</imageName> <baseImage>java</baseImage> <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint> <!-- copy the service's jar file from target into the root directory of the image --> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> </configuration> </plugin> ... </plugins> </build>
參數解釋:
- imageName:鏡像的名稱,可以通過${project.groupId}/${project.artifactId}:${project.version} 動態制定鏡像名稱
當然也可以在前面加上鏡像地址,比如127.0.0.1:5000,以聲明將構建好的鏡像存儲在本地 - baseImage: 基礎鏡像,這里是相當於Dockerfile的FROM java
- resources 下的配置:構建時會生成docker文件夾,這里指生成文件夾的內容來源,包含了mvn clean package 之后的target的文件和生成的jar包。
使用Dockerfile
為了使用Dockerfile,必須在pom的文件中通過dockerDirectory
來指明Dockerfile文件的所在目錄。如果配置了dockerDirectory
,baseImage
,maintainer
,cmd
和entryPoint
配置將忽略。下面的配置會將dockerDirectory
的內容拷貝值${project.build.directory}/docker
,使用resouces
元素可以拷貝其他的文件,比如生成jar包文件。
<build> <plugins> ... <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>VERSION GOES HERE</version> <configuration> <imageName>example</imageName> <dockerDirectory>docker</dockerDirectory> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> </configuration> </plugin> ... </plugins> </build>
使用
按照上面的配置之后,可以使用如下命令生成一個鏡像
mvn clean package docker:build
將生成的鏡像推送到鏡像注冊中心,通過pushImage
標簽
mvn clean package docker:build -DpushImage
如果推送制定tags 的鏡像,可使用pushImageTag
標簽
mvn clean package docker:build -DpushImageTag
為了是的上述的命令執行成功,需要在pom中配置imageTag
,可以配置多個imageTag
<build> <plugins> ... <plugin> <configuration> ... <imageTags> <imageTag>${project.version}</imageTag> <imageTag>latest</imageTag> </imageTags> </configuration> </plugin> ... </plugins> </build>
如果你想強制docker在每次新的構建上覆蓋鏡像tags,可配置foreceTags
<build> <plugins> ... <plugin> <configuration> ... <!-- optionally overwrite tags every time image is built with docker:build --> <forceTags>true</forceTags> <imageTags> ... </imageTags> </configuration> </plugin> ... </plugins> </build>
也可以在構建的命令行上添加上鏡像tags:
mvn ... docker:build -DpushImageTags -DdockerImageTags=latest -DdockerImageTags=another-tag
綁定docker命令到maven phases
你可以將bind,tag&push 目標綁定到maven phases,這樣僅僅通過運行mvn deploy命令就能完成項目built,tagged,pushed。如果你有一個多模塊項目,當通過綁定,在父項目運行maven命令的同時,子模塊項目可以自動構建。鏡像
<plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>VERSION GOES HERE</version> <executions> <execution> <id>build-image</id> <phase>package</phase> <goals> <goal>build</goal> </goals> </execution> <execution> <id>tag-image</id> <phase>package</phase> <goals> <goal>tag</goal> </goals> <configuration> <image>my-image:${project.version}</image> <newName>registry.example.com/my-image:${project.version}</newName> </configuration> </execution> <execution> <id>push-image</id> <phase>deploy</phase> <goals> <goal>push</goal> </goals> <configuration> <imageName>registry.example.com/my-image:${project.version}</imageName> </configuration> </execution> </executions> </plugin>
可以通過一下命令跳過docker構建的階段
- DskipDockerBuild 跳過鏡像構建
- DskipDockerTag 跳過鏡像tag設置
- DskipDockerPush 跳過鏡像推送
- DskipDocker 跳過所有的鏡像構建目標
刪除一個名稱為foobar的鏡像,可以運行如下命令
mvn docker:removeImage -DimageName=foobar
獲取完成的配置選項列表,可運行如下命令:
mvn com.spotify:docker-maven-plugin:<version>:help -Ddetail=true
使用私有鏡像中心
為了將鏡像推送到私有的鏡像注冊中心,docker需要在鏡像tag之前用注冊中心的地址作為前綴。比如需要推送my-image
到registry.example.com
,那么這個鏡像需要命名為registry.example.com/my-image
最簡單的方法就是在<imageName>
中配置:
<plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <configuration> <imageName>registry.example.com/my-image</imageName> ...
這樣,當你通過命令docker:build -DpushImage
或者docker:push
推送鏡像時,docker引擎會將鏡像推送到registry.example.com.
當然你可以在docker:build命令中通過 docker:tag -DpushImage
對創建的鏡像加上私有鏡像注冊中心的地址,如不配置,則會推送到默認的鏡像中心,即Docker hub;你也可如下這樣配置:
<plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <configuration> <imageName>my-image</imageName> ... </configuration> <executions> <execution> <id>build-image</id> <phase>package</phase> <goals> <goal>build</goal> </goals> </execution> <execution> <id>tag-image</id> <phase>package</phase> <goals> <goal>tag</goal> </goals> <configuration> <image>my-image</image> <newName>registry.example.com/my-image</newName> </configuration> </execution> </executions> </plugin>
認證
支持三種認證方式:
讀取本地配置文件,自動認證
從1.0.0版本之后,docker-maven-plugin插件會自動讀取到docker-cli的認證配置,默認在~/.dockercfg
和~/.docker/config.json
,而無需額外的配置
GCR認證
如果本機配置DOCKER_GOOGLE_CREDENTIALS
的環境變量,則會使用GCR認證。
Server認證
也可以在maven的settings.xml配置認證信息:
<servers> <server> <id>docker-hub</id> <username>foo</username> <password>secret-password</password> <configuration> <email>foo@foo.bar</email> </configuration> </server> </servers>
在pom.xml則通過如下配置關聯上述server id
<plugin> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>VERSION GOES HERE</version> <configuration> [...] <serverId>docker-hub</serverId> <registryUrl>https://index.docker.io/v1/</registryUrl> </configuration> </plugin> </plugins>
以上三種配置方式中,通過讀取客戶端默認配置的優先級更高。
在server配置中加密密碼
為了不在配置文件中不暴露明文密碼,可以使用maven加密功能對密碼進行加密,通過{ }
方式都認為是被加密的密碼
<servers> <server> <id>docker-hub</id> <username>foo</username> <password>{gc4QPLrlgPwHZjAhPw8JPuGzaPitzuyjeBojwCz88j4=}</password> </server> </servers>
注意
構建的鏡像名稱不要含有SNAPSHOT
,因為鏡像名稱只允許 [a-z0-9-_.]
作者:billJiang
鏈接:https://www.jianshu.com/p/3b91b8958c3e