我有一个转储.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-compose
的 volumes
属性将 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