首先,这个问题是不是问题的副本在这里。我目前正在学习 docker,并且需要创建一个在容器开始时使用以下命令dockerfile安装tomcat和运行它的entrypoint命令:
以下是我的内容dockerfile:
FROM ubuntu:latest
LABEL MAINTAINER="kesarling"
RUN apt update
RUN apt upgrade -y
RUN apt install apt-utils -y
RUN apt install maven gradle -y
RUN apt install wget tar zip unzip openjdk-14-jdk -y
RUN mkdir /usr/local/apache-tomcat-v8.5.55
RUN wget http://www-us.apache.org/dist/tomcat/tomcat-8/v8.5.55/bin/apache-tomcat-8.5.55.tar.gz -O /tmp/apache-tomcat-v8.5.55.tar.gz
RUN cd /tmp && tar xvfz apache-tomcat-v8.5.55.tar.gz
RUN cp -Rv /tmp/apache-tomcat-8.5.55/* /usr/local/apache-tomcat-v8.5.55/
RUN mkdir /usr/local/spring-v5.2.6
RUN wget https://repo.spring.io/release/org/springframework/spring/5.2.6.RELEASE/spring-5.2.6.RELEASE-dist.zip -O /tmp/spring-v5.2.6.zip
RUN cd /tmp && unzip spring-v5.2.6.zip
RUN cp -Rv /tmp/spring-framework-5.2.6.RELEASE/* /usr/local/spring-v5.2.6/
RUN cd ~
RUN touch server-start.sh
RUN echo "#!/bin/sh" | cat > server-start.sh
# start of condition
RUN echo 'bash -c "/usr/local/apache-tomcat-v8.5.55/bin/catalina.sh run&"' | cat >> server-start.sh
RUN echo "/bin/bash" | cat >>server-start.sh
# end of condition
RUN chmod +x server-start.sh
EXPOSE 8080
ENTRYPOINT [ "./server-start.sh" ]
Run Code Online (Sandbox Code Playgroud)
当服务器作为后台进程启动时,只有当我给出-it标志时它才能正常运行。否则,正如预期的那样,容器在我分离它的那一刻就退出了。
所以,简而言之:
docker container run -it -p 8080:8080 <mydockername>
Run Code Online (Sandbox Code Playgroud)
有效但:
docker container run -dp 8080:8080 <mydockername>
Run Code Online (Sandbox Code Playgroud)
没有(如预期的那样)。这就是条件出现的地方。简而言之,我需要它来检测 docker 是在后台运行还是在交互模式下运行。
中condition提到的blockdockerfile需要如下:
如果我使用-it标志执行它:
RUN echo 'bash -c "/usr/local/apache-tomcat-v8.5.55/bin/catalina.sh run&"' | cat >> server-start.sh
RUN echo "/bin/bash" | cat >>server-start.sh
Run Code Online (Sandbox Code Playgroud)
否则,如果我使用 -d 标志执行:
RUN echo 'bash -c "/usr/local/apache-tomcat-v8.5.55/bin/catalina.sh run"' | cat >> server-start.sh
Run Code Online (Sandbox Code Playgroud)
(注意/bin/bash已删除)
我该怎么做?
PS 这是我进入 docker 的第一周,所以请耐心等待我的 dockerfile :P
哦,更不用说搜索detect if the container has been run with an interactive flag没有带来任何有用的信息Google
在构建时,您不会知道运行时环境会是什么样子。因此,无法RUN根据-it标志或缺少标志来修改语句,我们没有时间旅行来展望未来,并且同一图像可以使用不同的标志多次运行。
您可以在入口点脚本中执行此操作。/dev/stdin映射到交互式容器的哪个将根据您是否有、或两者都没有/proc/self/fd/0指向不同的事物:-i-it
$ docker run -it --rm busybox ls -al /dev/stdin
lrwxrwxrwx 1 root root 15 Jun 18 14:43 /dev/stdin -> /proc/self/fd/0
$ docker run -it --rm busybox ls -al /proc/self/fd/0
lrwx------ 1 root root 64 Jun 18 14:43 /proc/self/fd/0 -> /dev/pts/0
$ docker run -i --rm busybox ls -al /proc/self/fd/0
lr-x------ 1 root root 64 Jun 18 14:50 /proc/self/fd/0 -> pipe:[9858991]
$ docker run --rm busybox ls -al /proc/self/fd/0
lrwx------ 1 root root 64 Jun 18 14:43 /proc/self/fd/0 -> /dev/null
Run Code Online (Sandbox Code Playgroud)
因此,如果您统计该链接以查看它/dev/null是否会出现,这将为您提供所问问题的答案。
旁注,如果您只关心-t,则可以运行另一个检查 shell,[ -t 0 ]例如:
$ docker run -it --rm busybox /bin/sh -c 'if [ -t 0 ]; then echo tty; else echo no tty; fi'
tty
$ docker run -i --rm busybox /bin/sh -c 'if [ -t 0 ]; then echo tty; else echo no tty; fi'
no tty
$ docker run --rm busybox /bin/sh -c 'if [ -t 0 ]; then echo tty; else echo no tty; fi'
no tty
Run Code Online (Sandbox Code Playgroud)
然而,docker 的最佳实践是在前台运行应用程序本身,作为 pid 1。如果您需要进入容器在开发环境中进行调试,请使用docker exec它。然后你的入口点变成:
ENTRYPOINT [ "/usr/local/apache-tomcat-v8.5.55/bin/catalina.sh", "run" ]
Run Code Online (Sandbox Code Playgroud)
通过这样做,您可以避免 pid 1 中出现额外的 shell,该 shell 可能会阻止容器停止信号正常停止应用程序。
然后要进行调试,您可以在运行后使用容器名称执行:
docker container run -dp 8080:8080 -n tomcat-app <mydockername>
docker container exec -it tomcat-app /bin/sh
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
228 次 |
| 最近记录: |