解决docker运行tomcat提示找不到文件的问题

目录
  • docker运行tomcat提示找不到文件
    • 问题描述
  • 线索一:容器退出码
  • 线索二:无法找到文件
  • 顺藤摸瓜:catalina.sh
  • 解决方法

docker运行tomcat提示找不到文件

问题描述

  • docker课程中,老师是用tomcat镜像来演示docker的一些操作
  • 但同样的操作有的同学是ok的,有的同学就会遇到如下错误

  • 核心信息
Exited(1)

Cannot find /usr/local/tomcat/bin/setclasspath.sh
This file is needed to run this program
  • 一开始也挺费解的,我虽然不上这个课,但也比较好奇,自己始终无法复现,但不断有学员问,我看到就回复,在docker run命令后加一个--privileged即可
  • 但为何呢,不能说的很清楚,因为--privileged这个参数就是让你容器内的root用户具备拥有真正的root权限。否则容器内的root只是外部的一个普通用户权限。

线索一:容器退出码

  • 从上面的提示可以看到容器退出了,ExitCode是1
  • 1的意思是:
    • 程序错误,或者Dockerfile中引用不存在的文件,如 entrypoint中引用了错误的包
    • 程序错误可以很简单,例如“除以0”,也可以很复杂,比如空引用或者其他程序 crash
  • ExitCode1: Indicates failure due to application error
  • Indicates that the container stopped due to either an application error or an incorrect reference in Dockerfile to a file that is not present in the container.
  • An application error can be as simple as “divide by 0” or as complex as “Reference to a bean name that conflicts with existing, non-compatible bean definition of same name and class.”
  • An incorrect reference in Dockerfile to a file not present in the container can be as simple as a typo (the example below has sample.ja instead of sample.jar)
  • 知道了这个似乎帮助不大,不过有的容器退出码是非常能指向原因的,比如ExitCode 0

线索二:无法找到文件

  • 这个线索就非常重要了
  • 那为何会无法找到,真的有吗?有的
  • 比如在我这个正常的容器中
[root@hecs-67651 ~]# docker ps -a
CONTAINER ID   IMAGE                                        COMMAND                  CREATED          STATUS          PORTS                                                                                      NAMES
59463bed0fd7   tomcat                                       "catalina.sh run"        35 minutes ago   Up 35 minutes   8080/tcp                                                                                   mytomcat5

[root@hecs-67651 ~]# docker exec -it 594 ls /usr/local/tomcat/bin/setclasspath.sh
/usr/local/tomcat/bin/setclasspath.sh
  • 那遇到问题的学员为何找不到呢?
  • 我们的这个tomcat镜像在启动的时候会执行一个脚本
[root@hecs-67651 ~]# docker inspect -f '{{.Config.Cmd}}' tomcat:latest
[catalina.sh run]
  • 来看看catalina.sh做了啥

顺藤摸瓜:catalina.sh

  • 这个shell脚本比较大646行,我就摘录关键部分
  • 你看懂需要懂一些shell
  • 第一部分:报错在哪里
if $os400; then
  # -r will Only work on the os400 if the files are:
  # 1. owned by the user
  # 2. owned by the PRIMARY group of the user
  # this will not work if the user belongs in secondary groups
  . "$CATALINA_HOME"/bin/setclasspath.sh
else
  if [ -r "$CATALINA_HOME"/bin/setclasspath.sh ]; then
    . "$CATALINA_HOME"/bin/setclasspath.sh
  else
    echo "Cannot find $CATALINA_HOME/bin/setclasspath.sh"
    echo "This file is needed to run this program"
    exit 1
  fi
fi
  • 可以看到我们的报错就在这里
  • 执行的时候[ -r "$CATALINA_HOME"/bin/setclasspath.sh ]这个分支为假就走到了我们的报错中,exit 1
  • 这句话的意思是看 "$CATALINA_HOME"/bin/setclasspath.sh文件是否有read权限
root@59463bed0fd7:/usr/local/tomcat/bin# ll setclasspath.sh
-rwxr-xr-x 1 root root 3342 Mar  6 23:33 setclasspath.sh*
  • 在我这个OK的环境中的权限如上,read是有的
  • 那可能的问题就是在CATALINA_HOME这个变量是否存在
  • 而再往前看我们走到第一个else是因为$os400为假

第二部分:os400(仅供学习,对本问题没有作用,无需分析)

cygwin=false
darwin=false
os400=false
hpux=false
case "`uname`" in
CYGWIN*) cygwin=true;;
Darwin*) darwin=true;;
OS400*) os400=true;;
HP-UX*) hpux=true;;
esac
  • 从这里可以看到os400初始值为false,只有你的uname是OS400的时候才为true
  • 而我们这个环境的uname的值是
[root@59463bed0fd7 ~]# uname
Linux
  • 第三部分:[ -r "$CATALINA_HOME"/bin/setclasspath.sh ]

    • 等价于 test -r "$CATALINA_HOME"/bin/setclasspath.sh
    • 我这个OK的环境执行效果
