对Dockerfile中的CMD / ENTRYPOINT感到困惑

时间:2019-09-11 14:10:05

标签: mongodb docker dockerfile

对于下面的parseInt(month),我不确定var date = "17-09-2019"; var [day, month, year] = date.split('-'); console.log(`${day}-${month}-${year}`) var set_date = new Date(parseInt(year), parseInt(month) - 1, parseInt(day)); console.log(set_date);ENTRYPOINT用什么。

CMD

我的MongoDB初始化基于标准映像随附的初始化。他们将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'"]

我需要一些东西-启动mongo,创建用户,然后运行我的脚本-设置并启动。

没有错误。但是,在mongod完成其操作之后,容器将退出。我希望它保持运行状态!

我猜我的CMD是错误的。请告知。

谢谢

1 个答案:

答案 0 :(得分:0)

  

ENTRYPOINT完成操作后,容器将退出。

这是一个普遍的事实:容器的生存期恰好是ENTRYPOINT的生存期,或者没有CMD的生存期。

就样式而言,请勿尝试在Dockerfile中内联编写非常长的脚本。使其成为一个单独的文件,COPY放入图像,确保其可执行文件,然后直接运行。

另一个样式要点是,在构建的映像中获得调试外壳非常有用,例如

docker run --rm -it imagename bash

但是,该形式只会覆盖CMD。这意味着通常应将要运行的命令专门放在CMD中。由于这将是主要的容器过程,因此它必须一直运行到容器将一直运行下去。不能像start.shservice start这样试图在后台启动它并立即返回的东西。例如,

CMD ["/opt/project/myservice", "--foreground"]

ENTRYPOINT有什么用处呢?如果同时具有ENTRYPOINTCMD,则ENTRYPOINT将以CMD作为命令行参数运行。一个非常常见的模式是编写一个脚本,进行一些初始设置,然后执行exec "$@"来运行命令部分。在您的示例中,

#!/bin/sh
./init_mongo.sh
exec "$@"

您合并的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"]