[英]Confused about CMD/ENTRYPOINT in Dockerfile
I am unsure what to use for ENTRYPOINT
vs CMD
for my Dockerfile
below. 我不确定要使用什么
ENTRYPOINT
VS CMD
我Dockerfile
以下。
FROM mongo:3.4-xenial
RUN apt-get update
RUN apt-get install -y software-properties-common
RUN apt-get install zip \
unzip
RUN apt-get install -y default-jdk
RUN apt-get update -y && \
apt-get clean
RUN mkdir -p /opt/project
COPY ./project-repo/target/project-repo.zip /opt/project
WORKDIR /opt/project
RUN unzip project-repo.zip
ENTRYPOINT echo '#!/bin/bash\n\
pidfile="${TMPDIR:-/tmp}/docker-entrypoint-temp-mongod.pid" \n\
rm -f "$pidfile" \n\
# start MongoDB here \n\
mongod --logpath /var/log/mongodb.log --dbpath /data/db/ --fork --pidfilepath "$pidfile" \n\
mongo=( mongo --host 127.0.0.1 --port 27017 --quiet ) \n\
# check to see that our "mongod" actually did start up (catches "--help", "--version", MongoDB 3.2 being silly, slow prealloc, etc) \n\
# https://jira.mongodb.org/browse/SERVER-16292 \n\
tries=30 \n\
while true; do \n\
if ! { [ -s "$pidfile" ] && ps "$(< "$pidfile")" &> /dev/null; }; then \n\
# bail ASAP if "mongod" is not even running \n\
echo >&2 \n\
echo >&2 "error: mongod does not appear to have stayed running -- perhaps it had an error?" \n\
echo >&2 \n\
exit 1 \n\
fi \n\
if mongo admin --eval "quit(0)" &> /dev/null; then \n\
# success! \n\
break \n\
fi \n\
(( tries-- )) \n\
if [ "$tries" -le 0 ]; then \n\
echo >&2 \n\
echo >&2 "error: mongod does not appear to have accepted connections quickly enough -- perhaps it had an error?" \n\
echo >&2 \n\
exit 1 \n\
fi \n\
sleep 1 \n\
done \n\
mongo -- admin <<-EOF \n\
db.createUser({user:"user", pwd:"admin123", roles:[{role:"root", db:"admin"}]}); \n\
EOF' >> ./init_mongo.sh && chmod +x ./init_mongo.sh && ./init_mongo.sh && \
chmod +x /opt/project/setup.sh && /opt/project/setup.sh all && \
chmod +x /opt/project/start.sh && /opt/project/start.sh all
EXPOSE 8080
CMD ["echo 'Welcome to Demo'"]
My MongoDB initialization is based on the one supplied with the standard image. 我的MongoDB初始化基于标准映像随附的初始化。 They use
mongod
as the CMD
. 他们使用
mongod
作为CMD
。
I need a few things - start mongo, create the user then run my scripts - setup and start. 我需要一些东西-启动mongo,创建用户,然后运行我的脚本-设置并启动。
There are no errors. 没有错误。 However, after
ENTRYPOINT
finishes doing its' thing, the container just exits. 但是,在
ENTRYPOINT
完成其操作后,容器将退出。 I want it to stay running!!! 我希望它继续运行!!!
My guess that my CMD
is wrong. 我猜我的
CMD
错误。 Please advise. 请指教。
Thank you 谢谢
After
ENTRYPOINT
finishes doing it's thing, the container just exits.ENTRYPOINT
完成操作后,容器就退出了。
This is a universal truth: the lifetime of a container is exactly the lifetime of the ENTRYPOINT
, or absent one, the CMD
. 这是一个普遍的事实:容器的生存期恰好是
ENTRYPOINT
的生存期,或者没有CMD
的生存期。
In terms of style, don't try writing very long scripts like that inline in a Dockerfile. 就样式而言,不要尝试在Dockerfile中内联编写很长的脚本。 Make it be a separate file,
COPY
it into the image, make sure it's executable, and just run it directly. 使它成为一个单独的文件,将其
COPY
到映像中,确保它是可执行文件,然后直接运行它。
The other style point is that it's very useful to get a debugging shell in a built image like 另一个样式要点是,在已构建的映像中获得调试外壳非常有用,例如
docker run --rm -it imagename bash
But, that form only overwrites the CMD
. 但是,该形式只会覆盖
CMD
。 That means you should generally put the command you want to run in CMD
exclusively. 这意味着通常应该只将要运行的命令放在
CMD
。 Since this will be the main container process, it must be something that stays running for as long as the container will be; 由于这将是主要的容器过程,因此它必须一直运行到容器将一直运行下去。 it can't be something like
start.sh
or service start
that tries to launch it in the background and immediately returns. 不能像
start.sh
或service start
试图在后台启动它并立即返回的东西。 For example, 例如,
CMD ["/opt/project/myservice", "--foreground"]
What good is ENTRYPOINT
, then? ENTRYPOINT
什么用呢? If you have both ENTRYPOINT
and CMD
, the ENTRYPOINT
will get run with the CMD
as command-line arguments. 如果您同时拥有
ENTRYPOINT
和CMD
,则ENTRYPOINT
将与CMD
作为命令行参数运行。 A very common pattern is to write a script that does some initial setup, then does exec "$@"
to run the command part. 一个非常常见的模式是编写一个脚本,该脚本进行一些初始设置,然后
exec "$@"
以运行命令部分。 From your example, 从您的例子来看,
#!/bin/sh
./init_mongo.sh
exec "$@"
And your combined Dockerfile could look more or less like 而且您组合的Dockerfile看起来或多或少像
FROM ubuntu:18.04
# ... other setup bits ...
WORKDIR /opt/project
COPY entrypoint.sh init_mongo.sh .
RUN chmod +x entrypoint.sh init_mongo.sh
ENTRYPOINT ["/opt/project/entrypoint.sh"]
CMD ["/opt/project/myservice", "--foreground"]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.