【问题标题】:how to run .sh file when container is running using dockerfile容器运行时如何使用 dockerfile 运行 .sh 文件
【发布时间】:2019-12-11 04:13:31
【问题描述】:

我正在制作一个 dockerfile 来安装 elasticsearch:6.5.4 并将一些文件添加到所需位置并运行名为 test.sh 的脚本以在 elasticsearch 运行时在 elasticsearch 中创建新索引。

我不确定是否应该使用 RUN、CMD 或 ENTRYPOINT 来执行此操作。

通过注释我的最后一行(包含 RUN/CMD/ENTRYPOINT test.sh),我已经成功构建了一个映像并运行了一个容器。我能够从容器的 bash 运行 test.sh 并获得所需的结果。

但是当我尝试为同一进程构建映像时,我收到以下错误:

$ docker build -t es .
Sending build context to Docker daemon  7.499MB
Step 1/8 : FROM elasticsearch:6.5.4
 ---> 93109ce1d590
Step 2/8 : WORKDIR /app
 ---> Running in 6b6412093d53
Removing intermediate container 6b6412093d53
 ---> a374ab69eb1a
Step 3/8 : ADD . /app
 ---> 6ed98ee7ad49
Step 4/8 : COPY test.sh .
 ---> 42184ec64c09
Step 5/8 : ADD analysis /usr/share/elasticsearch/config/analysis
 ---> 5a96f2098dd7
Step 6/8 : EXPOSE 9202
 ---> Running in 6c44b54dcc77
Removing intermediate container 6c44b54dcc77
 ---> d8723189c843
Step 7/8 : EXPOSE 9200
 ---> Running in c571b4cba1fa
Removing intermediate container c571b4cba1fa
 ---> 8fa11b03051e
Step 8/8 : RUN "sh test.sh"
 ---> Running in cf2e8cb3fd37
/bin/sh: sh test.sh: command not found
The command '/bin/sh -c "sh test.sh"' returned a non-zero code: 127

我已经为第 8 步尝试了不同的 RUN、CMD 和 ENTRYPOINT 组合

我的dockerfile如下:

FROM elasticsearch:6.5.4
WORKDIR /app
ADD . /app
COPY test.sh .
ADD analysis /usr/share/elasticsearch/config/analysis

EXPOSE 9202
EXPOSE 9200

RUN "sh test.sh"

我想在容器中运行 elasticsearch 并为 elasticsearch 创建一个新索引

【问题讨论】:

    标签: bash docker elasticsearch dockerfile


    【解决方案1】:

    在纯粹的机械层面上,报价会造成麻烦。当你说

    RUN "sh test.sh"
    

    它尝试运行一个名为sh\ test.sh 的命令;它不会尝试以test.sh 作为参数运行sh。以下任何一项都将实际运行脚本

    RUN ["sh", "test.sh"]
    RUN sh test.sh
    RUN chmod +x test.sh; ./test.sh
    

    在操作级别上,在服务器容器中运行该命令会遇到很多麻烦。最大的问题是您需要在服务器已经启动并运行之后运行该命令。所以你根本不能在 Dockerfile 中运行它(没有服务在 RUN 命令中运行)。一个容器运行一个进程,您需要该进程作为 Elasticsearch 服务器本身,因此您不能直接在 ENTRYPOINTCMD 中执行此操作。

    最简单的方法是从主机运行此命令:

    docker build -t my/elasticsearch .
    docker run -d --name my-elasticsearch -p 9200:9200 my/elasticsearch
    curl http://localhost:9200  # is it alive?
    ./test.sh
    

    如果您有 Docker Compose 设置,您也可以从单独的容器中运行它,或者您可以将它作为应用程序容器启动的一部分运行。在ENTRYPOINT 脚本中为您的应用程序容器运行数据库迁移有一些很好的示例,这基本上就是您正在寻找的模式。

    理论上可以在入口点脚本中运行它。你必须启动服务器,等待它启动,运行你的脚本,停止服务器,最后@987654332 @ 运行 CMD。这对于 Elasticsearch 来说比较棘手,您可能需要连接到同一 Elasticsearch 集群中的其他服务器,以免您的状态不同步。官方 Docker Hub mysql 这样做,对于非集群数据库服务器;有关想法,请参阅 its rather involved entrypoint script。)

    【讨论】:

      【解决方案2】:

      RUN "sh test.sh"

      去掉引号。您的脚本将尝试运行名为sh test.sh(带空格)的命令。

      【讨论】:

        【解决方案3】:

        在深入了解您的问题后,我认为您错过了一步,请在运行实际脚本之前运行chmod +x test.sh 命令,因为它可能无法在容器环境中执行。另外,我个人更喜欢使用 bash 运行 shell 脚本。

        Dockerfile:

        FROM elasticsearch:6.5.4
        WORKDIR /app
        ADD . /app
        COPY test.sh .
        ADD analysis /usr/share/elasticsearch/config/analysis
        
        EXPOSE 9202
        EXPOSE 9200
        
        RUN chmod +x test.sh
        RUN bash test.sh
        

        【讨论】:

        • 如果您使用bash scriptnamesh scriptname 运行它,则无需chmod 它。建议人们更喜欢 Bash 而不是 sh 充其量是可疑的。至少,您应该解释存在差异。 (另见Difference between sh and bash
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        • 2016-08-08
        • 2021-12-23
        • 2019-10-08
        • 1970-01-01
        • 2012-03-07
        • 1970-01-01
        相关资源
        最近更新 更多