docker 依赖容器通过卷从依赖容器访问文件

jk9hmnmh  于 2023-04-20  发布在  Docker
关注(0)|答案(2)|浏览(166)

Docker编写:

version: "3"
services:

  db:
    container_name: db
    image: mysql
    ports:
      - "3306:3306"
    volumes:
      - initdb:/docker-entrypoint-initdb.d/:ro
  
  web:
    container_name: web
    image: my_web
    volumes:
      - initdb:/initdb/:ro
    depends_on: 
      - db

volumes:
  initdb:

my_web映像包含/initdb/create_schema.sql。
web依赖于db。因此服务db将在web之前启动。来自web的create_schema. sql是否可供db使用?
通过测试,它是可用的。这是保证还是随机的?
create_schema. sql是在构建my_web映像时生成的。它不在主机磁盘上。
尝试了解卷何时创建并Map到容器。如果在启动所有容器之前创建并Map卷,则可以保证通过卷共享的数据可用。

igetnqfo

igetnqfo1#

大多数应用程序框架都包含某种 * 数据库迁移 * 系统,一种更健壮的方法是让应用程序在启动时运行迁移,而不是尝试使用这样的命名卷。
Docker命名卷有一个微妙的顺序来将内容复制到卷中。当创建一个挂载卷的容器时,当且仅当卷完全为空时,内容将从挂载点复制到镜像中。这仅在卷为空时发生(因此它永远不会看到映像内容的更改),并且它只发生在Docker命名卷上,而不是其他类型的挂载(Docker bind mounts,Kubernetes PersistentVolumeClaims,...)。
这个序列意味着Compose将
1.创建命名卷
1.创建并启动db容器,挂载空卷
1.创建并启动web容器,此时Docker会将脚本复制到卷中
这会导致一个竞态条件,即不确定是web容器启动时首先复制文件,还是db容器开始在该目录中查找初始化脚本。
如果您将此设置扩展到use a health check以等待数据库运行,那么这根本不起作用。在db容器完成初始化之前,不会创建web容器,这意味着您可以保证扫描/docker-entrypoint-initdb.d目录时卷为空。
同样,请记住Docker永远不会 * 更新 * 卷的内容,因此如果您更改初始化脚本,卷仍将使用旧的卷。标准数据库映像也仅在其数据目录未初始化时运行/docker-entrypoint-initdb.d。运行迁移系统可以避免这两个问题。

xmq68pz9

xmq68pz92#

如果你想的话
create_schema. sql是在构建my_web映像时生成的。它不在主机磁盘上。
然后你需要创建第三个容器(它可以用类似于web文件的Dockerfile生成,但有不同的入口点)让我们将其命名为init-db-script,在db容器之前启动它,在其中生成create_schema.sql
然后将其添加到depends for db

db:
    depends_on: 
      - init-db-script
    ...

或者你可以尝试通过docker run为'脚本容器'创建卷中的数据,这将在脚本完成后停止,但卷中的数据将被创建。
但我建议在构建脚本之前生成create_schema.sql,将其添加到存储库中,并将其副本添加到其Dockerfile中的db的Docker映像中

相关问题