【Docker】使用Docker构建Tomcat的一些坑

Dockerfile

#以 centos 作为基础镜像
FROM centos

#将主机上下文路径中的 openjdk-11+28_linux-x64_bin.tar.gz 解压到镜像容器的 /usr/local/jdk-11/
ADD openjdk-11+28_linux-x64_bin.tar.gz /usr/local/

#将主机上下文路径的 apache-tomcat-9.0.30/ 复制到镜像容器的 /usr/local/apache-tomcat-9.0.30/
COPY apache-tomcat-9.0.30/ /usr/local/apache-tomcat-9.0.30/

#设置环境变量
ENV JAVA_HOME=/usr/local/jdk-11/
ENV CATALINA_HOME=/usr/local/apache-tomcat-9.0.30/ 
ENV  PATH=${PATH}:${JAVA_HOME}/bin/:${CATALINA_HOME}/bin/

#暴露端口
EXPOSE 8080

#切换镜像容器内的工作目录为 /usr/local/apache-tomcat-9.0.30/webapps/
WORKDIR /usr/local/${CATALINA_HOME}/webapps/

#启动
ENTRYPOINT [ "catalina.sh","run" ]

步骤

1、选择以 centos 作为基础镜像来构建新的镜像。
2、假设当前在 /root/ 目录下,下载 jdk 和 tomcat 到当前目录下,并打算以此路径作为“Docker构建上下文路径”。
wget "https://download.java.net/java/GA/jdk13.0.2/d4173c853231432d94f001e99d882ca7/8/GPL/openjdk-13.0.2_linux-x64_bin.tar.gz" -P /root/
wget "http://mirror.bit.edu.cn/apache/tomcat/tomcat-9/v9.0.31/bin/apache-tomcat-9.0.31.tar.gz" -P /root/

注意通过 wget命令从

https://download.oracle.com/otn/java/jdk/11.0.6+8/90eb79fb590d45c8971362673c5ab495/jdk-11.0.6_linux-x64_bin.tar.gz

下载的 oracle-jdk 包——jdk-11.0.6_linux-x64_bin.tar.gz将无法解压。换句话说:这根本就不是一个资源链接

3、将 tomcat 解压并添加一些东西到 webapps 中。

在这里插入图片描述

4、以此目录为“构建上下文路径”进行构建镜像
docker build -t icefery/tomcat /root/

在这里插入图片描述

5、运行容器
docker run -d -p 80:8080 icefery/tomcat

在这里插入图片描述

注意事项

1、Dockerfile的构建上下文路径

最好将 Dockerfile 以及构建时所需的资源放在单独的目录中,以减少构建时寻找 Dockerfile 文件的时间。而这个上下文路径,也可以算是使用COPYADD等命令时的根路径。否则可能会报出类似" ADD failed: stat /var/lib/docker/tmp/docker-builder055888630/install/xxx.zip: no such file or directory "的错误。

2、COPYADD命令

可以笼统地说,“这两个命令用与从主机的上下文路径复制文件到镜像容器中ADD命令只不过多了个解压的过程”。而且ADD命令可以直接从资源链接添加并解压文件,就比如还可以:

ADD http://mirror.bit.edu.cn/apache/tomcat/tomcat-9/v9.0.31/bin/apache-tomcat-9.0.31.tar.gz /usr/local/

Docker 官方建议我们当需要从远程复制文件时,最好使用 curl 或 wget 命令来代替 ADD 命令。原因是,当使用 ADD 命令时,会创建更多的镜像层,当然镜像的 size 也会更大。

除此之外,COPY还有比较恶心的一点,我们预期的COPY命令是和cp -r <SOURCE> <DEST>的效果是一样:

在这里插入图片描述

可能我们希望的是:

  • 压缩文件经过解压后会有个“包装”,而不是解压后就散开了。至于“包装”名是否必须和压缩文件保持一致我们并不关心,例如openjdk-11+28_linux-x64_bin.tar.gz解压时的“包装”为jdk-11,我们也是可以接受的。
  • 复制目录是将整个目录递归复制到目标路径下,而不是只复制这个目录一下的内容。

所以,如果将 Dockerfile 中的命令替换为以下内容,可能就会比较恶心了。

COPY apache-tomcat-9.0.30/ /usr/local/
3、环境变量

ENV是可以跟多个环境变量的,格式为:

ENV <KEY>=<VALUE> [<KEY>=<VALUE>]...

但是如果使用长格式命令的换行符\区换行,可能就会出现问题。但是在RUN后面跟的命令是可以使用长格式命令大的换行符的。

4、工作路径

通常可以使用WORKDIR来切换镜像容器中的工作路径,效果是:进入容器后的当下路径就是最后一次切换的工作路径。
在这里插入图片描述

5、运行

关于CMDENTRYPOINT的区别基本上也可以笼统的理解为:“两者都是仅生效最后一条,CMD后跟的命令可以被创建容器时的参数替换”。然而也是可以通过--entrypoin选项区替换ENTRYPOINT的参数的。

另一个比较坑的点是:虽然startup.sh相当于catalina.sh的 DEBUG 模式,但 Docker 中的 tomcat 不能直接通过 startup.sh 启动。(详情请参考docker下面tomcat执行startup.sh问题

或者也可以通过以下方式运行,但是会明显感觉到停止该容器会慢一些。(参考自(十三) 使用Dockerfile 自定义tomcat镜像 ,并部署web项目

CMD /usr/local/tomcat/apache-tomcat-8.5.30/bin/startup.sh && tail -f /usr/local/tomcat/apache-tomcat-8.5.30/logs/catalina.out

除此之外,在 tomcat8.5 某版本中的镜像中,其 webapps/ 目录下什么东西都没有,所以启动成功后访问不到 tomcat 主。只要进入容器将 webapps.dist/ 中的东西复制进去就可以了。

原创文章 41 获赞 34 访问量 3万+

猜你喜欢

转载自blog.csdn.net/XY1790026787/article/details/104284063