用数据库备份一个postgres容器
所以我们有大约100个testing,每个testing连接到一个postgres实例,并使用一些数据加载数据库。 testing编辑并更改数据,以便重新加载每个testing的postgres数据库。
这需要很长时间,所以我想如下使用Docker。 我是docker工人,所以这是我使用的步骤:
1)我会创build一个postgres容器,加载我想要的testing数据库,并准备好并打磨。
2)使用此命令将我的容器保存为tar
docker save -o postgres_testdatabase.tar postgres_testdatabase
3)对于每个testing我加载一个新的焦油到一个图像
docker load -i postgres_testdatabase.tar
4)用postgres实例运行容器
docker run -i -p 5432 postgres_testdatabase
5)testing运行并更改数据
6)销毁容器并用新的新testing数据库装载新容器
7)运行第二个testing等等。
我的问题是,我发现当我备份一个容器到一个tar并加载它,然后运行一个新的容器,我没有得到我的数据库,我基本上得到一个新的postgres安装没有我的数据库。
我做错了什么?
编辑:
我尝试了其中一个build议来提交我的更改,然后将我的容器保存到图像中,如下所示:
我将我的更新容器提交给了一个新的映像。 保存该图片到一个tar文件,删除我现有的容器。 加载tar文件,然后从保存的图像运行一个新的容器。 我仍然没有看到我的数据库..我相信它必须做一些与卷。 如何在没有卷的情况下执行此操作? 我如何强制所有的数据在容器中,以便它与图像备份?
EDIT2 Warmoverflowbuild议我在加载图像时使用一个sql文件来加载我所有的数据。 这不会在我的情况下工作,因为数据是使用其他软件(ArcGIS)仔细创作,再加上数据有一些复杂的blob字段几何,所以SQL文件加载脚本将无法正常工作。 他还build议我不需要将数据保存为焦油,如果我在同一台机器spawing容器。 一旦我符合我的数据,并将其提交到图像,我可以将图像加载到一个新的容器。 感谢澄清这一点。 仍然问题是,我如何保持我的数据库在我的图像,所以当我恢复图像时,数据库与容器。
EDIT3
所以我find了一个由warmoverflowbuild议启发的解决方法,这应该解决我的问题。 不过,我仍然在寻找更干净的方式来做到这一点。
解决scheme是执行以下操作:
- 创build一个新鲜的postgres容器。
- 根据需要填充数据库,在我的情况下,我使用ArcGIS来完成
-
用这个命令使用pg_dumpall将整个postgres实例转储到一个文件中。 我们可以从任何postgres客户端运行这个命令,我们不必复制容器内的转储文件。 我从Windows运行这个。
C:\ Program Files \ PostgreSQL \ 9.3 \ bin> pg_dumpall.exe -h 192.168.99.100 -p 5432 -U postgres> c:\ Hussein \ dump \ pg_test_dump.dmp
-
您现在可以安全地删除您的容器。
- 创build一个新的postgres容器
-
在你的容器postgres实例上调用这个命令来加载你的转储
C:\ Program Files \ PostgreSQL \ 9.3 \ bin> psql -fc:\ Hussein \ dump \ pg_test_dump.dmp -h 192.168.99.100 -p 5432 -U postgres
-
运行testing,testing将螺旋数据,所以我们需要重新加载,我们只需重复上述步骤。
我仍然,真的希望容器图像有数据库“,所以当我从图像运行一个容器,我得到的数据库。 如果有人能提出一个解决scheme,那将是非常棒的,会为我节省很多时间。
Edit4最后Warmoverflow解决了它! 下面回答
谢谢
docker save
用于图像(将图像保存为tar文件)。 你需要的是提交容器更改到图像的docker commit
,然后将其保存为tar。 但是,如果你的数据库对于所有的testing都是一样的话,你应该使用一个Dockerfile来构build一个自定义的图像,然后使用单个图像来运行你的容器。
如果您的数据是使用sql
文件加载的,则可以按照官方postgres泊坞窗页面https://hub.docker.com/_/postgres/中 “如何扩展此图像”部分的说明进行操作。 您可以使用以下内容创build一个Dockerfile
FROM postgres RUN mkdir -p /docker-entrypoint-initdb.d ADD data.sql /docker-entrypoint-initdb.d/
把你的data.sql
文件和Dockerfile放在一个新文件夹中,然后运行docker docker build -t custom_postgres .
,它将为您创build一个定制的图像,并且每次运行一个新的容器时,它都会在启动时加载sql文件。
[更新]
基于问题的新信息,问题的原因是官方postgres
映像在postgres数据文件夹/var/lib/postgresql/data
定义了VOLUME
。 VOLUME
用于在容器外持久化数据(当您使用docker run -v
将主机文件夹挂载到容器时),因此在提交容器本身时不会保存VOLUME
中的任何数据。 虽然这通常是一个好主意,但是在这种特定情况下,我们实际上需要的数据不是持久的,这样每次都可以启动一个新的未修改相同数据的新容器。
解决的办法是创build自己的postgres图像版本,并删除VOLUME
。
- 这些文件在https://github.com/docker-library/postgres/tree/master/9.3
- 将这两个文件下载到一个新文件夹
- 从
Dockerfile
删除VOLUME
行 - 在Docker快速入门terminal中,切换到该文件夹,然后运行
docker build -t mypostgres .
,这将build立自己的postgres图像的名称mypostgres
。 - 使用
docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=123456 mypostgres
启动您的容器。 postgres数据库可在postgres:123456@192.168.99.100:5432
- 正常使用ArcGISinput数据
- 用
docker commit container_id_from_step_5 mypostgres_withdata
。 这将创build自己的postgres图像与数据 。 - 停止并删除中间容器
docker rm -f container_id_from_step_5
- 每当你需要一个新的容器时,在Docker Quickstart Terminal中,运行
docker run -d -p 5432:5432 mypostgres_withdata
来启动一个容器,然后记住停止或者移除使用过的容器,这样它就不会占用5432端口。