一旦通过run命令调用docker容器,我希望自动执行两个单独的JAR文件,因此当我键入docker run mycontainer
时,它们都被调用。到目前为止,我有一个看起来像这样的dockerfile:
# base image is java:8 (ubuntu)
FROM java:8
# add files to image
ADD first.jar .
ADD second.jar .
# start on run
CMD ["/usr/lib/jvm/java-8-openjdk-amd64/bin/java", "-jar", "first.jar"]
CMD ["/usr/lib/jvm/java-8-openjdk-amd64/bin/java", "-jar", "second.jar"]
但是,这只会启动second.jar。
现在,两个罐子都是循环中的服务器,所以我想一旦启动它就会阻塞终端。如果我使用run -it mycontainer bash
运行容器并手动调用它,第一个将执行其输出,而我无法启动另一个。
有没有办法打开不同的终端并在它们之间切换,让每个JAR在自己的上下文中运行?最好已经在dockerfile中。
我对ubuntu几乎一无所知,但我找到了xterm
命令,它打开了一个新的终端,但是在调用JAR之后这不会起作用。我正在寻找的是dockerfile内部的指令,例如打开一个新终端,执行first.jar,alt-tab到旧终端并执行second.jar,或至少实现相同。
谢谢!
答案 0 :(得分:2)
Docker容器在启动时只有一个进程。
之后您仍然可以创建多个流程。:
答案 1 :(得分:2)
第二条CMD指令替换第一条指令,因此您需要对两个命令使用单条指令。
简单(不太好)方法
您可以添加一个bash脚本,在第二个上执行命令和块:
# start.sh
/usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar first.jar &
/usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar second.jar
然后将Dockerfile更改为:
# base image is java:8 (ubuntu)
FROM java:8
# add files to image
ADD first.jar .
ADD second.jar .
ADD start.sh .
# start on run
CMD ["bash", "start.sh"]
使用docker stop
时可能无法正常关闭,请参阅:
https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/
更好的方法
要解决此问题,您可以使用Phusion:
https://hub.docker.com/r/phusion/baseimage/
它有一个比使用它更容易使用的init系统。 supervisord。
这是一个很好的起点: https://github.com/phusion/baseimage-docker#getting_started
使用错误的说明
可悲的是,Ubuntu 14.04 LTS没有正式的openjdk-8-jdk。您可以尝试使用非官方的ppa,用于以下说明。
在您的情况下,您需要打击脚本(其行为类似于"服务"):
# start-first.sh (the file has to start with the following line!):
#!/bin/bash
usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar /root/first.jar
# start-second.sh
#!/bin/bash
usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar /root/second.jar
你的Dockerfile看起来像这样:
# base image is phusion
FROM phusion/baseimage:latest
# Use init service of phusion
CMD ["/sbin/my_init"]
# Install unofficial openjdk-8
RUN add-apt-repository ppa:openjdk-r/ppa && apt-get update && apt-get dist-upgrade -y && apt-get install -y openjdk-8-jdk
ADD first.jar /root/first.jar
ADD second.jar /root/second.jar
# Add first service
RUN mkdir /etc/service/first
ADD start-first.sh /etc/service/first/run
RUN chmod +x /etc/service/first/run
# Add second service
RUN mkdir /etc/service/second
ADD start-second.sh /etc/service/second/run
RUN chmod +x /etc/service/second/run
# Clean up
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
这应安装两个服务,这些服务将在启动时运行,并在使用docker stop
时正常关闭。
答案 2 :(得分:1)
您有几个选择。很多答案都提到过使用主管,这是一个很好的解决方案。以下是其他一些内容:
创建一个简短的脚本,只需启动两个罐子。将其添加到您的CMD。例如,我们称之为run_jars.sh
的脚本可能如下所示:
/usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar first.jar;
/usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar second.jar;
然后你的CMD将是CMD sh run_jars.sh
另一个选择是运行两个单独的容器 - 一个用于first.jar
,另一个用于second.jar
。您可以通过docker run
运行每一个,例如:
docker run my_repo/my_image:some_tag /usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar second.jar
答案 3 :(得分:0)
如果您想在一个泊坞窗容器内启动两个不同的进程(不是推荐的行为),您可以使用类似supervisord
的内容