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

问题描述 投票:22回答:5

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

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

但是,我在运行docker-compose的机器上有这些文件,而不是在主机上。在运行entrypoint / cmd之前,是否无法指定本地计算机中的文件复制到容器中?我是否真的必须为这种情况创建一切的本地图像?

docker docker-compose
5个回答
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


24
投票

选项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之类的命令来打包和解压缩通过stdin发送的文件:

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模式,您可以在文件中包含文件作为配置。这允许通常需要将推送到群中任何节点的配置文件按需发送到运行服务的节点。这使用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


6
投票

这就是我用卷来做的事情:

services:
  my-db-app:
    command: /shell_scripts/go.sh
    volumes:
      - ./shell_scripts:/shell_scripts 

0
投票

作为此问题的最新更新:例如,通过在亚马逊上托管的docker swarm,您可以定义一个可以由服务共享的卷,并且可以在群的所有节点上使用(使用cloudstor驱动程序,后者又具有AWS EFS坚持不懈)。

version: '3.3'
services:
  my-db-app:
    command: /shell_scripts/go.sh
    volumes:
      shell_scripts:/shell_scripts 
volumes:
    shell_scripts:
      driver: "cloudstor:aws"

0
投票

我认为你必须在一个撰写文件中做:

volumes:
 - src/file:dest/path
© www.soinside.com 2019 - 2024. All rights reserved.