1 Star 0 Fork 0

凌宇柳州小分队 / spring-boot-docker-deploy

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
Apache-2.0

把 SpringBoot 应用打包成 Docker 镜像

在把应用打包成 Docker 镜像的时候,需要两个文件,一个是 SpringBoot 应用的打包文件,也就是一个可执行的 jar 文件,第二个是构建 Docker 镜像的文件 Dockerfile

通过 Dockerfile 中描述的信息,把 jar 文件加入到一个基础镜像中,然后重新打包成新的镜像,这个新的镜像就是我们的 SpringBoot 应用 Docker 镜像。

Dockerfile 描述镜像打包过程,在这个文件中明确 基础镜像把jar加入到镜像启动jar的Java命令

一、把项目打包成可执行的jar文件

如果没有现成可用的可执行jar文件,则需要从一个项目中通过项目源码把项目打包成一个可执行的jar文件。如果已经有一个可执行的jar文件则可以跳过此步骤。

通过 Maven 管理的项目可执行以下命令:

mvn clean package -Dmave.test.skip=true -DskipTests

执行完该命令后,在项目的 target/ 路径下会有一个jar文件 spring-boot-docker-deploy-0.0.1-SNAPSHOT.jar

image-20200219153850030

该jar文件为Java的可执行jar文件。可以通过在target/路径下执行Java命令来验证这个jar文件是否正常

java -jar spring-boot-docker-deploy-0.0.1-SNAPSHOT.jar

如果jar文件无误,看到 SpringBoot 启动成功提示:

image-20200219162501619

二、编写 Dockerfile 文件

通过第一步,我们已经拿到一个可执行的 jar 文件,那么第二步就需要编写 Dockerfile 来描述如何去构建一个新的镜像。在项目路径下新建一个Dockerfile文件,然后写入以下内容:

FROM java:8-alpine
ADD target/spring-boot-docker-deploy-0.0.1-SNAPSHOT.jar ./
EXPOSE 8080
ENTRYPOINT ["java","-jar","spring-boot-docker-deploy-0.0.1-SNAPSHOT.jar"]

这是一个最简单的 Dockerfile 文件,共有4行。

  • FROM [image-name:tag] 设置一个基础镜像,这里是要把 SpringBoot 应用打包成镜像,因此需要一个Java环境,java:8-alpine 镜像是一个精简的Java环境镜像,其镜像体积比java:8要小很多,但是提供了同样的环境。
  • ADD [source file or dir] [directory]java:8-alpine 镜像的基础上把某个文件添加到指定的路径中
  • EXPOSE [port] 声明这个镜像使用哪个端口对外提供服务
  • ENTRYPOINT [commands...] 容器启动时执行的命令

至此,已经编写好构建镜像所需的 Dockerfile 文件

三、执行镜像打包命令

在第一步拿到一个可执行的jar文件,第二步编写好构建镜像的Dockerfile文件,此时可以使用docker命令来构建一个镜像了。

在项目路径下执行镜像打包命令:

# 命令格式:docker build -t [镜像名称] [Dockerfile文件所在路径]
docker build -t spring-boot-app .

image-20200219162635342

此时就把SpringBoot应用成功的打包成了docker镜像。可以通过以下命令来查看当前系统中所有的镜像列表:

docker images

四、通过镜像运行一个容器

镜像是一个只读的状态,容器是镜像的运行状态,是可写的,它是在镜像层上添加一个读写层,可以通过以下命令指定某个镜像运行一个容器:

docker run -it -p 8081:8080 spring-boot-app
# 命令格式:docker run [参数列表] [镜像名称:镜像标签]
# 如果未指定镜像标签,则默认为latest标签,表示最新的镜像
# -it 说明:-i 打开STDIN,用于控制台交互;-t 分配tty设备,该可以支持终端登录,默认为false
# -it 参数起到的作用,当我们使用 Ctrl+C 组合键时可以停止容器关闭应用,否则容器将会一直在运行
# -p 参数表示把主机的8081端口映射到容器的8080端口,实际上也就是端口转发,当访问本机127.0.0.1的8081端口时会把数据转发到这个容器的8080端口。如果不设置端口映射,想要访问的时候需要访问 http://容器IP:容器端口号/ 