root@59463bed0fd7:/usr/local/tomcat/bin# [ -r "$CATALINA_HOME"/bin/setclasspath.sh ]
root@59463bed0fd7:/usr/local/tomcat/bin# echo $?
0
  • 可以看到,是为0的返回值,那自然就不会报错,报错的环境肯定是非0 的
  • 问题的焦点似乎就集中到了$CATALINA_HOME上

第四部分:$CATALINA_HOME怎么来的

# 下面的意思是如果没有CATALINA_HOME这个变量就设置为cd "$PRGDIR/.." >/dev/null; pwd 这个pwd的结果
[ -z "$CATALINA_HOME" ] && CATALINA_HOME=`cd "$PRGDIR/.." >/dev/null; pwd`

# 而PRGDIR是这么来的
PRGDIR=`dirname "$PRG"`

# PRG来自
PRG="$0"  # 就是catalina.sh所在目录

# 下面的我也有点看不懂了,大致就是获取目录
while [ -h "$PRG" ]; do
  ls=`ls -ld "$PRG"`
  link=`expr "$ls" : '.*-> \(.*\)$'`
  if expr "$link" : '/.*' > /dev/null; then
    PRG="$link"
  else
    PRG=`dirname "$PRG"`/"$link"
  fi
done
  • 找了半天找了个寂寞?好像是的。那问题到底在哪里呢?我也没法复现。捋一捋
  • 线索:[ -r "$CATALINA_HOME"/bin/setclasspath.sh ] 执行为非0是肯定的
  • 如果文件存在,变量存在,那问题就只能是-r了,权限问题!

解决方法

  • 在docker run命令后加一个--privileged即可
  • --privileged这个参数就是让你容器内的root用户具备拥有真正的root权限。否则容器内的root只是外部的一个普通用户权限。
  • 往上有个文档说是:与faccessat2系统调用有关,由于 runc 中的 bug,如果您的内核不支持 faccessat2,它将失败。这有点难了~看不懂

https://syntaxbug.com/6d684d2afe/

