是否有在主机上执行参数的 dockerfile 运行 命令?

Is there a dockerfile RUN command that executes the argument on the host?

我们正在尝试构建一个 Docker 堆栈,其中包括我们的完整应用程序:一个 Postgres 数据库和至少一个 Web 应用程序。

启动堆栈后,我们希望应用程序立即运行 - 不应因数据库设置或数据导入而造成任何延迟。所以在创建镜像的时候需要导入数据库schema(DDL)和初始数据。

这可以通过 docker 文件中的 RUN 命令来实现,例如

RUN psql.exe -f initalize.sql -h myhost -d mydatabase -U myuser
RUN data-import.exe myhost mydatabase myuser

但是,AFAIU 这将在 Postgres 容器内执行 data-import.exe,只有当 Postgres 容器是 Windows 容器时才有效。我们的产品使用 Linux Postgres 发行版,所以这不是一个好主意。我们需要图像成为 Linux Postgres 容器。

所以自然的解决方案是在主机上执行data-import.exe,像这样:

有这样的命令吗?如果没有,我们如何在 docker 中实现这种情况?

在Docker中,应用程序数据通常与图像和容器分开存储;例如,您会经常使用 docker run -v 选项将数据存储在主机目录或 Docker 卷中,这样它的寿命就会超过其容器。您通常不会尝试将数据烘焙到图像中,这既是出于规模原因,也是因为容器退出时任何更改都将丢失。

正如您所描述的更高级别的问题,我可能会分发类似 "test kit" 的内容,其中包括 docker-compose.yml 和基本数据目录。您的 Docker Compose 文件将使用带有数据的普通 PostgreSQL 容器:

postgres:
  image: postgres:10.5
  volumes:
    - './postgres:/var/lib/postgresql/data'

要回答您提出的具体问题,docker build 仅在 Docker 容器 space 中执行 运行 个单独的命令;他们不能 运行 任意主机命令,读取包含 Dockerfile 的树之外的文件系统内容,或者在容器之外写入任何类型的主机文件系统内容。

使用正确的工具,dockerfile 不是万能的锤子。

显然,您来自一个在使用某些导入工具之前已经安装了 postgres 的状态。现在您可以通过启动一个 postgres 容器来模仿该策略(没有 dockerfile,只是 docker/kubernetes)。然后 运行 导入工具,停止 postgres 容器,并使用 "docker commit" 对结果进行快照。提交的图像将用于部署的下一阶段。