使用初始模式构建postgres docker容器

jQw*_*rdy 34 postgresql docker dockerfile docker-compose

我正在寻找构建代表已存在的公司数据库的dockerfiles.同样,我想创建一个通过恢复psql转储开始的docker文件.

我有我psql_dump.sql.目录.

FROM postgres
ADD . /init_data
run "createdb" "--template=template0" "my_database"
run  "psql" "-d" "my_database"  --command="create role my_admin superuser"
run  "psql" "my_database" "<" "init_data/psql_dump.sql"
Run Code Online (Sandbox Code Playgroud)

我认为这样做会很好.我想避免使用.sh脚本的解决方案.像这个解决方案.

我使用template0,因为psql文档说您需要创建原始数据库中的相同用户,并且需要在还原之前使用template0创建数据库.

但是,它给了我一个错误:

createdb: could not connect to database template1: could not connect to server: No such file or directory
        Is the server running locally and accepting
Run Code Online (Sandbox Code Playgroud)

我也在使用docker compose作为整个应用程序,如果在docker-compose中解决这个问题更好,我会很乐意使用基本的psql镜像并使用docker compose来做到这一点.

Tho*_*eil 43

根据官方PostreSQL Docker镜像的使用指南,您只需要:

Dockerfile

FROM postgres
ENV POSTGRES_DB my_database
COPY psql_dump.sql /docker-entrypoint-initdb.d/
Run Code Online (Sandbox Code Playgroud)

POSTGRES_DB环境变量将指示容器中创建一个my_database在首次运行模式.

并且将执行在容器中.sql找到的任何文件/docker-entrypoint-initdb.d/.

如果要执行.sh脚本,还可以在/docker-entrypoint-initdb.d/目录中提供它们.

  • 主题要求"使用初始模式构建postgres docker容器".但是你建议在启动时创建模式,而不是构建一个已经具有该模式的容器.如果架构需要5分钟才能创建,那么每次创建卷时都会受到5分钟的惩罚,而不是将其放在实际容器中. (5认同)

jha*_*805 7

@Thomasleveil 的答案将在运行时重新创建数据库模式,这对于大多数情况来说都很好。

如果您想在构建时重新创建数据库模式(即,如果您的模式初始化非常慢),您可以docker_entrypoint.sh从 Dockerfile 中调用 Stock 。

但是,由于docker_entrypoint.sh设计用于启动长时间运行的数据库服务器,因此您必须添加额外的脚本以在数据库初始化之后、启动长时间运行的服务器之前退出该进程。

Dockerfile(带有构建时数据库初始化)

# STAGE 1 - Equivalent to @Thomasleveil
FROM postgres AS runtime_init
ENV POSTGRES_DB my_database
COPY 1-psql_dump.sql /docker-entrypoint-initdb.d/

# STAGE 2 - Initialize the database during the build
FROM runtime_init AS buildtime_init_builder
RUN echo "exit 0" > /docker-entrypoint-initdb.d/100-exit_before_boot.sh
ENV PGDATA=/pgdata
RUN docker-entrypoint.sh postgres

# STAGE 3 - Copy the initialized db to a new image to reduce size.
FROM postgres AS buildtime_init
ENV PGDATA=/pgdata
COPY --chown=postgres:postgres --from=buildtime_init_builder /pgdata /pgdata
Run Code Online (Sandbox Code Playgroud)

重要笔记

  • 常用的 postgres 镜像将按字母顺序运行初始化脚本,因此请确保您的数据库恢复脚本exit_before_boot.shDockerfile 中创建的脚本出现。
    • 1上面显示的和前缀证明了这一点100。根据您的喜好修改它们。
  • 对此映像正在运行的实例的数据库更新将不会在重新启动后保留,因为PGDATA存储数据库文件的路径不再映射到从主机安装的卷。

进一步阅读


yis*_*aiz 6

如评论中所述,如果您的架构重新创建速度很快,则@Thomasleveil答案将是非常简单的。但就我而言,它很慢,我想使用docker卷,所以这就是我所做的

  1. 首先使用docker image,如@Thomasleveil答案中所示,使用所有架构初始化的postgres创建一个容器

Dockerfile:

FROM postgres
WORKDIR /docker-entrypoint-initdb.d
ADD psql_dump.sql /docker-entrypoint-initdb.d
EXPOSE 5432
Run Code Online (Sandbox Code Playgroud)
  1. 然后运行它并创建一个新的本地目录,其中包含从“ psql_dump.sql”文件中填充的postgres数据: docker cp mypg:/var/lib/postgresql/data ./postgres-data

  2. 将数据复制到临时数据文件夹,然后启动一个新的postgres docker-compose容器,该容器的卷位于新的临时数据文件夹中:

startPostgres.sh:

rm -r ./temp-postgres-data/data
mkdir -p ./temp-postgres-data/data
cp -r ./postgres-data/data ./temp-postgres-data/
docker-compose -p mini-postgres-project up
Run Code Online (Sandbox Code Playgroud)

docker-compose.yml文件为:

version: '3'
services:
  postgres:
    container_name: mini-postgres
    image: postgres:9.5
    ports:
    - "5432:5432"
    volumes:
      - ./temp-postgres-data/data:/var/lib/postgresql/data
Run Code Online (Sandbox Code Playgroud)

现在,您可以在新机器上或者如果您的psql_dump.sql更改了,请运行步骤1和2。而且,每次您想要一个新的干净(但已经初始化)的数据库时,您只能从步骤3开始运行startPostgres.sh。而且它仍然使用docker卷。

  • 可以将`ADD psql_dump.sql / docker-entrypoint-initdb.d`简化为`ADD psql_dump.sql .`,因为您已经在该WORKDIR中了 (4认同)