【问题标题】:Restore SQL dump in PostgreSQL 11 Docker at image build time在映像构建时恢复 PostgreSQL 11 Docker 中的 SQL 转储
【发布时间】:2019-07-08 11:11:07
【问题描述】:

我想构建一个自定义 Postgres11 映像,其中创建了一些用户并安装了一些扩展。因为我希望在构建时创建这些,所以我不想使用docker-entrypoint-initdb.d。下一步也是恢复 sql 转储。

FROM postgres:11

ENV PG_MAJOR 11
ENV POSTGISV 2.5
ENV TZ Europe/Brussels

RUN apt-get update \
  && apt-get install -y --no-install-recommends \
  postgresql-$PG_MAJOR-postgis-$POSTGISV \
  postgresql-$PG_MAJOR-postgis-$POSTGISV-scripts

USER postgres

RUN  initdb && pg_ctl  -o "-c listen_addresses='*'" start &&\
    psql -h 0.0.0.0 --command "CREATE USER docker WITH SUPERUSER PASSWORD 'docker';" &&\
    psql -h 0.0.0.0 --command "CREATE USER akela_test WITH PASSWORD 'akela';" &&\
    createdb -E UTF8 -U postgres -h 0.0.0.0 -O akela_test akela_test --template template0 &&\
    psql -U postgres -d akela_test -h 0.0.0.0 -c 'CREATE EXTENSION IF NOT EXISTS "hstore";' &&\
    psql -U postgres -d akela_test -h 0.0.0.0 -c 'CREATE EXTENSION IF NOT EXISTS "postgis";' &&\
    psql -U postgres -d akela_test -h 0.0.0.0 -c 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp";' &&\
    psql -U postgres -d akela_test -h 0.0.0.0 -c "CREATE ROLE akela_db WITH LOGIN PASSWORD 'akela'" &&\
    psql -U postgres -d akela_test -h 0.0.0.0 -c "GRANT ALL PRIVILEGES ON DATABASE akela_test to akela_db" &&\
    psql -U postgres -d akela_test -h 0.0.0.0 -c "CREATE schema db" &&\
    pg_ctl stop
    # gunzip -c /tmp/dump.sql.gz | psql -U akela -h 0.0.0.0 akela
USER root

似乎有效:

...
CREATE SCHEMA
ALTER SCHEMA
CREATE ROLE
GRANT
CREATE SCHEMA
ALTER SCHEMA
waiting for server to shut down....2019-07-08 12:58:06.962 CEST [22] LOG:  received fast shutdown request
2019-07-08 12:58:06.964 CEST [22] LOG:  aborting any active transactions
2019-07-08 12:58:06.965 CEST [22] LOG:  background worker "logical replication launcher" (PID 29) exited with exit code 1
2019-07-08 12:58:06.965 CEST [24] LOG:  shutting down
2019-07-08 12:58:07.006 CEST [22] LOG:  database system is shut down
 done
server stopped
...

运行图像但没有显示用户或数据库:

postgres=# \l
                                 List of databases
   Name    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges   
-----------+----------+----------+------------+------------+-----------------------
 postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 | 
 template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
(3 rows)

postgres=# \du
                                   List of roles
 Role name |                         Attributes                         | Member of 
-----------+------------------------------------------------------------+-----------
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

可能是什么问题?

【问题讨论】:

  • 为什么要在构建时创建用户?您的容器的入口点可能会重置或损坏数据库。您最好按照预期使用 initdb 创建用户

标签: postgresql docker postgresql-11


【解决方案1】:

postgres 的 Dockerfile defines a volume 这意味着通过 RUN 步骤对该目录所做的任何更改都将被丢弃。要更改此目录,您需要执行以下选项之一:

  1. 在运行时进行更改而不是构建,并保存生成的卷。
  2. 在构建期间进行更改,但在不同的目录中。这需要更改 postgres 配置以使用不同的目录。
  3. 将更改保存到其他目录,然后在启动容器时恢复这些更改(有关此示例,请参阅 save and load volume scripts)。
  4. 在没有卷定义的情况下构建您自己的 postgres 映像。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-19
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-05
    相关资源
    最近更新 更多