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

Alb*_*bac 38 postgresql docker

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

我是关于PostgreSQL的docker-compose.yml文件的一部分:

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
Run Code Online (Sandbox Code Playgroud)

当我做docker-compose时,我收到这条消息:

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".
Run Code Online (Sandbox Code Playgroud)

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

FROM postgres:9.4
COPY pgdata /var/lib/postgresql/data
Run Code Online (Sandbox Code Playgroud)

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

更新

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

joh*_*all 54

以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: {}
Run Code Online (Sandbox Code Playgroud)

演示

启动Postgres数据库服务器:

$ docker-compose up
Run Code Online (Sandbox Code Playgroud)

显示数据库中的所有表.在另一个终端,与集装箱的Postgres交谈:

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c '\z'
Run Code Online (Sandbox Code Playgroud)

它没有显示任何内容,因为数据库是空白的.创建一个表:

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c 'create table beer()'
Run Code Online (Sandbox Code Playgroud)

列出新创建的表:

$ 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 |                   | 
Run Code Online (Sandbox Code Playgroud)

好极了!我们现在使用共享存储卷启动了Postgres数据库,并在其中存储了一些数据.下一步是在服务器停止后检查数据是否实际存在.

现在,杀死Postgres服务器容器:

$ docker-compose stop
Run Code Online (Sandbox Code Playgroud)

再次启动Postgres容器:

$ docker-compose up
Run Code Online (Sandbox Code Playgroud)

我们希望数据库服务器将重新使用存储,因此我们非常重要的数据仍然存在.校验:

$ 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 |                   | 
Run Code Online (Sandbox Code Playgroud)

我们已成功使用新式Docker Compose文件使用外部数据卷运行Postgres数据库,并检查它是否保证我们的数据安全无虞.

存储数据

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

$ docker exec -it $(docker-compose ps -q postgres9 ) pg_dump -Upostgres > backup.sql
Run Code Online (Sandbox Code Playgroud)

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

$ docker exec -it $(docker-compose ps -q postgres9 ) psql -Upostgres -c 'drop table beer'
Run Code Online (Sandbox Code Playgroud)

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

注意:使用"exec -i",而不是 "-it",否则你将得到"输入设备不是TTY"错误.

$ docker exec -i $(docker-compose ps -q postgres9 ) psql -Upostgres < backup.sql
Run Code Online (Sandbox Code Playgroud)

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

$ 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 |                   | 
Run Code Online (Sandbox Code Playgroud)

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

谢谢Tomasz!


ira*_*kli 10

看起来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"
Run Code Online (Sandbox Code Playgroud)

我测试和工作正常.您可以在此处阅读有关仅数据容器的更多信息:为什么Docker数据容器(卷!)是好的

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

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

  • 谢谢,这似乎是正确的.但根据UPDATE 5 http://stackoverflow.com/questions/18496940/how-to-deal-with-persistent-storage-eg-databases-in-docker.现在不需要数据容器,而是应该使用新的卷api https://docs.docker.com/engine/reference/commandline/volume_create/.我们如何用这个新api解释你的例子? (7认同)
  • 如果您的 Postgres Docker 容器由于 OP 提到的错误而没有启动,您知道如何进行 SQL 转储吗? (2认同)