[英]How to load data in postgres docker image on creation
我有以下 Dockerfile
FROM postgres:9.6.18
ENV POSTGRES_PASSWORD postgres
ENV POSTGRES_DB import
COPY docker/admin-db/*.sql /docker-entrypoint-initdb.d/
這工作正常,但每次我構建並啟動我的集群(docker-compose,結合 api 容器)時,加載所有 sql 文件(它包含測試數據)需要大約 2 分鍾。 這不是很敏捷,所以我想在創建圖像時加載數據,而不是在啟動容器時加載數據。 由於數據庫圖像不會經常更改,因此在圖像創建期間加載數據,大部分時間將從緩存層中獲取。
如何在創建鏡像時啟動容器,這樣每次運行docker-build都不需要在容器啟動時加載數據?
我已經廣泛閱讀了這個主題; 發現絕大多數建議也涉及使用 Docker 卷。 但是,我也堅信一定有辦法。 我想出了解決方案,效果很好。
init-scripts
的目錄,並將初始化 SQL 放在那里。build-bootstrapped-postgres-docker-image.sh
腳本粘貼到上述目錄旁邊的 build-bootstrapped-postgres-docker-image.sh 中。POSTGRES_DB
和POSTGRES_PASSWORD
。./build-bootstrapped-postgres-docker-image.sh postgres:12.9-alpine your-db 1.0
這將使用postgres:12.9-alpine
構建一個預先填充的 Postgres Image your-db:1.0
。
#!/bin/bash
# set -o xtrace
PG_IMAGE_NAME=$1
IMG_NAME=$2
IMG_TAG=$3
IMG_FQN="$IMG_NAME:$IMG_TAG"
CONTAINER_NAME="$IMG_NAME-$IMG_TAG-container"
echo 'killing any existing container that is running w same name'
docker kill $CONTAINER_NAME
echo 'running postgres container and bootstrapping schema/data... please wait.'
docker container run \
--rm \
--interactive \
--tty \
--detach \
--volume ${PWD}/data:/var/lib/postgresql/data \
--volume ${PWD}/init-scripts:/docker-entrypoint-initdb.d \
--name $CONTAINER_NAME \
--entrypoint /bin/bash \
--env POSTGRES_DB=database \
--env POSTGRES_PASSWORD=password \
--env PGDATA=data \
$PG_IMAGE_NAME
docker container exec -d $CONTAINER_NAME sh -c 'docker-entrypoint.sh postgres >> bootstrap.log 2>&1'
echo 'waiting for container...this may take a while'
grep -q 'IPv4' <(docker exec $CONTAINER_NAME tail -f /bootstrap.log)
# echo 'removing the initialization SQL files'
docker container exec $CONTAINER_NAME rm -rf /docker-entrypoint-initdb.d/*
echo 'stopping pg'
docker container exec -u postgres $CONTAINER_NAME pg_ctl stop -D /data
# commit it.
echo 'committing the container to a new image'
docker container commit \
--change='CMD postgres' \
--change='ENTRYPOINT ["docker-entrypoint.sh"]' \
--change='USER postgres' \
$CONTAINER_NAME $IMG_FQN
# cleanup!
docker kill $CONTAINER_NAME
echo "successfully built $IMG_FQN"
現在你可以運行容器了:
docker run your-db:1.0
如果您想要一個有點手動的簡單解決方案,那么您將:
docker commit
將容器保存為新圖像。在 docker 構建時應用測試腳本的完全自動化的解決方案將必須了解如何啟動 postgres。 在這里,您可以像這樣調查問題:
# Create a postgres container.
docker create postgres:9.6 --name postgres
# Copy the entrypoint script out.
docker cp postgres:/usr/local/bin/docker-entrypoint.sh docker-entrypoint.sh
現在,修改后的 docker-entrypoint.sh 腳本可以用作
RUN apply-sql-scripts.sh
在您的 Dockerfile 中。 它看起來可能很復雜。
在構建時使用卷而不是將數據復制到 /docker-entrypoint-initdb.d/ 使用卷,第一次啟動容器時,它將加載所有數據。 之后,它將僅重用已加載的數據(這似乎是您所需要的)。 只要您不刪除該卷,您的數據將在您重新啟動時始終存在。
這是一個示例:
pgdb:
image: postgres
restart: always
container_name: pgdb
env_file: ./postgres/docker-compose.env
volumes:
- ./postgres/postgresDB:/var/lib/postgresql/data
- ./postgres/postgresInit:/docker-entrypoint-initdb.d
ports:
- "5432:5432"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.