此时可以在控制台看到启动SpringBoot应用时打印的日志信息,表示打包的这个镜像是正常可用的。我们可以通过在浏览器访问:http://127.0.0.1:8081/ 来检查应用是否可访问。

image-20200219162756533

五、可能遇到的问题

1. 时区问题,应用的时间与北京时间相差8小时

这个问题很大可能会在生产环境中遇到,因为生产环境是使用Linux系统,docker也运行在Linux系统上,容器时间有可能会变成UTC时区时间,此时Java应用获取到的时间就比北京时间晚了8个小时,与其他系统对接(比如对接数据库)的时候会因为时间问题而产生时间错乱、不一致,或者页面展示数据的时间不准确的问题。

关于该问题,有两种解决方案,一种是配置环境变量,一种是修改容器内/etc/timezone/etc/localtime文件内容。

一般只要给容器添加表示时区的环境变量即可,把时区的环境变量设置为上海Asia/Shanghai

1.1 配置环境变量:修改 Dockerfile

我们在Dockerfile文件中加入环境变量来指定容器的时区:

FROM java:8-alpine
ENV TZ Asia/Shanghai
ADD target/spring-boot-docker-deploy-0.0.1-SNAPSHOT.jar ./
EXPOSE 8080
ENTRYPOINT ["java","-jar","spring-boot-docker-deploy-0.0.1-SNAPSHOT.jar"]
1.2 配置环境变量:修改容器启动命令
docker run -it -p 8081:8080 -e TZ="Asia/Shanghai" spring-boot-app
1.3 修改容器内文件

通过在 Dockerfile 文件描述构建镜像的过程中修改容器内文件信息

FROM java:8-alpine
RUN ln -sf /usr/share/zoneinfo/Asia/shanghai /etc/localtime
RUN echo "Asia/shanghai" > /etc/timezone
ADD target/spring-boot-docker-deploy-0.0.1-SNAPSHOT.jar ./
EXPOSE 8080
ENTRYPOINT ["java","-jar","spring-boot-docker-deploy-0.0.1-SNAPSHOT.jar"]

或者通过启动命令直接挂载当前主机(需要当前主机时区正常)的文件到容器内:

docker run -it -p 8081:8080 -v /etc/timezone:/etc/timezone -v /etc/localtime:/etc/localtime spring-boot-app

2. 如何把应用运行时产生的文件等数据保存到当前电脑上?

在使用docker运行应用的时候,我们应用可能会产生一些文件和数据需要永久存储的,而不是删除容器后导致数据同时丢失,要做到即使删除容器、升级镜像版本也不会影响我们的数据。

此时需要设置在容器上面挂载一个目录,把这个目录的所有数据保存到主机中。

docker run -it -p 8081:8080 -v /var/www/data:/app/log spring-boot-app

此处用到一个 -v 参数,这个参数把当前主机上的 /var/www/data 目录挂载到容器的 /app/log 路径,当容器应用在容器内的 /app/log 路径下写入数据时,会把数据保存到我们主机的 /var/www/data 路径下。

六、通过Maven插件来构建Docker镜像

通过Maven插件来构建Docker镜像的时候,就只需要在pom.xml文件中配置好镜像信息,然后执行Maven命令即可构建镜像。

这里用到的 com.spotifydocker-maven-plugin 插件,当第一次使用该插件的时候需要下载插件依赖,由于网络原因,这个可能会花很久的时间。

需要在pom.xml文件中配置插件信息:

<build>
    <plugins>
        <!-- docker的maven插件,官网:https://github.com/spotify/docker-maven-plugin -->
        <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <version>1.2.2</version>
            <configuration>
                <!-- 设置构建的应用镜像名称,注意 imageName 一定要是符合正则 [a-z0-9-_.] 的,否则构建不会成功 -->
                <!-- 详见:https://github.com/spotify/docker-maven-plugin -->
                <imageName>${project.artifactId}</imageName>
                <baseImage>java:8-alpine</baseImage>
                <imageTags>
                    <imageTag>${project.version}</imageTag>
                    <imageTag>latest</imageTag>
                </imageTags>
                <!-- 设置容器内的工作目录 -->
                <workdir>/app</workdir>
                <exposes>8080</exposes>
                <env>
                    <TZ>Asia/Shanghai</TZ>
                </env>
                <entryPoint>["java", "-jar", "${project.build.finalName}.jar"]
                </entryPoint>
                <!-- 指定 Dockerfile 所在的路径 -->
                <!-- <dockerDirectory>${project.basedir}</dockerDirectory> -->
                <resources>
                    <resource>
                        <targetPath>.</targetPath>
                        <directory>${project.build.directory}</directory>
                        <include>${project.build.finalName}.jar</include>
                    </resource>
                </resources>
            </configuration>
        </plugin>
    </plugins>
</build>

在这里,设置了构建的镜像名称为${project.artifactId}表示当前项目的artifactId信息,每个标准的Maven项目都会有三个基本信息:

<groupId>com.timeloit.gx</groupId>
<artifactId>spring-boot-docker-deploy</artifactId>
<version>0.0.1</version>

每个镜像都会有一个镜像标签 imageTage ,可以用这个镜像标签来表示当前镜像对应的应用版本信息,在插件配置中分配了两个标签,分别为${project.version}latest,前者当前Maven项目的版本,后者表示镜像的最新版本,表示构建的这个镜像的版本是 0.0.1同时也是一个最新的版本。

此时执行以下Maven命令即可构建一个Docker镜像

mvn docker:build

把 Maven Docker 插件与 Maven 打包命令结合

在执行 Maven Docker 构建镜像命令的时候,需要先执行 Maven 打包命令,先生成一个jar文件才能进行Docker镜像打包,否则打包出来的镜像将无法正常运行。

此时可以把Docker镜像构建命令与Maven打包jar命令结合起来,在打包项目的时候同时构建一个Docker镜像,这时候需要修改Maven Docker插件配置。

<build>
    <plugins>
        <!-- docker的maven插件,官网:https://github.com/spotify/docker-maven-plugin -->
        <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <version>1.2.2</version>
            <!-- start:本次添加内容 -->
            <executions>
                <execution>
                    <id>build-image</id>
                    <phase>package</phase>
                    <goals>
                        <goal>build</goal>
                    </goals>
                </execution>
            </executions>
            <!-- end:本次添加内容 -->
            
            <configuration>
                <!-- 设置构建的应用镜像名称,注意 imageName 一定要是符合正则 [a-z0-9-_.] 的,否则构建不会成功 -->
                <!-- 详见:https://github.com/spotify/docker-maven-plugin -->
                <imageName>${project.artifactId}</imageName>
                <baseImage>java:8-alpine</baseImage>
                <imageTags>
                    <imageTag>${project.version}</imageTag>
                    <imageTag>latest</imageTag>
                </imageTags>
                <!-- 设置容器内的工作目录 -->
                <workdir>/app</workdir>
                <exposes>8080</exposes>
                <env>
                    <TZ>Asia/Shanghai</TZ>
                </env>
                <entryPoint>["java", "-jar", "${project.build.finalName}.jar"]
                </entryPoint>
                <!-- 指定 Dockerfile 所在的路径 -->
                <!-- <dockerDirectory>${project.basedir}</dockerDirectory> -->
                <resources>
                    <resource>
                        <targetPath>.</targetPath>
                        <directory>${project.build.directory}</directory>
                        <include>${project.build.finalName}.jar</include>
                    </resource>
                </resources>
            </configuration>
        </plugin>
    </plugins>
</build>
Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2020 spring-boot-docker-deploy Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

简介

暂无描述 展开 收起
Java 等 2 种语言
Apache-2.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/timeloit_gxlz_old_1/spring-boot-docker-deploy.git
git@gitee.com:timeloit_gxlz_old_1/spring-boot-docker-deploy.git
timeloit_gxlz_old_1
spring-boot-docker-deploy
spring-boot-docker-deploy
master

搜索帮助