Docker入门到实践(十)IDEA集成Docker构建容器镜像、部署项目

2,015 阅读8分钟

Docker 入门到实践系列文章列表:

Docker 入门到实践 (一) docker 简介与安装
Docker 入门到实践 (二) docker 常用命令讲解
Docker 入门到实践 (三) Dockerfile 解析与镜像制作
Docker 入门到实践 (四) docker 容器数据卷与数据卷容器
Docker 入门到实践 (五) docker 数据的备份、恢复与迁移
Docker 入门到实践 (六) docker 网络模式详解以及容器间的网络通信
Docker 入门到实践 (七) docker 常用软件的安装
Docker 入门到实践 (八) 本地镜像推送到阿里云 和 下载镜像到本地
Docker 入门到实践 (九) docker 可视化界面 portainer 的安装与使用
Docker 入门到实践 (十) IDEA 集成 Docker 构建容器镜像,部署项目
Docker 入门到实践 (十一) docker 私有仓库的搭建与配置
Docker 入门到实践 (十二) docker compose 简介与安装
Docker 入门到实践 (十三) docker compose 配置文件与常用命令讲解
Docker 入门到实践 (十四) docker 企业级容器镜像仓库 HarBor 的搭建与配置

一、前言

  在上一篇文章中已经介绍了 docker 可视化界面 portainer 的安装与使用, 下面正式进入到 IDEA 集成 Docker 构建容器镜像,部署项目的讲解。

二、开启 docker 的 tcp 远程访问

由于使用 IDEA 来构建容器镜像,部署项目对于 Linux 服务器上的 docker 宿主机来说是一种远程操作,而远程操作 docker 默认是关闭的,就需要我们开启远程访问

//1、编辑docker.service
vim /usr/lib/systemd/system/docker.service

//2、修改ExecStart属性,在后面添加-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock

//3、刷新配置,重启服务
systemctl daemon-reload
systemctl restart docker

打开浏览器,在地址栏中输入http://Linux的ip地址:2375/version,出现如下图片中的相关信息,则表示成功开启 docker 的 tcp 远程访问

三、通过 docker 的 maven 插件构建镜像

方式一:不使用 Dockerfile 来构建镜像

1、在 pom.xml 中添加如下配置,更多相关配置信息请查看:配置详解

<build>
    <!-- 打包后的文件名称 -->
    <finalName>app</finalName>

    <plugins>
        <!-- Maven 插件 -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <!-- 项目基于maven pom多模块的开发的,需要设置goal-repackage属性为true,否则打包后依赖文件没有一起打包,导致镜像内没有可以运行的程序文件 -->
            <executions>
               <execution>
                   <goals>
                       <goal>repackage</goal>
                   </goals>
               </execution>
            </executions>
            <configuration>
              <includeSystemScope>true</includeSystemScope>
            </configuration>
        </plugin>

        <!--使用docker-maven-plugin插件,官网:https://github.com/spotify/docker‐maven‐plugin-->
        <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <version>1.0.0</version>

            <!--将插件绑定在某个phase执行-->
            <executions>
                <execution>
                    <id>build-image</id>
                    <!--将插件绑定在package这个phase上。也就是说,用户只需执行mvn package,就会自动执行mvn docker:build-->
                    <phase>package</phase>
                    <goals>
                        <goal>build</goal>
                    </goals>
                </execution>
            </executions>

            <configuration>
                <!--指定生成的镜像名-->
                <imageName>${project.artifactId}</imageName>
                <!--指定标签,可添加多个imageTag,为同一个镜像指定多个标签-->
                <imageTags>
                    <imageTag>latest</imageTag>
                </imageTags>

                <!-- 用于指定基础镜像,类似于Dockerfile中的FROM指令 -->
                <baseImage>java:8u111</baseImage>

                <!--
                   类似于Dockerfile的ENTRYPOINT指令,
                   由于tomcat的session id的生成主要通过java.security.SecureRandom生成随机数来实现,导致启动过程很慢
                   通过-Djava.security.egd=file:/dev/./urandom参数可以加快随机数产生过程
                -->
                <entryPoint>["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/${project.build.finalName}.jar"]</entryPoint>

                <!-- 这里是复制 jar 包到 docker 容器指定目录配置 -->
                <resources>
                    <resource>
                        <targetPath>/</targetPath>
                        <!--指定需要复制项目jar包的所在路径,${project.build.directory}表示target目录 -->
                        <directory>${project.build.directory}</directory>
                        <!-- 用于指定需要复制的文件。${project.build.finalName}.jar指的是打包后的jar包文件 -->
                        <include>${project.build.finalName}.jar</include>
                    </resource>
                </resources>

                <!--指定远程 docker api地址-->
                <dockerHost>http://192.168.198.124:2375</dockerHost>
                <!-- 如需重复构建相同标签名称的镜像,可将forceTags设为true,这样就会覆盖构建相同标签的镜像。 -->
                <forceTags>true</forceTags>
            </configuration>
        </plugin>
    </plugins>
