Docker 无法在容器启动时运行自定义脚本

Docker 无法在容器启动时运行自定义脚本,docker,dockerfile,clair,Docker,Dockerfile,Clair,我正在尝试设置Clair(Docker图像漏洞扫描工具) 我让Clair使用docker compose在本地正常工作。问题是,当我将其部署到AWS时,我需要指定postgres服务器地址、用户名和密码等。在构建映像时,postgres服务器地址未知,因此在构建Clair docker映像时无法包含它。它需要在容器/映像启动时进行定制 对于使用数据库的其他应用程序,我通常只需自定义docker映像,并添加一个脚本(在启动时运行),该脚本使用SED将正确的值(取自环境变量)插入到应用程序配置文件中

我正在尝试设置Clair(Docker图像漏洞扫描工具)

我让Clair使用docker compose在本地正常工作。问题是,当我将其部署到AWS时,我需要指定postgres服务器地址、用户名和密码等。在构建映像时,postgres服务器地址未知,因此在构建Clair docker映像时无法包含它。它需要在容器/映像启动时进行定制

对于使用数据库的其他应用程序,我通常只需自定义docker映像,并添加一个脚本(在启动时运行),该脚本使用SED将正确的值(取自环境变量)插入到应用程序配置文件中

例如:

Dockerfile

FROM quay.io/coreos/clair:latest

COPY /docker/clair/runtime.sh /runtime.sh
RUN chmod +x /runtime.sh

CMD ["/runtime.sh"]
FROM quay.io/coreos/clair:latest

RUN apk --no-cache upgrade
RUN apk add --no-cache curl py-pip bash postgresql-client figlet \
 && curl -L https://github.com/optiopay/klar/releases/download/v2.4.0/klar-2.4.0-linux-amd64 \
  > /usr/local/bin/klar \
 && chmod +x /usr/local/bin/klar \
 && pip install awscli

# Copy in custom Clair config file
COPY /docker/clair/config.yaml /etc/clair/config.yaml

# Env Vars for use with Klar CLI
ENV CLAIR_ADDR http://127.0.0.1:6060

# Copy runtime script & make it executable
COPY /docker/clair/runtime.sh /runtime.sh
RUN chmod +x /runtime.sh

# Override the parent images ENTRYPOINT
# Run a script on container startup which does a few things in addition to starting Clair at the end.
# Note, this script is a BASH script. It is critical that you install bash into the docker image or this script will
# fail with errors that are not very helpful.
ENTRYPOINT ["/runtime.sh"]
runtime.sh

sed-i-e“s、#POSTGRES#u SERVER、$POSTGRES#u SERVER、g”config.yaml

出于某种原因,上述方法无法用于Clair docker图像。这种方法对许多其他主流图像都有效,所以我认为这是克莱尔图像的特殊之处

我没有收到任何错误,它只是忽略dockerfile中的
CMD[“/runtime.sh”]
,并像平常一样启动

有人能指出我如何运行我的自定义脚本,或者指出实现相同功能的其他方法吗

==========使用解决方案更新===========

问题是Clair映像基于BusyBox,默认情况下,BusyBox使用
ash
shell,而我编写/正在使用的shell脚本是为
bash
shell编写的。也许这应该是显而易见的,但我对编写linux shell脚本有点陌生,还没有遇到过这一点

我在测试了mchawre的答案后意识到了这一点,该答案避免了我遇到的问题,因为它不使用shell脚本

因此,我使用的解决方案是将
bash
安装到映像中,然后我可以在容器启动时使用我常用的bashshell脚本

Dockerfile

FROM quay.io/coreos/clair:latest

COPY /docker/clair/runtime.sh /runtime.sh
RUN chmod +x /runtime.sh

CMD ["/runtime.sh"]
FROM quay.io/coreos/clair:latest

RUN apk --no-cache upgrade
RUN apk add --no-cache curl py-pip bash postgresql-client figlet \
 && curl -L https://github.com/optiopay/klar/releases/download/v2.4.0/klar-2.4.0-linux-amd64 \
  > /usr/local/bin/klar \
 && chmod +x /usr/local/bin/klar \
 && pip install awscli

# Copy in custom Clair config file
COPY /docker/clair/config.yaml /etc/clair/config.yaml

# Env Vars for use with Klar CLI
ENV CLAIR_ADDR http://127.0.0.1:6060

# Copy runtime script & make it executable
COPY /docker/clair/runtime.sh /runtime.sh
RUN chmod +x /runtime.sh

# Override the parent images ENTRYPOINT
# Run a script on container startup which does a few things in addition to starting Clair at the end.
# Note, this script is a BASH script. It is critical that you install bash into the docker image or this script will
# fail with errors that are not very helpful.
ENTRYPOINT ["/runtime.sh"]
runtime.sh(小摘录)

请查收

sed
命令放在dockerfile
CMD
中应该可以工作

CMD sed-i“s/localhost/$DB_HOST/”/config/config.yaml&&exec/clair-config=/config/config.yaml

这种方法似乎认可的是从源代码树中获取数据,根据口味对其进行定制,并使用
docker run-v
选项将其注入容器中。差不多吧

docker网络创建网络
docker run-d\
--网克莱尔网\
--姓名clairpg\
博士后:9.6
mkdir clair_配置
sed's/host=localhost/host=clairpg/'config.yaml.sample>clair_config/config.yaml
docker run-d\
--网克莱尔网\
-v$PWD/clair\u配置:/config\
-p 6060:6060\
-p 6061:6061\
码头io/coreos/clair:最新版本\
-config=/config/config.yaml
(这是一种非常有用的方法,可能比在容器启动时尝试修补配置文件更容易。)

如果您在Kubernetes中运行此程序,那么源代码树还包括一个头盔图表,在安装时使用。不过,这是一个非常特定于Kubernetes的解决方案,我不建议运行Kubernetes只是为了能够以这种方式运行

否则,您将无法查看(在存储库的根目录中)。这包括这一行:

ENTRYPOINT ["/usr/bin/dumb-init", "--", "/clair"]
如果您使用自己的
CMD
构建一个派生映像,该映像将作为附加参数传递给
ENTRYPOINT
,在本例中,这意味着它将作为参数传递给Clair;调用方不能提供备用命令、启动调试shell,或者在您的情况下,在不完全重写entrypoint值的情况下插入额外的启动时间步骤

您可以通过编写自己的入口点脚本来解决这个问题。我建议从设置步骤中分离出要运行的命令(
/clair
)。脚本可能看起来像

#!/bin/sh
# I am /docker-entrypoint.sh, with mode 0755
sed "s/host=localhost/host=$PGHOST/" /config/config.yaml.sample > /config/config.sample
exec /usr/bin/dumb-init -- "$@"
然后是派生的Dockerfile,比如

FROM quay.io/coreos/clair
COPY docker-entrypoint.sh /
RUN chmod 0755 /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["/clair"]

谢谢,这个答案很有效,也让我想出了如何让我的自定义脚本工作。我已经更新了我的问题,包括这些细节。也谢谢你的回答!