Docker:使用docker-compose复制文件和目录

12

我为定制应用程序创建了一个Docker镜像,该应用程序需要一些许可证文件(一些文件和一个目录)才能运行,因此我在Dockerfile中使用COPY命令将许可证文件复制到镜像中:

# Base image: Application installed on Debian 10 but unlicensed
FROM me/application-unlicensed

# Copy license files
COPY *.license /opt/application/
COPY application-license-dir /var/lib/application-license-dir

我使用这个 Dockerfile 为单个容器构建一个新的带有许可证的镜像。由于我有5种不同的许可证,我创建了5个不同的镜像,每个镜像都有一个特定的许可证文件和目录。

这些许可证也被固定到一个MAC地址,因此当我运行其中的一个容器时,我会使用 --mac-address 参数指定它自己的MAC地址:

docker run --rm --mac-address AB:CD:EF:12:34:56 me/application-license1

我的方法可以工作,但我希望有更好、更智能的方法来管理这个:

docker-compose 与指定容器 MAC 地址类似,我是否可以只使用未经许可的基本镜像,在构建 5 个容器时复制许可文件和许可目录?


编辑:让我更好地解释一下许可文件的结构

应用程序部署在 Docker 镜像的 /opt/application 目录中。

许可文件 (*.license) 与应用程序本身位于同级别的 /opt/application 中,因此除非我创建一些符号链接(但我必须检查应用程序是否能以这种方式工作),否则无法将其保存到 Docker 卷中。

应用程序许可目录需要位于 /var/lib/application-license-dir,以便可以将其挂载到 Docker 卷中(我必须检查应用程序是否能工作,但我认为是可以的)。

*.license 文件以及 application-license-dir 中的文件都是二进制的,因此我无法在运行时编写脚本或创建它们。

所以:

  1. docker-compose 是否可以在绑定和挂载到 Docker 卷之前在 Docker 主机服务器上创建一个本地目录?
  2. docker-compose 是否可以从 Git 仓库(本地克隆)将我的许可证文件和许可证目录复制到第一步创建的本地目录中?
  3. docker-compose 是否可以为存储在卷中的 *.license 文件在容器的/opt/application 目录中创建一些符号链接?
3个回答

7

如果每次运行容器或在不同系统上运行容器时都有所不同的内容,通常不希望在Dockerfile中指定这些内容。 这包括您上面显示的许可文件; 用户ID等也符合此模式;根据您的配置文件的固定程度,它们也可以计入其中。(对于每次运行容器都相同的内容,例如应用程序源代码,确实需要将其放在映像中。)

您可以使用Docker 绑定挂载在运行时将文件注入容器中。 使用volumes:指令的Compose语法进行绑定挂载。

这样会给您一个大致如下的Compose文件:

version: '3'
services:
  app1:
    image: me/application-unlicensed
    volumes:
      - './app1.license:/opt/application/app.license'
      - './application-license-dir:/var/lib/application-license-dir'
    mac_address: 'AB:CD:EF:12:34:56'

像这样的绑定挂载在将配置文件推送到容器时非常合适。它们可以提供一个空的主机目录,其中日志文件可以被写入,但不是将数据从镜像中复制出来的机制。如果您的应用程序无法将其所有状态存储在外部数据库中,则它们也可以作为存储需要超越容器生命周期的数据的地方。


1
谢谢!app1.license卷可以是一个文件吗?所以我的理解是Docker Compose不能动态部署容器,因此我应该创建一些脚本(例如Fabric)将许可证文件复制到卷目录中,并根据我正在部署的许可证创建Docker Compose文件(我有5个许可证,每个许可证都有不同的文件/目录,一个许可证可以有不同数量的.license文件要复制到附加到容器的卷上)。 - Mat
2
可以的。如果您仔细查看该行,我打算将特定于容器的app1.license文件挂载到容器中固定的/opt/application目录中,因此您可以为每个容器重复此操作(使用不同的文件)。 - David Maze

3
根据这个提交,docker-compose现在支持mac_address。可以通过使用-v选项挂载许可文件。

1

您可以为不同的容器设置MAC地址,例如:mac_address: AB:CD:EF:12:34:12。有关详细信息,请参见此处

如果要从相同的镜像创建多个实例,则必须在docker-compose文件中复制每个应用程序块5次,并在每个块中设置不同的MAC地址。


2
好的,但问题在于许可文件和目录文件是二进制的,所以我无法编写脚本来处理它们,我需要将它们复制到容器中。 - Mat
3
您可以使用卷将它们附加到容器中。这可以通过docker-compose文件完成。如果您想了解更多信息,请参阅此文档,https://docs.docker.com/compose/compose-file/#volumes,尝试使用一些选项,它应该可以工作。如果不起作用,请创建另一个问题,因为这是一个不同的主题,我会检查 :) - Kushal Billaiya
2
我编辑了问题,添加了有关许可文件和目录的更多信息,以了解docker-compose是否可以管理整个部署过程,或者我需要一些外部脚本,例如Fabric脚本或类似的东西。 - Mat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接