【问题标题】:Load Postgres dump after docker-compose up在 docker-compose up 后加载 Postgres 转储
【发布时间】:2016-08-15 09:15:26
【问题描述】:

我有一个 dump.sql 文件,我想用 docker-compose 加载它。

docker-compose.yml:

services:
  postgres:
    environment:
      POSTGRES_DB: my_db_name
      POSTGRES_USER: my_name
      POSTGRES_PASSWORD: my_password
    build:
      context: .
      dockerfile: ./devops/db/Dockerfile.db

目前我的 Dockerfile.db 真的很简单:

FROM postgres
MAINTAINER me <me@me.me>

COPY ./devops/db ./devops/db
WORKDIR ./devops/db

我想在某个时候运行类似psql my_db_name &lt; dump.sql 的命令。如果我从 Dockerfile.db 运行这样的脚本,问题是脚本在构建之后但在 docker-compose up 之前运行,并且数据库尚未运行。

知道怎么做吗?

【问题讨论】:

  • 一般来说,我通过编写一个执行 docker-compose up -d 的 bash 脚本,然后使用执行 SQL 转储命令的 docker-compose exec db_service_name 来完成此操作。

标签: postgresql docker docker-compose dockerfile


【解决方案1】:

阅读https://hub.docker.com/_/postgres/,“扩展此映像”部分解释说,/docker-entrypoint-initdb.d 中的任何 .sql 都将在构建后执行。

我只需要将 Dockerfile.db 更改为:

FROM postgres

ADD ./devops/db/dummy_dump.sql /docker-entrypoint-initdb.d

而且它有效!

【讨论】:

  • très bonne reponse, merci beacoup!!!省去我长时间调试的时间...
  • 文档表明也可以使用*.sh 脚本,这提供了更广泛的灵活性。我用它来pg_restore 一个.dump 文件。
  • 我正在尝试这种方法,我得到以下结果:postgres | /usr/local/bin/docker-entrypoint.sh:运行 /docker-entrypoint-initdb.d/dump-202105231637-1.sql postgres |输入是 PostgreSQL 自定义格式转储。后勤 |使用 pg_restore 命令行客户端将此转储恢复到数据库。有什么想法吗?
【解决方案2】:
sudo docker exec postgres psql -U postgres my_db_name < dump.sql

【讨论】:

  • 虽然这段代码可以回答问题,但最好解释一下如何解决问题,并提供代码作为示例或参考。仅代码的答案可能会令人困惑且缺乏上下文。
  • 它解决了导入转储的问题,而无需像接受的答案那样调整 dockerfile。我还需要在这篇文章中解释什么:psql -U postgres my_db_name &lt; dump.sql?如果您在这个级别遇到问题,最好阅读基础知识
  • 这对我有用,但在exec 之后需要-i 所以它是sudo docker exec -i postgres psql -U postgres my_db_name &lt; dump.sql
  • 另外,exec 要求(我相信?)Docker 系统已经启动,这可能与导入完整的数据库转储不兼容。
【解决方案3】:
CONTAINER_NAME="postgres"
DB_USER=postgres
LOCAL_DUMP_PATH="..."
docker run --name "${CONTAINER_NAME}" postgres
docker exec -i "${CONTAINER_NAME}" psql -U "${DB_USER}" < "${LOCAL_DUMP_PATH}"

【讨论】:

    【解决方案4】:

    docker-compose up 之后,执行docker ps,它将为您提供活动 docker 容器的列表。从中,您可以获取容器 ID。

    那么,

    docker exec -i ${CONTAINER_ID} psql -U ${USER} < ${SQL_FILE}
    

    【讨论】:

      【解决方案5】:

      您可以在容器内使用pg_restore

      cat ${BACKUP_SQL_File} | docker exec -i ${CONTAINER_NAME} pg_restore \
          --verbose \
          --clean \
          --no-acl \
          --no-owner \
          -U ${USER} \
          -d ${DATABASE}
      

      【讨论】:

        【解决方案6】:

        另一个不需要 Dockerfile 的选项是使用 docker-composevolumes 属性将您的 sql 文件挂载到 docker-entrypoint-initdb.d 文件夹中。 官方 postgres 镜像https://hub.docker.com/_/postgres/ 将导入并执行该文件夹中的所有 SQL 文件。所以像

        services:
          postgres:
            environment:
              POSTGRES_DB: my_db_name
              POSTGRES_USER: my_name
              POSTGRES_PASSWORD: my_password
          volumes:
            - ./devops/db/dummy_dump.sql:/docker-entrypoint-initdb.d/dummy_dump.sql
        

        这将自动为您填充指定的POSTGRES_DB

        【讨论】: