如何在 Dockerfile 中访问 docker-compose 卷挂载的文件?



工作区文件夹结构(=my_application):

➜ tree -L 2
.
├── Dockerfile
├── docker-compose.yml
├── configs
│     ├── configure_all.sh
│     ├── create_connections.sh
│     ├── requirements
│     └── variables.json
...

docker-compose.yml:

services:
my_service:
build: .

...

volumes:
- .:/opt/my_application
...

注意,整个工作空间目录都挂载在/opt/my_application上。

最后,Dockerfile:
FROM ubuntu
USER root
RUN apt-get update 
&& apt-get install -y --no-install-recommends 
build-essential gcc git wget unzip 
&& apt-get autoremove -yqq --purge 
&& apt-get clean 
&& rm -rf /var/lib/apt/lists/*
RUN sh /opt/my_application/configs/configure_all.sh

但是这引发了一个错误,因为/opt/my_application/在构建时还没有挂载。

我知道我可以使用类似COPY命令的东西,但它使我每次更改(或修复)configs中的任何文件时都要构建图像,这真的很烦人。我想利用docker-compose.ymlvolumes,它可以连续同步更改。

有什么办法可以做到吗?

你不能按照你描述的方式来做。从本质上讲,卷在构建映像之前不会被挂载。您可以在同一个映像上运行多个容器,可能会挂载不同(或没有)卷,并且映像不会重新构建。

…每次我更改(或修复)configs…中的任何文件时构建映像

将您的应用程序分成几个不同的部分可能会有所帮助:

  1. 你有应用程序本身,它不会改变,当它被重新运行。
  2. 你有configs,可以不同的运行。
  3. 你有应用程序运行时生成的任何数据,当它结束时可以丢弃。

你可以使用Docker绑定挂载注入配置,即使应用程序的其余部分已经"嵌入"了。到图像。

我建议做的第一件事,然后,在应用程序代码中更新你的Dockerfile到COPY,RUN任何你需要运行来构建它的命令,并设置默认的CMD来运行应用程序。良好的第一步是在图像中内置configs的情况下运行此操作。

设置的一个复杂之处在于注入的配置的一部分是一个可运行的脚本。由于这来自绑定挂载,因此在容器启动之前脚本将不可用。您可以使用入口点包装器脚本在容器启动时运行此脚本:提供一个shell脚本,作为映像的ENTRYPOINT运行,执行任何初始设置,然后以exec "$@"结束以运行映像的CMD

#!/bin/sh
# docker-entrypoint.sh
# If the configuration includes an initialization script, run it
if [ -x ./configs/configure_all.sh ]; then
./configs/configure_all.sh
fi
# Run the main container CMD
exec "$@"

(由于这是一个shell脚本,您可以做任何shell脚本可以做的事情。例如,如果脚本设置环境变量,您可以使用内置的.在包含shell中设置它们;或者您可以根据是否设置了变量或是否存在文件来设置逻辑;或……)

在Dockerfile中,保持CMD不变,但将此脚本添加为ENTRYPOINT

COPY docker-entrypoint.sh .           # if a `COPY . .` doesn't already include it
ENTRYPOINT ["./docker-entrypoint.sh"] # must be JSON-array syntax
CMD the_application                   # same as before
最后,当您启动应用程序时,使用docker run -v绑定挂载到,只有注入configs目录;不要用绑定挂载覆盖主应用程序代码。
volumes:
- ./configs:/opt/my_application/configs

如果你想检查发生了什么,docker-compose run启动一个交互式调试shell将取代CMD而不是ENTRYPOINT,这意味着安装包装器仍然会运行,但会启动交互式shell而不是主应用程序。

docker-compose run my_service 
cat /opt/my_application/etc/output_of_configure_all.sh
# ^^^ runs _after_ the setup in the entrypoint script
#     runs _instead of_ the default container CMD (or Compose command:)

相关内容

  • 没有找到相关文章

最新更新