将Docker Postgres容器连接到现有的空数据库

时间:2019-12-17 16:36:17

标签: postgresql docker

我想创建一个包含一个空数据库(即一系列空表)的tarball和一个启动Postgres容器的Shell脚本,该容器将连接到空数据库。最终产品是.tar.gz,它具有数据库的副本,开始脚本和停止脚本。所有这些都是为了在macOS中工作

要创建数据库,我在笔记本电脑上本地启动了Postgres服务器,并创建了一个名为“ postgres-15year”的数据库。在CLI上使用“ DBeaver”数据库管理器和“ psql”,我可以看到dbase已正确创建并且可以正常工作。

然后我创建了以下脚本:

start.sh

#!/bin/bash
echo $(pwd)
docker run --rm --name payments-15years -e POSTGRES_PASSWORD=docker -d -p5432:5432 -v$(pwd)/postgres-15year/data:/var/lib/postgresql/data:delegated postgres:11.6

stop.sh

#!/bin/bash
docker stop payments-15years
echo "docker stop payments-15years"

然后我将所有这些文件放在我想压缩的目录中。

enter image description here

因此,用户将收到压缩包,将其解压缩并运行启动脚本,并能够连接到具有预定义结构和模式的数据库。这是我认为“我的start.sh”脚本正在执行的操作:

  1. 创建一个容器名称“ payments-15years”
  2. 设置通用用户('postgres')的db密码
  3. 将数据库端口设置为5432,并将其映射到本地服务器端口 5432(不确定是否有必要,但所有示例似乎都可以 它)
  4. 将数据库映射到容器的var / lib并进行“委托”操作 进行“缓存”,以便更改持续存在
  5. 将Postgres docker映像指定为11.6

我的挑战是运行启动脚本“ docker ps”后返回:

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
14d2cba6abe2        postgres:11.6       "docker-entrypoint.s…"   44 seconds ago      Up 42 seconds       0.0.0.0:5432->5432/tcp   payments-15years

但是,当我这样做时,然后从CLI运行'psql':

docker exec -it payments-15years psql -U postgres

数据库('postgres-15year')未列出。

有人知道我的方法有什么问题吗?

注意:

  1. 我没有提供数据库,但是它是带有模式的空表 定义,并且以上所有脚本和图片应足够 重现问题。
  2. 我发现的最接近堆栈的答案是here,但没有帮助。

2 个答案:

答案 0 :(得分:1)

实际上,根据-v $(pwd)/postgres-15year/data:/var/lib/postgresql/data:delegated的官方文档,当您使用postgres-docker运行命令时。

  

命令的-v /my/own/datadir:/var/lib/postgresql/data部分将基础主机系统中的/my/own/datadir目录作为/var/lib/postgresql/data装入容器中,默认情况下PostgreSQL将在其中写入其数据文件。

因此,您只是在创建数据目录,而不是数据库。您可以使用inspect关键字进行检查。

docker container inspect <container_name>

在您的方案中,“ 15年付款”提供了相关的交易量详细信息,

"Mounts": [
            {
                "Type": "bind",
                "Source": "/Users/macair/postgres-15year/data",
                "Destination": "/var/lib/postgresql/data",
                "Mode": "delegated",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

要创建数据库,请像以前一样执行交互式会话,然后手动创建数据库或尝试执行此操作。

docker run -it --rm --network some-network postgres psql -h some-postgres -U postgres

答案 1 :(得分:1)

首先参考您的评论,

我能够使用交互方式创建数据库。为了用正确的模式填充空的数据库,我有一个pg-dump文件(.sql)。我不确定如何使该文件可用于容器。有什么想法吗?

如果您有转储文件,为什么在容器启动后就烦恼运行该命令?

更好地使其成为Dockerfile的一部分,而您无需手动转储Docker映像即可处理它。

FROM postgres
ADD mydb.sql /docker-entrypoint-initdb.d

现在,如果您上移容器,数据库将自动填充。

初始化脚本

  

如果您想对派生的图像进行其他初始化   从这一项中,在下面添加一个或多个* .sql,*。sql.gz或* .sh脚本   /docker-entrypoint-initdb.d(必要时创建目录)。   在入口点调用initdb之后,创建默认的postgres用户   和数据库,它将运行任何* .sql文件,运行任何可执行文件* .sh   脚本,并提供在其中找到的所有非可执行* .sh脚本   目录以在启动服务之前进行进一步的初始化。

postgress init DB

现在问您一个问题,您可以使用Tarball来做到这一点,tar不处理体积,而Postgres docker image随volume一起提供。因此您需要遵循Dockerfile在启动时导入数据。