是否有在主机上执行参数的 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 build
时,一个 Linux Postgres 容器被启动。
RUN psql.exe ...
运行在 Postgres 容器中有一些 SQL 命令。
- 现在,我们的
data-import.exe
在主机上执行了。它的 Postgres 客户端连接到容器中的数据库并导入数据。
- 数据导入完成后,数据将提交到映像,docker 构建包含 Postgres 数据库和导入数据的映像。
有这样的命令吗?如果没有,我们如何在 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" 对结果进行快照。提交的图像将用于部署的下一阶段。
我们正在尝试构建一个 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 build
时,一个 Linux Postgres 容器被启动。 RUN psql.exe ...
运行在 Postgres 容器中有一些 SQL 命令。- 现在,我们的
data-import.exe
在主机上执行了。它的 Postgres 客户端连接到容器中的数据库并导入数据。 - 数据导入完成后,数据将提交到映像,docker 构建包含 Postgres 数据库和导入数据的映像。
有这样的命令吗?如果没有,我们如何在 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" 对结果进行快照。提交的图像将用于部署的下一阶段。