如何将PostgreSQL容器与现有数据一起使用?

时间:2016-02-28 07:40:23

标签: postgresql docker

我正在尝试设置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

当我做码头工作时,我收到了这条消息:

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时都会执行此文件。

2 个答案:

答案 0 :(得分:44)

以irakli的答案为基础,这是一个更新的解决方案:

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

搬运工-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",否则你会得到一个"输入设备不是TTY"错误。

$ 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 |                   | 

总而言之,我们已经确认我们可以启动数据库,重启后数据仍然存在,我们可以从主机恢复备份。

感谢Tomasz!

答案 1 :(得分:9)

看起来PostgreSQL映像存在已装入卷的问题。 FWIW,它可能比Dockers更多的是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转储,而不是移动二进制文件(这就是我要做的)。