我正在编写一个运行如下的 C++ 程序:
./program data_file config_file
Run Code Online (Sandbox Code Playgroud)
我想和它一起使用 docker。我写了以下内容Dockerfile:
FROM gcc:7.2.0
ENV MYP /repo
WORKDIR ${MYP}
COPY . ${MYP}
RUN /bin/sh -c 'make'
ENTRYPOINT ["./program"]
CMD ["file1", "file2"]
Run Code Online (Sandbox Code Playgroud)
所以我docker build -t test .使用它并使用docker run test默认值查看一切正常。
但是,如果我file1在我的工作目录中修改(构建之后),我注意到当我运行时docker run test file1 file2,被file1调用的是容器内的那个,作为参数输入的那个被忽略了。
同样,如果我使用重命名的数据和配置文件并运行docker run test file3 file4,我会收到一条错误消息,指出这些文件不存在(因为它们不在容器中)。
那么,如何让 docker 识别这些作为参数传递的输入文件,避免使用图像中包含的文件?
Docker 版本为 18.04.0-ce,构建 3d479c0af6。
编辑
另一种选择是使用如下launch.sh脚本:
#!/bin/sh
./program "${DATA_FILE}" "${CONFIG_FILE}"
Run Code Online (Sandbox Code Playgroud)
所以ENTRYPOINT和CMD指令被 Dockerfile 中的以下行替换:
CMD ["./launch.sh"]
Run Code Online (Sandbox Code Playgroud)
但是现在如果我运行:
docker run test -e DATA_FILE=file1 -e CONFIG_FILE=file2
Run Code Online (Sandbox Code Playgroud)
我收到权限错误...
docker:来自守护进程的错误响应:OCI 运行时创建失败:container_linux.go:348:启动容器进程导致“exec:\”-e\“:在 $PATH 中找不到可执行文件”:未知。ERRO[0000] 错误等待容器:上下文取消
您可以使用卷机制将主机目录挂载到容器。
在主机的某个目录中创建file1.txt和file2.txt文件。例如我们在/var/dir1/目录中创建文件。
您在 docker 容器中的工作目录是/program.
因此,当您运行 docker 时,您应该使用-v 标志将此主机目录挂载到容器
docker run -v /var/dir1/:/program test file1.txt file2.txt
Run Code Online (Sandbox Code Playgroud)
哦,我知道我们为什么有问题。 
当我将主机目录安装到工作目录时,我实际上是从它的工作目录中删除容器内所有创建的文件,包括./program二进制文件。所以docker run命令失败。
因此我们不必挂载工作目录。例如,我们可以挂载工作目录的子目录。
 docker run -v /var/dir1/:/program/dir test dir/file1.txt dir/file2.txt 
Run Code Online (Sandbox Code Playgroud)
这个对我有用!