如果可能的话,我会尽量避免使用docker compose,因此我正在构建一个Dockerfile
,在Dockerfile中创建entrypoint.sh
。这完美地解决了一个问题——我需要接受entrypoint.sh
文件中的环境变量
这是我的Dockerfile
:的结尾
FROM kalilinux/kali-rolling
RUN echo "n##### Provision openvas user #####n" >> /opt/entrypoint.sh &&
echo "useradd -rm -d /home/openvas -s /bin/bash -g _gvm openvas" >> /opt/entrypoint.sh &&
echo "chown -R openvas:_gvm /home/openvas" >> /opt/entrypoint.sh &&
echo "gvmd --user=admin --new-password=${OV_PASSWORD}" >> /opt/entrypoint.sh &&
chmod +x /opt/entrypoint.sh
ENTRYPOINT ["/opt/entrypoint.sh"]
CMD ["tail", "-f","/dev/null"]
然而,当我尝试用docker run
启动容器并将环境变量传递给它时,由于一些格式错误,它似乎不起作用。下面是我正在运行的内容及其输出的示例:
ubuntu@ip-10-20-32-116:~/openvas$ docker run -e OV_PASSWORD=password -ti 05190b668480 /bin/bash
standard_init_linux.go:228: exec user process caused: exec format error
有没有想过这里会发生什么?我相信在我将${OV_PASSWORD}
添加到echo语句中时,错误就开始了。我也只尝试了OV_PASSWORD
,但也出现了类似的错误,所以不太确定我在格式化方面做错了什么。
在机械级别上,您可能会发现在主机上将入口点脚本创建为单独的文件更容易,然后简单地将其COPY
到图像中。这避免了@DannyB在回答中强调的引用问题。
FROM kalilinux/kali-rolling
COPY entrypoint.sh /opt/entrypoint.sh
# RUN chmod +x /opt/entrypoint.sh # if not already executable
ENTRYPOINT ["/opt/entrypoint.sh"]
CMD ["tail", "-f","/dev/null"]
确保脚本以行exec "$@"
结束以运行CMD
,并且Dockerfile中的ENTRYPOINT
行使用JSON数组语法。(评论表明您的设置已经正确。(
在您展示的设置中,每次启动容器时都会以完全相同的方式完成一些事情,并且这些事情可以重构为在构建映像时只运行一次。所以我可能会改为:
FROM kalilinux/kali-rolling
... do the other things to install the application ...
# Create a non-root user
RUN useradd -rM -g _gvm openvas
# Change file ownership so the non-root user can modify the application
# at runtime (not usually recommended)
# RUN chown -R openvas:_gvm /home/openvas
# Copy in the entrypoint script
COPY entrypoint.sh /opt/entrypoint.sh
# RUN chmod +x /opt/entrypoint.sh # if not already executable
# Specify how to run the container
USER openvas
ENTRYPOINT ["/opt/entrypoint.sh"]
CMD ["openvas", "-u"]
入口点仅包含
#!/bin/sh
# /opt/entrypoint.sh
# Configure the application password
if [ -n "$OV_PASSWORD" ]; then
gvmd --user=admin "--new-password=${OV_PASSWORD}"
fi
# Run the main container command
exec "$@"
当同时给定CMD
和ENTRYPOINT
时,CMD被视为入口点的默认输入。
我建议你去掉CMD,用docker logs <container-id>
代替
您的Dockerfile有几个问题。
CMD
被用作ENTRYPOINT
的参数,因此不会像您预期的那样运行- 当您使用变量
echo
,并且希望在回显期间不对变量求值时,请使用单引号 - 您的
ENTRYPOINT
不需要使用[...]
语法
要实现您想要的目标,请将tail -f
命令放在入口点内。
这是的工作样本
FROM alpine
RUN echo 'echo got password $PASS' > /opt/entrypoint.sh &&
echo "tail -f /dev/null" >> /opt/entrypoint.sh &&
chmod +x /opt/entrypoint.sh
ENTRYPOINT "/opt/entrypoint.sh"
运行方式:
$ docker run --rm -it -e PASS=123 your_image_name
RUN echo "n##### Provision openvas user #####n" >> /opt/entrypoint.sh &&
echo "useradd -rm -d /home/openvas -s /bin/bash -g _gvm openvas" >> /opt/entrypoint.sh &&
echo "chown -R openvas:_gvm /home/openvas" >> /opt/entrypoint.sh &&
echo "gvmd --user=admin --new-password=${OV_PASSWORD}" >> /opt/entrypoint.sh &&
chmod +x /opt/entrypoint.sh
您的shell脚本没有定义解释器,例如第一行通常为#!/bin/sh
。然后,您尝试使用exec从内核执行该脚本,而不是从默认使用自身来解释脚本的shell中执行,因为您的入口点使用了json/exec格式:
ENTRYPOINT ["/opt/entrypoint.sh"]
这就是触发的原因
standard_init_linux.go:228: exec user process caused: exec format error
也就是说,您的可执行文件/二进制文件的格式不适合内核运行。要修复,请使第一行成为图像中存在的外壳:
RUN echo '#!/bin/shn' > /opt/entrypoint.sh &&
echo 'n##### Provision openvas user #####n' >> /opt/entrypoint.sh &&
echo 'useradd -rm -d /home/openvas -s /bin/bash -g _gvm openvas' >> /opt/entrypoint.sh &&
echo 'chown -R openvas:_gvm /home/openvas' >> /opt/entrypoint.sh &&
echo 'gvmd --user=admin --new-password=${OV_PASSWORD}' >> /opt/entrypoint.sh &&
chmod +x /opt/entrypoint.sh