</build>

以上配置会自动生成如下的 Dockerfile 文件

# Base images 基础镜像
FROM java:8u111

#ADD  app.jar文件将拷贝到容器根目录下,拷贝过去会自动解压
ADD app.jar /

#ENTRYPOINT 应用启动命令 参数设定
#由于tomcat的session id的生成主要通过java.security.SecureRandom生成随机数来实现,导致启动过程很慢
#通过-Djava.security.egd=file:/dev/./urandom参数可以加快随机数产生过程
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar"]

2、在 windows 的命令提示符下 或者 IDEA 集成的 Terminal 窗口,进入到工程所在的目录,输入以下命令,进行打包、构建和上传镜像

/**
 * mvn clean package:表示打包项目
 * docker:build:表示构建docker镜像
 **/
mvn clean package docker:build


/**
 * 如果在pom.xml中添加了如下配置,则在执行mvn package,就会自动执行mvn docker:build
 * 即可以省略docker:build,命令为 mvn clean package
 **/
<executions>
    <execution>
	<id>build-image</id>
	<phase>package</phase>
	<goals>
	    <goal>build</goal>
	</goals>
    </execution>
</executions>


/**
 * 如果需要把镜像上传到私有仓库或者阿里云仓库中,则需要进行以下两步操作
 **/

//1、修改<imageName>标签,上传到私有仓库,则配置如下
<imageName>Linux的ip地址:5000/${project.artifactId}</imageName>

//上传到阿里云仓库,则配置如下
<imageName>registry.cn-地域名称.aliyuncs.com/你的命名空间名称/${project.artifactId}</imageName>

//2、在命令行后面添加 -DpushImage:表示推送镜像到仓库中
mvn clean package docker:build -DpushImage
或者
mvn clean package -DpushImage (需要在pom.xml中配置<executions>的相关信息)


3、运行镜像,产生容器实例。注意: 第二个 7001 端口 (即:容器端口),是你项目的 application.yml / application.properties 配置文件中 server.port 指定的端口

4、访问项目

方式二:通过 Dockerfile 实现细腻化的镜像构建

由于在很多场景下,我们希望使用 Dockerfile 进行更精确、有可读性地构建容器镜像,接下来就让我们来了解一下,如何通过 Dockerfile 进行镜像的构建

1、首先,在项目的 src/main 路径下,创建一个 docker 目录,并在 docker 目录下新建一个 Dockerfile 文件,其内容如下所示:

# Base images 基础镜像
FROM java:8u111

#MAINTAINER 维护者信息
MAINTAINER wubin<1035644768@qq.com>

#VOLUME:挂载目录
VOLUME /temp

#ADD  将app.jar文件将拷贝到容器中,默认拷贝到根路径下
#也可以直接写成ADD app.jar /app.jar 或者 ADD app.jar /
ADD app.jar app.jar

#修改app.jar这个文件的访问时间和修改时间为当前时间,而不会修改文件的内容。
RUN bash -c "touch /app.jar"

#EXPOSE 容器暴露端口
EXPOSE 7001

#ENTRYPOINT 应用启动命令 参数设定
#由于tomcat的session id的生成主要通过java.security.SecureRandom生成随机数来实现,导致启动过程很慢
#通过-Djava.security.egd=file:/dev/./urandom参数可以加快随机数产生过程
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar"]

2、修改 pom.xml,不再指定<baseImage><entrypoint>标签,而是使用<dockerDirectory>指定 Dockerfile 所在的路径

