如何将 docker ENTRYPOINT 与 shell 脚本文件组合参数一起使用

imo*_*ori 3 bash shell docker

我编写了 shell 脚本文件并将其与 docker ENTRYPOINT 一起使用,但是当我运行 docker image 时,它​​会因为入口点代码行而停止而没有任何错误日志

我的 Dockerfile

FROM ubuntu:16.04
MAINTAINER limtaegeun <imori333@gmail.com>

RUN apt-get update
RUN apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf

# Define mountable directories.
VOLUME ["/etc/nginx/sites-enabled", "/etc/nginx/certs", "/etc/nginx/conf.d", "/var/log/nginx", "/var/www/html"]

ENV CONTAINER_NAME nodejs
ENV SERVER_NAME myserver.com
ENV PEM_PATH /etc/nginx/certs/cert.pem
ENV KEY_PATH /etc/nginx/certs/cert.key

WORKDIR /etc/nginx

ADD ./sites-available/ssl /etc/nginx/sites-available/ssl
ADD ./docker-entrypoint.sh /etc/nginx/docker-entrypoint.sh
RUN chmod 777 /etc/nginx/docker-entrypoint.sh
EXPOSE 80 443
ENTRYPOINT /etc/nginx/docker-entrypoint.sh ${CONTAINER_NAME} ${SERVER_NAME} ${PEM_PATH} ${KEY_PATH}
CMD ["nginx"]
Run Code Online (Sandbox Code Playgroud)

docker-entrypoint.sh

#!/bin/sh

CONTAINER_NAME=$1
SERVER_NAME=$2
PEM_PATH=$3
KEY_PATH=$4

rm -f /etc/nginx/sites-enabled/default
sed -ri 's@CONTAINER_NAME@'${CONTAINER_NAME}'@' /etc/nginx/sites-available/ssl
sed -ri 's@SERVER_NAME@'${SERVER_NAME}'@' /etc/nginx/sites-available/ssl
sed -ri 's@PEM_PATH@'${PEM_PATH}'@' /etc/nginx/sites-available/ssl
sed -ri 's@KEY_PATH@'${KEY_PATH}'@' /etc/nginx/sites-available/ssl
# cp -f sites-available/ssl sites-available/default
ln -s /etc/nginx/sites-available/ssl /etc/nginx/sites-enabled/default
Run Code Online (Sandbox Code Playgroud)

我的 docker 运行命令

docker run -v /home/ubuntu/Docker-nginx-cloudflare-ssl-proxy/certs:/etc/nginx/certs \
--name nginx-ssl -p 443:443 -p 80:80 --network nginx-net --rm -d nginx-cloudfare-ssl-proxy
Run Code Online (Sandbox Code Playgroud)

什么问题??

Dav*_*aze 6

当 Docker 容器运行时,它运行ENTRYPOINT(仅),传递CMDas 命令行参数,并在ENTRYPOINT完成时退出容器。在 Dockerfile 中,ENTRYPOINT它必须是 JSON 数组语法才能看到CMD参数,并且脚本本身需要实际运行CMD,通常使用像exec "$@".

您可以做的最简单的清理事情就是不要尝试在环境变量和位置参数之间来回切换。该ENTRYPOINT脚本将能够直接读取ENV您在 Dockerfile 中设置的变量(或使用docker run -e选项覆盖)。因此,如果您从位置参数中删除设置这些变量的脚本的第一行,并确保运行CMD

#!/bin/sh
# delete the lines that set CONTAINER_NAME et al.
rm -f /etc/nginx/sites-enabled/default
sed -ri 's@CONTAINER_NAME@'${CONTAINER_NAME}'@' /etc/nginx/sites-available/ssl
...
# and add this at the end
exec "$@"
Run Code Online (Sandbox Code Playgroud)

然后将 Dockerfile 更改为不传递位置参数但使用 JSON 数组语法 ENTRYPOINT

ENTRYPOINT ["/etc/nginx/docker-entrypoint.sh"]
CMD ["nginx"]
Run Code Online (Sandbox Code Playgroud)

这应该让你离开地面。

值得考虑您实际需要配置多少。例如,您是否需要/etc/nginx/certs与隔离容器文件系统空间内的默认路径不同的路径?通常使用标准的nginx Docker Hub 映像,您可以通过注入完整的配置文件来使用它,如果您选择这样做,它会简化您的 Docker 设置。

其他一般性建议:删除VOLUME声明(它们可能会在 Dockerfile 稍后导致混淆行为并泄漏匿名卷,否则没有必要);不要使可执行文件世界可写 ( chmod 0755, not 0777); RUN apt-get update && apt-get install在同一个 Dockerfile 命令中。