我想通过两个任务准备自定义图像(基于官方Postges image):
我想在构建映像时而不是在运行容器时执行这两个步骤,因为它们每个都花费很多时间,并且我想一次构建映像并快速运行许多容器。
我知道如何在构建映像期间执行步骤1(下载数据),但是我不知道如何在构建映像期间将数据加载到数据库中,而不是运行容器(步骤2)。
示例:
(下载-构建映像期间,加载-运行容器期间)
Dockerfile
:
FROM postgres:10.7
RUN apt-get update \
&& apt-get install -y wget \
&& rm -rf /var/lib/apt/lists/*
COPY download.sh /download.sh
RUN /download.sh
download.sh
:
#!/bin/bash
cd /docker-entrypoint-initdb.d/
wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/northwindextended/northwind.postgre.sql
要下载数据,我自己运行脚本。要加载数据,我使用Postgres官方图片中的“ initialization scripts”实用程序。
建筑图片:
docker build -t mydbimage .
运行图像:
docker run --name mydbcontainer -p 5432:5432 -e POSTGRES_PASSWORD=postgres -d mydbimage
运行后,您可以看到需要多少加载数据:
docker logs mydbcontainer
此示例数据集很小,但是长时间运行的容器比较笨拙。
答案 0 :(得分:1)
您可以剖析上游Dockerfile及其docker-entrypoint.sh,只需选择所需的代码片段即可初始化数据库:
FROM postgres:10.7
ENV PGDATA /var/lib/postgresql/datap-in-image
RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA" # this 777 will be replaced by 700 at runtime (allows semi-arbitrary "--user" values)
RUN set -x \
&& apt-get update && apt-get install -y --no-install-recommends ca-certificates wget && rm -rf /var/lib/apt/lists/* \
&& wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/northwindextended/northwind.postgre.sql \
-O /docker-entrypoint-initdb.d/northwind.postgre.sql \
&& cp ./docker-entrypoint.sh ./docker-entrypoint-init-only.sh \
&& sed -ri '/exec "\$@"/d' ./docker-entrypoint-init-only.sh \
&& ./docker-entrypoint-init-only.sh postgres \
&& rm ./docker-entrypoint-initdb.d/northwind.postgre.sql ./docker-entrypoint-init-only.sh \
&& apt-get purge -y --auto-remove ca-certificates wget
构建,运行和测试:
docker build -t mydbimage .
# bring up the database
docker run --rm mydbimage --name pgtest
# run this in another terminal to check for the imported data
docker exec -ti pgtest psql -v ON_ERROR_STOP=1 --username "postgres" --no-password --dbname postgres --command "\d"
注意事项:
PGDATA
更改为未声明为卷的目录的原因。基本上,这就是为什么在启动容器时而不是在上游存储库中构建时要处理导入的原因。如果您将非机密数据用作只读数据,则在构建过程中导入它仍然很有意义,以节省时间并在容器启动期间更易于处理。