<build>
  <!-- 打包后的文件名称 -->
  <finalName>app</finalName>

  <plugins>
      <!-- Maven 插件 -->
      <plugin>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-maven-plugin</artifactId>
          <!-- 项目基于maven pom多模块的开发的,需要设置goal-repackage属性为true,否则打包后文件依赖文件没有一起打包,然后镜像内没有可以运行的程序文件,显示错误no main manifest attribute, in /app.jar -->
          <executions>
              <execution>
                  <goals>
                      <goal>repackage</goal>
                  </goals>
              </execution>
          </executions>
          <configuration>
              <includeSystemScope>true</includeSystemScope>
          </configuration>
      </plugin>

      <!--使用docker-maven-plugin插件,官网:https://github.com/spotify/docker‐maven‐plugin-->
      <plugin>
          <groupId>com.spotify</groupId>
          <artifactId>docker-maven-plugin</artifactId>
          <version>1.0.0</version>

          <!--将插件绑定在某个phase执行-->
          <executions>
              <execution>
                  <id>build-image</id>
                  <!--将插件绑定在package这个phase上。也就是说,用户只需执行mvn package,就会自动执行mvn docker:build-->
                  <phase>package</phase>
                  <goals>
                      <goal>build</goal>
                  </goals>
              </execution>
          </executions>

          <configuration>
              <!--指定生成的镜像名-->
              <imageName>${project.artifactId}</imageName>
              <!--指定标签,可添加多个imageTag,为同一个镜像指定多个标签-->
              <imageTags>
                  <imageTag>latest</imageTag>
              </imageTags>

              <!-- 指定 Dockerfile 路径-->
              <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>

              <!-- 这里是复制 jar 包到 docker 容器指定目录配置 -->
              <resources>
                  <resource>
                      <targetPath>/</targetPath>
                      <!--指定需要复制项目jar包的所在路径,${project.build.directory}表示target目录 -->
                      <directory>${project.build.directory}</directory>
                      <!-- 用于指定需要复制的文件。${project.build.finalName}.jar指的是打包后的jar包文件 -->
                      <include>${project.build.finalName}.jar</include>
                  </resource>
              </resources>

              <!--指定远程 docker api地址-->
              <dockerHost>http://192.168.198.124:2375</dockerHost>
              <!-- 如需重复构建相同标签名称的镜像,可将forceTags设为true,这样就会覆盖构建相同标签的镜像。 -->
              <forceTags>true</forceTags>
          </configuration>
      </plugin>
  </plugins>
</build>

3、执行相关命令,与方式一:不使用 Dockerfile 来构建镜像的步骤 2 一样,这里不再重复

四、通过 IDEA 的 Docker 插件构建镜像

1、安装 Docker 插件

1.1、在顶部工具栏中找到 File → Settings

1.2、找到 Plugins,点击 “Browse repositories” 按钮

1.3、在搜索框输入 Docker,选择 Docker 插件,点击 “Install” 按钮进行安装,然后点击 “Close” 按钮

3.2、可以看到 Docker 插件已经被我们安装上了,然后点击 "Apply" 按钮,再点击 "OK" 按钮,最后重启 IDEA 即可生效

2、配置 Docker 服务

2.1、在顶部工具栏中找到 File → Settings,进入到 Settings 设置页面中,找到 Build,Execution,Deployment → Docker,点击 "+",添加一个 docker 连接

2.2、在 Engine API URL 中输入你的 docker 服务地址,格式为:tcp://Linux(即: docker 宿主机) 的 ip 地址: 2375,配置好后,idea 会自动检测,然后在左下方输出 "connection successful",然后点击 "Apply" 按钮,再点击 "OK" 按钮

2.3、选择 IDEA 的 Docker 窗口,点击 "绿色运行按钮",连接 Linux 服务器上的 docker,连接成功之后,会显示 Containers 和 Images,即:docker 中已有的容器和镜像

3、通过 Docker 插件构建镜像

1、首先,在项目的 src/main 路径下,创建一个 docker 目录,并在 docker 目录下新建一个 Dockerfile 文件,其内容如下所示:

# Base images 基础镜像
FROM java:8u111

#MAINTAINER 维护者信息
MAINTAINER wubin<1035644768@qq.com>

#VOLUME:挂载目录
VOLUME /temp

