我有一个脚本/init
,该脚本启动apache和neo4j。该脚本已经在图像ubuntu:14
中。以下是/init
的内容:
service apache2 start
service neo4j start
根据该图像,我正在使用以下dockerfile创建另一个图像
FROM ubuntu:v14
EXPOSE 80 80
ENTRYPOINT ["/init"]
当我运行命令docker run -d ubuntu:v15
时,容器将启动,然后退出。据我了解,-d
选项在后台运行容器。另外,脚本\init
启动两个守护程序。 为什么容器会退出?
答案 0 :(得分:1)
当您的Dockerfile指定ENTRYPOINT时,容器的生存期正好是其过程的长度。通常,service ... start
的行为是将服务作为后台进程启动,然后立即返回;因此,您的/init
脚本运行了两个service
命令并完成了,现在入口点过程完成了,容器退出了。
通常公认的最佳实践是在容器中仅运行一个进程。当其中一个进程是数据库时,尤其如此。在您的情况下,有标准的Docker Hub Apache httpd
和neo4j
映像,因此我将首先使用Docker Compose之类的编排工具来并行运行这两个容器。>
答案 1 :(得分:1)
事实上,我认为您的第一个问题是#!
文件中的init
,如果您一开始没有添加类似#!/bin/bash
的内容,那么容器会像下面这样抱怨:>
shubuntu1@shubuntu1:~$ docker logs priceless_tu
standard_init_linux.go:207: exec user process caused "exec format error"
但是即使您解决了上述问题,您仍然无法启动容器,原因与其他人说的一样:PID 1应该一直存在,在您的情况下,service xxx start
完成之后,PID 1退出这也会导致容器退出。
因此,要解决此问题,您应该设置一个命令永不退出,这是一个可供参考的最小可行示例:
Dockerfile:
FROM ubuntu:14.04
RUN apt-get update && \
apt-get install -y apache2
COPY init /
RUN chmod +x /init
EXPOSE 80
ENTRYPOINT ["/init"]
初始化:
#!/bin/bash
# you can add other service start here
# e.g. service neo4j start as you like if you have installed it already
# next will make apache run in foreground, so PID1 not exit.
/usr/sbin/apache2ctl -DFOREGROUND