【问题标题】:How to use a PostgreSQL container with existing data?如何将 PostgreSQL 容器与现有数据一起使用?
【发布时间】:2016-06-11 08:06:22
【问题描述】:

我正在尝试设置一个 PostgreSQL 容器 (https://hub.docker.com/_/postgres/)。我有一些来自当前 PostgreSQL 实例的数据。我从/var/lib/postgresql/data 复制了它,并希望将其设置为 PostgreSQL 容器的卷。

我在 docker-compose.yml 文件中关于 PostgreSQL 的部分:

db:
    image: postgres:9.4
    ports:
        - 5432:5432
    environment:
        POSTGRES_PASSWORD: postgres
        POSTGRES_USER: postgres
        PGDATA : /var/lib/postgresql/data
    volumes:
        - /projects/own/docker_php/pgdata:/var/lib/postgresql/data

当我制作 docker-compose up 时,我会收到以下消息:

db_1  | initdb: directory "/var/lib/postgresql/data" exists but is not empty
db_1  | If you want to create a new database system, either remove or empty
db_1  | the directory "/var/lib/postgresql/data" or run initdb
db_1  | with an argument other than "/var/lib/postgresql/data".

我试图从容器中创建自己的镜像,所以我的 Dockerfile 是:

FROM postgres:9.4
COPY pgdata /var/lib/postgresql/data

但是我得到了同样的错误,我做错了什么?

更新

我使用 pg_dumpall 获取了 SQL 并将其放在 /docker-entrypoint-initdb.d 中,但是每次执行 docker-compose up 时都会执行此文件。

【问题讨论】:

  • 您是否曾经使用数据卷而不是纯数据容器解决了这个问题?

标签: postgresql docker


【解决方案1】:

以伊拉克利的回答为基础,这里有一个更新的解决方案:

  • 使用较新的版本 2 Docker Compose 文件
  • 单独的volumes部分
  • 已删除额外设置

docker-compose.yml

version: '2'

services:
  postgres9:
    image: postgres:9.4
    expose:
      - 5432
    volumes:
      - data:/var/lib/postgresql/data

volumes:
  data: {}

演示

启动 Postgres 数据库服务器:

$ docker-compose up

显示数据库中的所有表。在另一个终端中,与容器的 Postgres 对话:

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c '\z'

它什么都不会显示,因为数据库是空白的。创建表:

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c 'create table beer()'

列出新创建的表:

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c '\z'

                         Access privileges
 Schema |   Name    | Type  | Access privileges | Column access privileges 
--------+-----------+-------+-------------------+--------------------------
 public | beer      | table |                   | 

耶!我们现在使用共享存储卷启动了一个 Postgres 数据库,并在其中存储了一些数据。下一步是检查服务器停止后数据是否真正保留。

现在,终止 Postgres 服务器容器:

$ docker-compose stop

再次启动 Postgres 容器:

$ docker-compose up

我们希望数据库服务器会重新使用存储,所以我们非常重要的数据仍然存在。检查:

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c '\z'
                         Access privileges
 Schema |   Name    | Type  | Access privileges | Column access privileges 
--------+-----------+-------+-------------------+--------------------------
public | beer      | table |                   | 

我们已经成功地使用了一种新型 Docker Compose 文件来运行一个使用外部数据卷的 Postgres 数据库,并检查它是否能保证我们的数据安全无虞。

存储数据

首先,进行备份,将我们的数据存储在主机上:

$ docker exec -it $(docker-compose ps -q postgres9 ) pg_dump -Upostgres > backup.sql

从访客数据库中删除我们的数据:

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c 'drop table beer'

将我们的备份(存储在主机上)恢复到 Postgres 容器中。

注意:使用“exec -i”,不要使用“-it”,否则会出现“input device is not a TTY”错误。 p>

$ docker exec -i $(docker-compose ps -q postgres9 ) psql -Upostgres < backup.sql

列出表以验证还原是否有效:

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c '\z'
                         Access privileges
Schema |   Name    | Type  | Access privileges | Column access privileges 
--------+-----------+-------+-------------------+--------------------------
public | beer      | table |                   | 

综上所述,我们已经验证了我们可以启动一个数据库,重启后数据仍然存在,我们可以从主机恢复备份。

感谢托马斯!

【讨论】:

  • 很好的例子,谢谢,在“Zap our data ...”下的一个观察结果应该是 'drop table beer' 而不是 'delete table beer',不是吗?
  • 很好的答案。非常感谢!
  • 嗨@johntellsall,感谢演示。你介意告诉我,卷data: {} 实际上指向哪个主机目录?
  • 对于它的价值,如果您的数据没有持久化,您可以查看here 以获得答案
  • 我也有同样的情况,但我在使用干净的数据库时遇到了问题。我必须把- PGDATA=/tmp 解决它。
【解决方案2】:

看起来 PostgreSQL 映像在安装卷方面存在问题。 FWIW,它可能比 Docker 更像是 PostgreSQL 问题,但这没关系,因为无论如何,挂载磁盘不是持久化数据库文件的推荐方式。

您应该改为创建仅数据的 Docker 容器。像这样:

postgres9:
  image: postgres:9.4
  ports:
    - 5432:5432
  volumes_from:
    - pg_data
  environment:
    POSTGRES_PASSWORD: postgres
    POSTGRES_USER: postgres
    PGDATA : /var/lib/postgresql/data/pgdata

pg_data:
  image: alpine:latest
  volumes:
    - /var/lib/postgresql/data/pgdata
  command: "true"

我测试并运行良好。您可以在此处阅读有关纯数据容器的更多信息:Why Docker Data Containers (Volumes!) are Good

至于:如何导入初始数据,可以:

  1. docker cp,进入设置的纯数据容器,或
  2. 使用数据的 SQL 转储,而不是移动二进制文件(我会这样做)。

【讨论】:

猜你喜欢
  • 2022-11-27
  • 2020-08-30
  • 2013-06-27
  • 2017-07-12
  • 1970-01-01
  • 2012-04-12
  • 1970-01-01
  • 1970-01-01
  • 2019-01-31
相关资源
最近更新 更多