如何使用卷在dockerized postgres数据库中保存数据

Ale*_*ail 166 postgresql docker docker-compose docker-volume

我的docker compose文件有三个容器,web,nginx和postgres.Postgres看起来像这样:

postgres:
  container_name: postgres
  restart: always
  image: postgres:latest
  volumes:
    - ./database:/var/lib/postgresql
  ports:
    - "5432:5432
Run Code Online (Sandbox Code Playgroud)

我的目标是安装一个./database与postgres容器内调用的本地文件夹相对应的卷/var/lib/postgres.当我启动这些容器并将数据插入postgres时,我验证/var/lib/postgres/data/base/了我正在添加的数据(在postgres容器中),但是在我的本地系统中,./database只获取了一个data文件夹,即./database/data创建了它,但它是空的.为什么?

笔记:

更新1

根据尼克的建议,我做了一个docker inspect并发现:

    "Mounts": [
        {
            "Source": "/Users/alex/Documents/MyApp/database",
            "Destination": "/var/lib/postgresql",
            "Mode": "rw",
            "RW": true,
            "Propagation": "rprivate"
        },
        {
            "Name": "e5bf22471215db058127109053e72e0a423d97b05a2afb4824b411322efd2c35",
            "Source": "/var/lib/docker/volumes/e5bf22471215db058127109053e72e0a423d97b05a2afb4824b411322efd2c35/_data",
            "Destination": "/var/lib/postgresql/data",
            "Driver": "local",
            "Mode": "",
            "RW": true,
            "Propagation": ""
        }
    ],
Run Code Online (Sandbox Code Playgroud)

这似乎是数据被另一个我自己编码的卷偷走了.不知道为什么会这样.postgres图像是否为我创建了该卷?如果是这样,当我重新启动时,是否有某种方法可以使用该卷而不是我正在安装的卷?否则,是否有一种很好的方法可以禁用其他卷并使用我自己的卷./database

更新2

我找到了解决方案,感谢尼克!(和另一位朋友)以下答案.

Ale*_*ail 216

奇怪的是,解决方案最终要改变

volumes:
  - ./postgres-data:/var/lib/postgresql
Run Code Online (Sandbox Code Playgroud)

volumes:
  - ./postgres-data:/var/lib/postgresql/data
Run Code Online (Sandbox Code Playgroud)

  • 只是快速"为什么"这个答案(这是有效的).根据postgres人员,默认数据目录是`/ var/lib/postgresql/data` - 你可以在这里阅读PGDATA变量注释:https://store.docker.com/images/022689bf-dfd8-408f-9e1c- 19acac32e57b?标签=描述 (37认同)
  • 在上面的问题中,OP表示它最终没有/ data的情况下对他有用.那是对的吗? (2认同)
  • 并将本地目录添加到`.dockerignore`文件中,特别是如果您将其转换为生产映像.有关讨论,请参阅https://codefresh.io/blog/not-ignore-dockerignore/. (2认同)
  • 这仍然对我不起作用(Mac OS X High Sierra) (2认同)
  • @OlliD-Metz 在它工作之前我必须做一个`docker rm my_postgres_container_1`(也是High Sierra)。 (2认同)
  • 如果您在测试期间运行 docker-compose 而不指定卷信息,我认为您将自动创建持久的卷。就我而言,我必须在容器使用包含的卷信息之前手动删除它们。我的解决方案是: docker volume rm <longvolume string> (2认同)

Nis*_*ani 81

您可以为所有Postgres数据创建公共

 docker volume create pgdata
Run Code Online (Sandbox Code Playgroud)

或者您可以将其设置为撰写文件

   version: "3"
   services:
     db:
       image: postgres
       environment:
         - POSTGRES_USER=postgres
         - POSTGRES_PASSWORD=postgress
         - POSTGRES_DB=postgres
       ports:
         - "5433:5432"
       volumes:
         - pgdata:/var/lib/postgresql/data
       networks:
         - suruse
   volumes: 
     pgdata:
Run Code Online (Sandbox Code Playgroud)

它将创建卷名称pgdata并将此卷装入容器的路径.

您可以检查此卷

docker volume inspect pgdata

// output will be
[
    {
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/pgdata/_data",
        "Name": "pgdata",
        "Options": {},
        "Scope": "local"
    }
]
Run Code Online (Sandbox Code Playgroud)

  • 评论有点晚,但如果我做一个`docker-compose down -v`,这个数据不会很清楚.那是什么解决方案? (8认同)
  • @Sid 甚至稍后评论,但你*可以*使用 `docker-compose down --rmi all` *不*使用`-v`选项,它会清除“所有内容”*除了*卷,即容器、网络、图像等。我在部署时这样做,同时允许数据持久性。 (7认同)
  • “suruse”有什么用? (4认同)
  • @Sid,是的,它会!小心这个选项. (3认同)
  • 那么使用 docker-compose [down] 卷不再保留?甚至可以完全清理卷吗? (3认同)

小智 11

我会避免使用相对路径.请记住,docker是一个守护进程/客户端关系.

当你执行compose时,它基本上只是分解成各种docker客户端命令,然后传递给守护进程.那./database是相对于守护进程,而不是客户端.

现在,docker开发团队在这个问题上有一些来回,但最重要的是它可以有一些意想不到的结果.

简而言之,不要使用相对路径,使用绝对路径.


Dav*_*aze 9

postgres图像的 Dockerfile 包含这一行

VOLUME /var/lib/postgresql/data
Run Code Online (Sandbox Code Playgroud)

当一个容器基于这个镜像启动时,如果没有其他东西挂载到那里,Docker会创建一个匿名卷并自动挂载它。您可以使用诸如 之类的命令查看此卷docker volume ls,这也是docker inspect您引用的输出中的第二个安装。

这样做的主要后果是您的外部卷挂载必须位于父目录上/var/lib/postgresql/data,而不是父目录中。(另请参阅@AlexLenail 的回答。)

如果您改为挂载主机目录/var/lib/postgresql,则:

  1. Docker 在内部对挂载进行排序,因此父目录首先挂载。
  2. 主机目录安装在/var/lib/postgresql.
  3. 上未安装任何内容/var/lib/postgresql/data,因此 Docker 创建匿名卷。
  4. 挂载点不存在(它位于空的绑定挂载主机目录中),因此 Docker 创建它,同时也在./database/data主机上创建目录。
  5. 匿名卷安装在该目录上,但仅安装在容器文件系统中。

结果就是您所看到的,数据库显然运行正常,但其数据不一定持久,您只能得到data主机上的空目录。