一、前言

  在上一篇文章中已经介绍了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启动项的相关信息
在这里插入图片描述

注意: 容器端口,是你项目的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、拉取镜像





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的搭建与配置




Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