Docker-Compose Postgresql 导入 dump

17

我有一个关于docker和postgres的问题。每次docker启动时我都要设置一个新的postgres数据库,并想导入给定的转储。

我的问题与此类似,但回答对我来说不够充分:Docker postgres does not run init file in docker-entrypoint-initdb.d

Docker-Compose:

postgres:
  environment:
   - POSTGRES_USER=****
   - POSTGRES_PASSWORD=****
   - POSTGRES_DB=****
build:
  context: .
  dockerfile: dockerfile-postgres

我的Dockerfile:(我已经尝试过用一个以.sh结尾的脚本)

FROM postgres
ADD dump.sql /docker-entrypoint-initdb.d/
根据 https://hub.docker.com/_/postgres/,必须使用dump.sql来导入数据库。

仅使用docker启动应用程序只会给出:

postgres_1     | LOG:  invalid record length at 0/1708600
postgres_1     | LOG:  redo is not required
postgres_1     | LOG:  MultiXact member wraparound protections are now enabled
postgres_1     | LOG:  database system is ready to accept connections
postgres_1     | LOG:  autovacuum launcher started

除此之外,我测试了我的数据库是否已经被导入,但是我的数据库中没有表。我做错了什么(在目标系统上读取和执行文件没有问题)?使用psql导入它没有问题,所以我的转储文件是正确的。

希望你能帮助我,我提前感谢你。


希望记得没错,但是ADD只有在作为URL时才会运行魔法,就像Docker COPY vs ADD中所讨论的那样。你不想运行pr_restore并将其路径指向你的dump.sql副本吗?...但也许pg_restore不能与容器化变体一起使用(正如Postgres Docker Hub页面上18天前的评论所建议的那样)。 - Dilettant
是的,我考虑过使用“复制到”并尝试了它,但结果相同。文件已正确放置在目标位置。我已经尝试过在此文件夹中使用pqdump和sh脚本。该脚本应该只调用:pg_restore -d databasename /tmp/dump.backup。pg_restore本身在目标机器上运行良好,但脚本未被执行。 - Simon
我猜你想要的是pg_restore,而不是将数据库中的内容倒出来再填回去,对吗? - Dilettant
SQL文件或导入转储不是问题,我的脚本可以正确地导入它,如果手动执行的话。我的问题是Docker不会执行它。 - Simon
抱歉,我要提出以下建议,你是否已经尝试将其命名为init.sql而不是dump.sql呢?这可能是一种魔法水平,可以在这样一个神奇的文件夹中导致执行。 - Dilettant
3个回答

18

好的,我找到了这个技巧,我必须执行 "docker-compose rm" 命令才能在这个文件夹中运行脚本和 SQL 文件。一旦构建并未被删除的 init 文件夹将被忽略。

更新 我再次遇到了这个问题,这次删除 Docker 创建的镜像解决了问题。


1
请注意,如果您更改了“ADD”脚本,则在运行“docker-compose rm”之后,您可能还需要执行“docker-compose build”。 - user101289
救命稻草……即使清理所有 Docker 镜像和层也没有用,但这个方法却奏效了。 - drewboswell
由于这似乎是一个常见的问题或研究,如果本答案能够更详细地阐述,将不胜感激。 - Pipo

-1

这里的答案在一定程度上为我解决了问题,但是让docker-entrypoint-initdb/*.sql脚本正常工作的最后一步是确保sql脚本本身没有语法问题(因为我在Dockerfile中更改了SQL版本,所以出现了问题)。

如果存在任何语法问题,docker-entrypoint-initdb/*.sql脚本中的所有内容似乎都会被回滚。

要检查是否存在任何语法脚本问题(或其他问题),您可能会发现查看docker日志有用:

$ docker ps -all

注意:-all 选项确保列出那些可能启动失败的镜像。

找到刚创建的镜像,并查找容器 ID,它应该是一个由12个字符组成的哈希值:

$ docker logs baf32ff7ec03

请记得您仍然需要遵循其他答案,即删除先前构建的镜像并删除数据文件夹(如果需要,请备份)。


-1

这种情况很可能是因为

docker-entryfile.sh脚本负责按字母顺序运行/docker-entrypoint-initdb.d/*文件,只有在创建卷时才会首次运行。

您可以在此处查看一些详细信息。

解决方案(适用于我)

这是我的docker-compose文件的片段

  postgres_service:
    build:
      context : docker-postgres
      dockerfile: Dockerfile-base
    image: 'datahub/postgres:development'
    user: postgres
    ports:
      - "5432:5432"
    env_file:
      - credentials/postgres/development.env
    volumes:
      - /Users/yogesh.yadav/DockerData/datahub/postgresql/data:/var/lib/postgresql/data
    restart: unless-stopped
    networks:
      - datahubnetwork

步骤 -

1) docker-compose -f docker-compose-filename.yml down

或者

docker-compose -f docker-compose-filename.yml stop postgres_service

2) 删除与postgres_service docker服务附加的卷(/Users/yogesh.yadav/DockerData/datahub/postgresql/data)。您可以手动执行此操作,也可以通过docker-compose rmdocker volume rm执行。在删除之前,请确定已附加到该postgres服务的卷。更多信息请点击这里

3) Docker通过构建镜像和运行它们使用非常好的缓存管理。如果您没有修改Dockerfile,Docker将从缓存中运行已构建的镜像并运行它。因此,我建议您也删除postgres_service的镜像。

列出镜像

docker images -a

输出 -

REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
datahub/postgres          development         e7707e670ad4        35 minutes ago      265 MB

删除该图片(如有需要,请使用-f)

docker rmi IMAGE_ID_HERE

4) 再次启动您的服务

docker-compose -f docker-compose-filename.yml up --build postgres_service

这次你可以看到你的docker-entrypoint.shdump.sql将会被执行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接