使用 docker-compose 将文件添加到标准图像

新手上路,请多包涵

我不确定是否有明显的东西逃脱了我,或者它是否不可能,但我正在尝试使用来自 docker hub 的图像组成整个应用程序堆栈。

其中之一是 mysql,它支持通过卷添加自定义配置文件并从安装目录运行 .sql 文件。

但是,我在运行 docker-compose 的机器上拥有这些文件,而不是在主机上。在运行入口点/cmd之前,是否无法从本地机器指定文件复制到容器中?我真的必须为这种情况创建所有内容的本地图像吗?

原文由 Andreas Wederbrand 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 370
2 个回答

如果你不能使用卷(想要无状态的 docker-compose.yml 并使用远程机器),你可以通过命令编写配置文件。

官方图片中的 nginx 配置示例:

 version: "3.7"

services:
  nginx:
    image: nginx:alpine
    ports:
      - 80:80
    environment:
      NGINX_CONFIG: |
        server {
          server_name "~^www\.(.*)$$" ;
          return 301 $$scheme://$$1$$request_uri ;
        }
        server {
          server_name example.com
          ...
        }
    command:
      /bin/sh -c "echo \"$$NGINX_CONFIG\" > /etc/nginx/conf.d/redir.conf; nginx -g \"daemon off;\""

环境变量也可以保存在 .env 文件中,您可以使用 Compose 的扩展功能或从 shell 环境加载它(您从其他地方获取它):

https://docs.docker.com/compose/compose-file/#env_file https://docs.docker.com/compose/compose-file/#variable-substitution

获取容器的原始入口点命令:

 docker container inspect [container] | jq --raw-output .[0].Config.Cmd

要调查修改哪个文件通常会起作用:

 docker exec --interactive --tty [container] sh

原文由 Bobík 发布,翻译遵循 CC BY-SA 4.0 许可协议

选项 A: 在图像中包含文件。这不太理想,因为您将配置文件与图像混合(实际上应该只包含您的二进制文件,而不是您的配置),但满足仅使用 docker-compose 发送文件的要求。

这个选项是通过使用 docker-compose 来构建你的镜像来实现的,并且该构建会将构建目录中的任何文件发送到远程 docker 引擎。您的 docker-compose.yml 看起来像:

 version: '2'

services:
  my-db-app:
    build: db/.
    image: custom-db

db/Dockerfile 看起来像:

 FROM mysql:latest
COPY ./sql /sql

入口点/cmd 将保持不变。如果图像已经存在并且您需要更改 sql 文件,则需要运行 docker-compose up --build


选项 B: 使用卷来存储数据。这不能直接在 docker-compose 内部完成。但是,这是将图像外部的文件包含到容器中的首选方式。您可以使用 docker CLI 和输入重定向以及 tar 之类的命令在网络上填充卷,以打包和解压缩通过标准输入发送的文件:

 tar -cC sql . | docker run --rm -it -v sql-files:/sql \
  busybox /bin/sh -c "tar -xC /sql"

通过脚本运行它,然后让相同的脚本反弹 db 容器以重新加载该配置。


选项 C: 使用某种网络附加文件系统。如果您可以在运行 docker CLI 的主机上配置 NFS,则可以使用以下选项之一从远程 docker 节点连接到这些 NFS 共享:

 # create a reusable volume
$ docker volume create --driver local \
    --opt type=nfs \
    --opt o=addr=192.168.1.1,rw \
    --opt device=:/path/to/dir \
    foo

# or from the docker run command
$ docker run -it --rm \
  --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,volume-opt=o=addr=192.168.1.1,volume-opt=device=:/host/path \
  foo

# or to create a service
$ docker service create \
  --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,volume-opt=o=addr=192.168.1.1,volume-opt=device=:/host/path \
  foo


选项 D: 使用 swarm 模式,您可以在映像中包含文件作为配置。这允许配置文件(通常需要推送到 swarm 中的任何节点)按需发送到运行服务的节点。这使用 docker-compose.yml 文件来定义它,但是 swarm 模式不使用 docker-compose 本身,所以这可能不符合您的特定要求。您可以运行单节点集群模式集群,因此即使您只有一个节点也可以使用此选项。此选项确实需要将每个 sql 文件作为单独的配置添加。 docker-compose.yml 看起来像:

 version: '3.4'

configs:
  sql_file_1:
    file: ./file_1.sql

services
  my-db-app:
    image: my-db-app:latest
    configs:
      - source: sql_file_1
        target: /sql/file_1.sql
        mode: 444

然后,您将运行 --- 而不是 docker-compose up docker stack deploy -c docker-compose.yml my-db-stack

原文由 BMitch 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题