加载 Postgres 转储后 docker-compose up



我有一个转储.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 < dump.sql这样的命令。如果我从 Dockerfile.db 运行这样的脚本,问题是该脚本在构建后但在 docker-compose up 之前运行,并且数据库尚未运行。

知道如何做到这一点吗?

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

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

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

它有效!

另一个不需要 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

sudo docker exec postgres psql -U postgres my_db_name < dump.sql

您可以在容器内使用pg_restore

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

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

然后

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

为了从我转储恢复,我使用 sh 来恢复数据库。

如果您将转储与docker-entrypoint-initdb.d一起使用,则会出现错误"输入是PostgreSQL自定义格式转储。使用 pg_restore 命令行客户端将此转储还原到数据库。

docker-compose.yaml

version: "3.9"
services:
  db:
    container_name: postgis_my_db_name
    image: postgis/postgis:14-3.3
    ports:
      - "5430:5432"
    # restart: always
    volumes:
    - ./my_db_name.sql:/my_db_name.sql
    - ./restore.sh:/docker-entrypoint-initdb.d/restore.sh
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: my_password
      POSTGRES_DB: my_db_name

restore.sh

 pg_restore -d my_db_name my_db_name.sql
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}"

您也可以在没有 dockerfile 的情况下执行此操作:

# start first container
docker compose start $db_container
# dump intial database
docker compose exec db pg_dump -U $user -Fc $database > $dump_file
# start container db
docker compose start $db_container
# get container id 
docker ps
# copy to container
docker cp $dump_file $container_id:/var
# delete database container / Can't use
docker compose exec $db_container dropdb -U $user $database
# user pg_restore
docker compose exec $db_container pg_restore -U $user -C -d postgres /var/$dump_file

最新更新