bash - 如何在容器运行时使用 dockerfile 运行 .sh 文件

标签 bash docker elasticsearch dockerfile

我正在制作一个 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

我已经为 STEP 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创建一个新的索引

最佳答案

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

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 脚本中为您的应用程序容器运行数据库迁移的好例子,这基本上就是您正在寻找的模式。

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

关于bash - 如何在容器运行时使用 dockerfile 运行 .sh 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57328079/

相关文章:

linux - 在终端中记录任何内容

bash - :'END'在bash中如何工作以创建多行注释 block ?

python - 在 elasticsearch 中索引/搜索 "complex"JSON

linux - 如何只监听inotifywait中的特定事件?

linux - 每秒将时间列为 Bash 脚本

docker - 是否可以集成SonarQube,Jenkins和GitLab(全部在docker中)?

docker - netcat 未在 docker 内返回

linux - 如何设置 'docker logs -t' 的时区?

python - 使用elasticsearch的jupyter python笔记本

json - 从输出中隐藏time_out,_shards,max_score和其他默认字段