Ruby on rails 具有初始数据的docker postgres不会在提交期间持久化

Ruby on rails 具有初始数据的docker postgres不会在提交期间持久化,ruby-on-rails,postgresql,docker,Ruby On Rails,Postgresql,Docker,我在docker环境中创建了一个rails应用程序,它链接到一个postgres实例。我编辑了 postgres容器添加初始数据(通过从rails应用程序运行rake db:setup)。现在我提交了postgres数据库,但在创建新容器(提交的postgres图像)时,它似乎不记得我的数据 难道不可能在提交中保存数据,然后在提交后重新使用吗 我使用了postgres映像:问题是postgres Dockerfile将“/var/lib/postgresql/data”声明为卷。这只是一个普通目

我在docker环境中创建了一个rails应用程序,它链接到一个postgres实例。我编辑了 postgres容器添加初始数据(通过从rails应用程序运行rake db:setup)。现在我提交了postgres数据库,但在创建新容器(提交的postgres图像)时,它似乎不记得我的数据

难道不可能在提交中保存数据,然后在提交后重新使用吗


我使用了postgres映像:

问题是postgres Dockerfile将“/var/lib/postgresql/data”声明为卷。这只是一个普通目录,位于映像使用的联合文件系统之外。卷一直存在,直到没有容器链接到它们并且它们被显式删除

您有几个选择:

  • 使用
    --volumes from
    命令与新容器共享数据。这只在一次只有一个正在运行的postgres映像时才起作用,但这是最好的解决方案
  • 编写自己的Dockerfile,在声明卷之前创建数据。创建容器时,这些数据将被复制到卷中
  • 编写入口点或cmd脚本,在运行时填充数据库
所有这些建议都要求您在容器运行后使用卷来管理数据。或者,您可以编写自己的Dockerfile,而不声明卷。然后,您可以使用
docker commit
在添加数据后创建新映像。这可能会在短期内起作用,但绝对不是您应该如何使用容器-它是不可重复的,最终将耗尽Union文件系统中的层


查看上的正式Docker文档以了解更多信息。

提交期间不可能保存数据,因为数据驻留在特定于该容器的装载上,并且在运行
Docker rm
后将被删除,但您可以使用数据卷在容器之间共享和重用数据,并且所做的更改将被直接删除在音量上

您可以使用
docker run-v/host/path:/Container/path
将卷装载到新容器中


请参阅:

创建新的Dockerfile并更改
PGDATA

FROM postgres:9.2.10

RUN mkdir -p /var/lib/postgresql-static/data
ENV PGDATA /var/lib/postgresql-static/data

为了保存数据库等永久性数据,您应该将这些数据卷定义为外部数据卷,因此不会在每次运行docker compose up或down命令,或将堆栈重新部署到swarm时自动删除或创建这些数据卷

...
volumes:
  db-data:
    external: true
...
然后,您应该创建此卷:

docker volume create db-data
并将其用作数据库的数据卷:

...
db:
  image: postgres:latest
  volumes:
    - db-data:/var/lib/postgresql/data
  ports:
    - 5432:5432
...

在生产中,当使用DOCKER来安全地保存永久数据时,有很多因素需要考虑,特别是在群模式或KubNeNETs集群中。

您应该全部设置如下命令。最重要的部分是PGDATA位置,它不应该是默认值

docker run -e PGDATA=/var/lib/postgresql/pgdata -e POSTGRES_PASSWORD=YourPa$$W0rd -d postgres

运行
docker rm
时不会删除卷。您必须明确指定
-v
选项,即
docker rm-v
。假设我希望在CI环境中并行运行一些测试,并希望为每组测试提供自己的数据库,其中包含要运行的预加载数据。我唯一不使用标准postgres图像的选择是什么?好吧,选择是一样的。在这种情况下,我可能会通过修改官方Postgres图片的Dockerfile来创建您自己的图片。我不知道为什么会这样,但这很神奇。谢谢,我没有看到它。有一种方法可以将初始数据添加到postgres docker图像中:这有缺点,也在那里讨论过。我认为它没有回答这个问题,它只是单独存储数据,对吗?