传统项目Docker化

最近一段时间项目升级总是出现各种各样的问题,要是可以docker部署就可以避免一些不必要的错误发生,心动不如行动,于是捣鼓了下如何将一个传统的项目docker,其中还是有不少收获的,这里就和大家分享下。

环境准备

环境只需要两个

这个环境其实是指编译打包调试的环境,一般来讲开发的时候是可以不用的。但这里作为调试环境需要验证是否有效,所以需要安装docker,windows下docker的支持有限,安装使用有些浪费资源,不过本人的系统已换成Linux用起来无压力。关于docker的安装可以参考下官网文档

简单示例

新项目一般都是使用的springboot用来docker化比较容易,具体可以参考官方说明。下面这个例子是针对传统项目来实现docker

pom.xml依赖

1
2
3
4
5
6
7
8
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>

简单的servlet

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.toss;

public class DemoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
PrintWriter w = resp.getWriter();
w.write("hello: " + format.format(new Date()));
w.flush();
w.close();
}
}

web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
<display-name>Docker Web Application</display-name>
<servlet>
<servlet-name>demo</servlet-name>
<servlet-class>com.toss.DemoServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>/demo</url-pattern>
</servlet-mapping>
</web-app>

这样一个传统的基本的web应用就被创建完毕,最关键的还是maven插件

pom.xml插件配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.19.v20190610</version>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.10</version>
<configuration>
<dockerfile>Dockerfile</dockerfile>
<repository>hst-boss</repository>
<tag>${project.version}</tag>
<buildArgs>
<WAR_FILE>target/${project.artifactId}.war</WAR_FILE>
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>

这里两个插件,一个jetty插件,一个docker插件,这里主要讲一下关于docker插件的Dockerfile,Dockerfile描述了docker镜像的生成步骤。

1
2
3
4
5
6
FROM tomcat:7

ENV TZ Asia/Shanghai
RUN rm -fr $CATALINA_HOME/webapps/ROOT
ARG WAR_FILE
COPY ${WAR_FILE} $CATALINA_HOME/webapps/ROOT.war

关于Dockerfile更详细的用法可以查阅官方文档,此处仅做简单的介绍。

注意事项

在使用过程中需要注意几点,这里单独拿出来详细的介绍

  • 项目名,项目名不能是docker,由于docker插件在使用过程中会生成docker相关信息的文件并处理,若项目名也是docker会扰乱docker插件的执行导致无法生成正确的docker镜像
  • 时区,这个问题比较隐晦,Java程序在docker中的时间是UTC时间,所以需要在Dockerfile中设置ENV TZ Asia/Shanghai,将时区改为东八区
  • 项目运行路径,war在tomcat中运行时路径是会带上项目名的,一般来讲可以通过修改conf/context.xml配置来实现,不过有些复杂需要为每个项目都配置一遍,所以可以采用ROOT.war的方式实现,这样可以降低复杂度。
  • dubbo服务注册问题,当服务都在一台机器时没有任何问题,但是在不同机器时就会出现问题,这个问题在dubbo的后续版本被处理,处理方式很简单指定环境变量DUBBO_IP_TO_REGISTRY — 注册到注册中心的ip地址DUBBO_PORT_TO_REGISTRY — 注册到注册中心的port端口,旧版dubbo如何处理?hostname区分,dubbo的docker内host文件指定127.0.0.1同时暴露端口,外部再指定host指向宿主机即可,具体实现这里就不再赘述。

写在最后

路漫漫其修远兮,只能一步一步来,现在工作虽然不能马上用到这些东西,但是多一份积累多一份成长总是好的,希望本文能为你带来些帮助。