到此这篇关于解决docker运行tomcat提示找不到文件的问题的文章就介绍到这了,更多相关docker运行tomcat提示找不到文件内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Docker运行Web服务实战之Tomcat的详细过程

    目录 1. 关于Tomcat 2. 准备工作 3.Dockerfile文件和其他脚本文件 4. 创建和测试镜像 1. 关于Tomcat Tomcat是由Apache软件基金会下属的Jakarta项目开发的一个Servlet容器,按照Sun Microsystems提供的技术规范,实现了对Servlet和Java Server Page(JSP)的支持.同时,它提供了作为Web服务器的一些特有功能,如Tomcat管理和控制平台.安全域管理和Tomcat阀等.由于Tomcat本身也内含了一个HTTP

  • 详解Docker学习笔记之搭建一个JAVA Tomcat运行环境

    前言 Docker旨在提供一种应用程序的自动化部署解决方案,在 Linux 系统上迅速创建一个容器(轻量级虚拟机)并部署和运行应用程序,并通过配置文件可以轻松实现应用程序的自动化安装.部署和升级,非常方便.因为使用了容器,所以可以很方便的把生产环境和开发环境分开,互不影响,这是 docker 最普遍的一个玩法.更多的玩法还有大规模 web 应用.数据库部署.持续部署.集群.测试环境.面向服务的云计算.虚拟桌面 VDI 等等. 主观的印象:Docker 使用 Go 语言编写,用 cgroup 实现

  • Docker学习之基于Dockerfile搭建JAVA Tomcat运行环境的方法

    前言 在第一篇文字中,我们完全人工方式,一个命令一个命令输入,实现一个java tomcat运行环境,虽然也初见成效,但很累人.如果依靠依靠脚本构建一个Tomcat容器实例,一个命令可以搞定,何乐而不为呢.好在Docker提供了Dockerfile作为构建Docker镜像脚本,避免人们一行一行的输入,真是善莫大焉.Dockerfile脚本可以做到随时维护修改,即可以分享,更有利于在模板化,更不用说传输了,好处那是一大箩筐! 最终目的:打造一个支持SSH终端登录.Tomcat7自动运行的Docke

  • Docker 搭建 Tomcat 运行环境的方法

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何接口. 1 Docker与虚拟机   2 搭建过程 2.1 准备宿主系统 准备一个 CentOS 7操作系统,具体要求如下: 必须是 64 位操作系统 建议内核在 3.8 以上 通过以下命令查看您的 CentOS 内核: # uname -r 2.2 安装Docker # yum install d

  • Docker下搭建一个JAVA Tomcat运行环境的方法

    前言 Docker旨在提供一种应用程序的自动化部署解决方案,在 Linux 系统上迅速创建一个容器(轻量级虚拟机)并部署和运行应用程序,并通过配置文件可以轻松实现应用程序的自动化安装.部署和升级,非常方便.因为使用了容器,所以可以很方便的把生产环境和开发环境分开,互不影响,这是 docker 最普遍的一个玩法.更多的玩法还有大规模 web 应用.数据库部署.持续部署.集群.测试环境.面向服务的云计算.虚拟桌面 VDI 等等. 主观的印象:Docker 使用 Go 语言编写,用 cgroup 实现

  • 解决docker运行tomcat提示找不到文件的问题

    目录 docker运行tomcat提示找不到文件 问题描述 线索一:容器退出码 线索二:无法找到文件 顺藤摸瓜:catalina.sh 解决方法 docker运行tomcat提示找不到文件 问题描述 docker课程中,老师是用tomcat镜像来演示docker的一些操作 但同样的操作有的同学是ok的,有的同学就会遇到如下错误 核心信息 Exited(1) Cannot find /usr/local/tomcat/bin/setclasspath.sh This file is needed

  • 解决cmd运行java程序“找不到文件”提示的方案

    一般我们在运行java代码时,运行器出现这样的问题的时候,说明我们当前的路径不是java文件存放路径. 第一步:我们需要找到我们存放我们的java代码的文件夹,然后在上面的"搜索"栏上输入"cmd",直接回车. 第二步:弹出"命令提示符",我们就会知道我们的"命令提示符"上的路径就会和我们的java代码存放的路径一致了. 第三步:我们根据我们保存的java文件名输入以下代码,对我们的代码进行打印,具体如下: 第一次输入:jav

  • 解决Pycharm 包已经下载,但是运行代码提示找不到模块的问题

    问题产生: pycharm→settings→Project interpreter→下载matplotlib包 运行代码,出现以下提示:找不到'matplotlib'模块ModuleNotFoundError: No module named 'matplotlib' 检查路径: 没有错误-- 让我们试试下面的步骤: 右上角,点击Edit Configuration: 发现Python interpreter路径非当前python文件,点击设置为默认路径 问题解决. 以上这篇解决Pycharm

  • docker 容器上编译 go 程序提示找不到文件问题

    dockerfile [root@SZB-L0010091 zxg]# cat Dockerfile FROM scratch COPY webdemo / EXPOSE 9999 CMD ["/webdemo"] docker run 报错信息: [root@zxg]# docker run --rm -it -p 9999:9999 web:1.0 panic: standard_init_linux.go:178: exec user process caused "n

  • 如何解决cmd运行python提示不是内部命令

    python安装完成后,直接运行python.exe能够正常执行python程序.但是进入到cmd命令窗口(同时按下win+r组合键后输入cmd进入),输入python命令提示"不是内部或外部命令",遇到这种现象通常是没有将python的安装路径添加到环境变量中. 在桌面上右键点击"此电脑",选择"属性",弹出系统界面选择"高级系统设置",进入系统属性界面后在"高级"选项中选中"环境变量"

  • 解决安装WampServer时提示缺少msvcr110.dll文件的问题

    今天开始学习PHP,对于初学者来说,我们一定希望从简单的开始,所以,从集成环境非常好的WampServer的安装开始. 1.下载WampServer安装程序,安装完毕后会出现一个错误.如下: 2.这是因为你的电脑缺少c++环境.你可以直接在bing里搜索"Visual C++ Redistributable for Visual Studio 2012 Update 4",找到文件后自己下载就可以了. 3.如图所示,找到文件后选择"中文(简体)",单击"下

  • Windows提示找不到文件“chkfat.exe”的解决方法

    尽管已经中毒,但卡巴斯基对这一个进程,一个文件,只能循环连续地报毒,再报杀毒成功,一个chkfat.exe需要重启后删除. 在msconfig启动中关了可疑进程后,重启卡巴斯基提示仍然!察看进程仍可以看到chkfat.exe的运行.结束进程后它随即又启动,卡巴斯基提示仍然! 在window的system32中找到chkfat.exe文件,用unlocker删除,按提示重启电脑,在再开机后弹出提示说,Windows找不到文件"chkfat.exe",请确定文件名正确后,在试一次等等内容.

  • 解决docker run中使用 ./ 相对路径挂载文件或目录失败的问题

    docker-compose.yml文件中允许使用'./'相对路径 version: '3' ... volumes: - ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro - ./mongo-volume:/data/db ... 会将当前路径下的init-mongo.js文件挂载到容器中的/docker-entrypoint-initdb.d/init-mongo.js,并且设置为只读方式; 会将当前路径下的mongo-

  • pyinstaller打包找不到文件的问题解决

    1.将python程序打包成单文件(使用 -F 参数)后,尝试运行外部文件却提示找不到的问题 当你将python程序打包成单文件(使用 -F 参数)后,运行程序,它实际上是先将exe内的资源文件解压到临时文件夹,然后再运行的,所以会导致这种问题 比如,当你在程序里面调用一个外部exe时,但却提示找不到该exe文件. 例子(这里我用win32api去隐式运行外部exe文件): import win32api win32api.ShellExecute(0, 'open', 'nginx.exe',

  • 解决Maven项目加载spring bean的配置xml文件会提示找不到问题

    Maven 加载spring bean的配置xml文件会提示找不到 如果你也在开发spring项目时用的是maven项目,如果出现运行是: ***xml can not open ,because it does not exist. 解决方法 很简单,因为maven需要将你的配置文件即***.xml放到根目录下,就是/src/main/java/这个目录下. 如果你把配置文件放到了自己新建的config文件夹中,记住也要放到这个目录里面,然后在 ApplicationContext ctx =

随机推荐