#ADD  将microservicecloud-eureka-7001-1.0-SNAPSHOT.jar文件将拷贝到容器中,默认拷贝到根路径下
#注意:microservicecloud-eureka-7001-1.0-SNAPSHOT.jar的名称前的microservicecloud-eureka-7001对应<artifactId>标签中的内容,1.0-SNAPSHOT对应<version>标签中的内容
ADD microservicecloud-eureka-7001-1.0-SNAPSHOT.jar app.jar

RUN bash -c "touch /app.jar"

#EXPOSE 容器暴露端口
EXPOSE 7001

#ENTRYPOINT 应用启动命令 参数设定
#由于tomcat的session id的生成主要通过java.security.SecureRandom生成随机数来实现,导致启动过程很慢
#通过-Djava.security.egd=file:/dev/./urandom参数可以加快随机数产生过程
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar"]

2、创建 Dockerfile 启动项

2.1、选择 Edit Configurations…

2.2、点击 "+",找到 Docker,选择 Dockerfile

2.3、配置 Dockerfile 启动项的相关信息
image.png 注意: 容器端口,是你项目的 application.yml / application.properties 配置文件中 server.port 指定的端口


3、在 pom.xml 文件中添加 SpringBoot 的 maven 插件,如果不添加,运行容器时,会报错,错误信息为:no main manifest attribute, in /xxx.jar

<build>
   <plugins>
       <plugin>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-maven-plugin</artifactId>
           <!-- 项目基于maven pom多模块的开发的,需要设置goal-repackage属性为true,否则打包后文件依赖文件没有一起打包,然后镜像内没有可以运行的程序文件 -->
           <executions>
               <execution>
                   <goals>
                       <goal>repackage</goal>
                   </goals>
               </execution>
           </executions>
           <configuration>
               <includeSystemScope>true</includeSystemScope>
           </configuration>
       </plugin>
   </plugins>
</build>

4、执行 mvn clean install 命令,打包项目并安装到本地的 maven 仓库中

5、在本地 maven 仓库中找到刚才安装好的 microservicecloud-eureka-7001-1.0-SNAPSHOT.jar,拷贝到项目的 src/main/docker 目录下,并运行 Docker 启动项,Docker 插件会自动帮我们构建项目镜像,并启动容器实例

因为我们在 Dockerfile 文件中配置了ADD microservicecloud-eureka-7001-1.0-SNAPSHOT.jar app.jar,而 Dockerfile 文件是放在项目的 src/main/docker 目录下,所以它会在当前目录(即:docker目录)下寻找microservicecloud-eureka-7001-1.0-SNAPSHOT.jar

6、访问项目

改进:前面说了,我们需要把项目的 jar 包拷贝到 docker 目录下,然后再运行,有什么办法能够不拷贝项目的 jar 包到 docker 目录下,直接运行呢?解决方案如下:

1、删除之前的 docker 目录,在项目的根目录下,新建一个 Dockerfile 文件,内容如下:

注意:需要将之前的ADD microservicecloud-eureka-7001-1.0-SNAPSHOT.jar app.jar 修改为 ADD /target/microservicecloud-eureka-7001-1.0-SNAPSHOT.jar app.jar,让它去读取 target 目录下的项目 jar 包

# Base images 基础镜像
FROM java:8u111

#MAINTAINER 维护者信息
MAINTAINER wubin<1035644768@qq.com>

#VOLUME:挂载目录
VOLUME /temp

#ADD  将microservicecloud-eureka-7001-1.0-SNAPSHOT.jar文件将拷贝到容器中,默认拷贝到根路径下
ADD /target/microservicecloud-eureka-7001-1.0-SNAPSHOT.jar app.jar

RUN bash -c "touch /app.jar"

#EXPOSE 容器暴露端口
EXPOSE 7001

#ENTRYPOINT 应用启动命令 参数设定
#由于tomcat的session id的生成主要通过java.security.SecureRandom生成随机数来实现,导致启动过程很慢
#通过-Djava.security.egd=file:/dev/./urandom参数可以加快随机数产生过程
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar"]

2、修改 Docker 启动项,重新指定 Dockerfile 文件的所在路径

3、删除之前运行的项目容器实例 和 项目镜像

4、执行 mvn clean package 命令,把项目的 jar 包安装到当前项目的 target 目录下,最后运行 Docker 启动项

小提示:我们也可以通过 IDEA 的 Docker 插件,进行如下操作:

1、运行镜像,创建容器实例


2、拉取镜像

本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net