ChatGPT解决这个技术问题 Extra ChatGPT

在 Dockerfile 中运行脚本

我试图在我的 Dockerfile 中的构建过程中运行一个脚本,但它似乎不起作用。

我试过这样:

FROM php:7-fpm
ADD bootstrap.sh /
ENTRYPOINT ["/bin/bash", "/bootstrap.sh"]

也是这样:

FROM php:7-fpm    
ADD bootstrap.sh /
RUN bash -c "/bootstrap.sh"

并且还通过执行我正在运行的容器:

docker exec symfony /bin/bash -c "/bootstrap.sh"

似乎没有任何效果。

你知道怎么做吗?

bootstarp.sh 是否设置了可执行位?
像那个 RUN chmod +x /bootstarp.sh ?
对于“不起作用”,到底发生了什么?它是否显示错误?文件是否存在于图像中?如果您在容器内docker exec -it symfony bash,您可以手动运行脚本并检查其内容吗? (cat bootstarp.sh)?
试试这个:docker exec symfony /bin/bash /bootstarp.sh,让我知道输出。
Ermahgerd 引导程序!

F
Francis Chartrand

RUNENTRYPOINT 是执行脚本的两种不同方式。

RUN 表示它创建一个中间容器,运行脚本并将该容器的新状态冻结在一个新的中间映像中。该脚本将不会在此之后运行:您的最终图像应该反映该脚本的结果。

ENTRYPOINT 表示您的映像(尚未执行脚本)将创建一个容器并运行该脚本。

在这两种情况下,都需要添加脚本,RUN chmod +x /bootstrap.sh 是个好主意。

它还应该以 shebang 开头(如 #!/bin/sh

考虑到您的脚本(bootstrap.sh:几个 git config --global 命令),最好在 Dockerfile 中将该脚本RUN一次,但请确保使用正确的用户(全局 git config 文件是%HOME%/.gitconfig,默认情况下是 /root 之一)

添加到您的 Dockerfile:

RUN /bootstrap.sh

然后,在运行容器时,检查 /root/.gitconfig 的内容以确认脚本已运行。


此外,您可能指的是 bootstrap.sh 而不是 bootstarp.sh:请参阅 stackoverflow.com/a/1254561/6309
第一行的shebang为我做了,谢谢! :)
请检查开箱即用的 docker 图像 - hub.docker.com/repository/docker/myset/bootstrap
@myset 有趣的想法:执行 $BOOTSTRAP,在运行时将该变量设置为您想要执行的内容。
V
VeganHunter

除了上面的答案:

如果您在 Windows 中创建/编辑了 .sh 脚本文件,请确保它以 Unix 格式的行结尾保存。默认情况下,Windows 中的许多编辑器会将 Unix 行结尾转换为 Windows 格式,Linux 将无法识别文件开头的 shebang (#!/bin/sh)。所以Linux会产生错误信息,就像没有shebang一样。

提示:

如果使用 Notepad++,需要点击“编辑/EOL 转换/UNIX (LF)”

如果您使用 Visual Studio,我建议您安装“End Of Line”插件。然后,您可以通过按 Ctrl-R、Ctrl-W 使行尾可见。要设置 Linux 风格的结尾,您可以按 Ctrl-R、Ctrl-L。对于 Windows 样式,请按 Ctrl-R、Ctrl-C。


哇,你拯救了我的一天。这次真是万分感谢。
杰出的!这是我的确切问题!
我的 VSCode 在 Windows 中自动将 shell 脚本的行尾设置为 CRLF。由于一些随机字符,docker 构建失败。我更改了 VS Code 中的设置,它立即开始工作。谢谢!我投了赞成票。
在 Windows 上,git 默认使用 CR+LF 签出,这会在创建 docker 映像时导致 shell 脚本出现问题,因此您的回答真的很有帮助!
M
Michael

尝试使用 ADD 命令和工作目录规范创建脚本像这样(“script”是脚本的名称,/root/script.sh 是您希望它在容器中的位置,它可以是不同的路径:

ADD script.sh /root/script.sh

在这种情况下,ADD 必须在 CMD 之前,如果您有一个顺便说一句,将脚本从主机导入容器中的任何位置是一种很酷的方法

CMD[./script]

它应该自动执行你的脚本

您还可以将 WORKDIR 指定为 /root,然后在启动容器时自动将您置于 root 中


docker 最初是如何识别 script.sh 的位置的?我的意思是,第一个参数 script.sh
由于您正在构建容器,因此您还负责放置路径
第一个参数 script.sh 的路径和名称相对于 Dockerfile
@eja 似乎不是:“源代码必须位于运行 docker build 命令的目录中。”
r
rayryeng

当您从本地文件系统复制到映像时,最好使用 COPY 而不是 ADD。另外,我建议创建一个子文件夹来放置您的内容。如果不出意外,它会使事情保持整洁。确保使用 chmod 将脚本标记为可执行文件。

在这里,我正在创建一个 scripts 子文件夹来放置我的脚本并从以下位置运行它:

RUN mkdir -p /scripts
COPY script.sh /scripts
WORKDIR /scripts
RUN chmod +x script.sh
RUN ./script.sh

D
Danwand N S
WORKDIR /scripts
COPY bootstrap.sh .
RUN ./bootstrap.sh