docker 容器中 PostgreSQL 的权限问题
Permission issue with PostgreSQL in docker container
我正在尝试 运行 使用 PostgreSQL 的 docker 映像,该映像的卷配置为持久化数据。
docker-compose.yml
version: '3.1'
services:
db:
image: postgres
restart: always
volumes:
- ./data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: example
当我启动容器时,我看到了输出
fixing permissions on existing directory /var/lib/postgresql/data ... ok
我无法再读取数据文件夹。
如果我提升自己并访问数据目录,我可以看到文件在那里。此外,命令 ls -ld data
给我
drwx------ 19 systemd-coredump root 4096 May 17 16:22 data
我可以使用 sudo chmod 755 data
手动设置目录权限,但这只有在我重新启动容器后才有效。
为什么会发生这种情况,我该如何解决?
这是因为 postgres 图像的 dockerfile 中写的内容。
从第 15 行到第 18 行,您将看到使用了组 999 和用户 999。我猜在您的主机中,它们分别映射到 systemd-coredump
和 root
.
您需要知道,每当您在图像中使用 user/group 时,如果您的主机中存在 uid/gid,那么它将被映射到它。
您可以从 postgres 映像 here 中阅读有关 docker 中心的文档。有一段 Arbitrary --user Notes 解释了它如何在此图像的上下文中工作。
另一个答案确实指出了问题的根本原因,但是它所指向的帮助页面没有包含解决方案。这是我想出的让这个对我有用的东西:
- 使用普通的 docker-compose 文件启动容器,这会创建带有硬编码 uid:gid (999:999)
的目录
version: '3.7'
services:
db:
image: postgres
container_name: postgres
volumes:
- ./data:/var/lib/postgresql/data
environment:
POSTGRES_USER: fake_database_user
POSTGRES_PASSWORD: fake_database_PASSWORD
- 停止容器并手动将所有权更改为您想要的uid:gid(我将在本示例中使用1000:1000
$ docker stop postgres
$ sudo chown -R 1000:1000 ./data
- 编辑您的 docker 文件以添加您想要的 uid:gid 并使用 docker-compose 再次启动它(注意
user:
)
version: '3.7'
services:
db:
image: postgres
container_name: postgres
volumes:
- ./data:/var/lib/postgresql/data
user: 1000:1000
environment:
POSTGRES_USER: fake_database_user
POSTGRES_PASSWORD: fake_database_password
您不能从一开始就使用 user:
的原因是,如果图像以不同的用户身份运行,则无法创建数据文件。
在 image documentation page 上,它确实提到了一个解决方案,即在提供 --user
选项时添加一个卷以将 /etc/passwd
文件在图像中显示为只读,但是,不适用于最新图像,因为我收到以下错误。事实上,三个提议的解决方案中 none 对我有用。
initdb: error: could not change permissions of directory "/var/lib/postgresql/data": Operation not permitted
一个更简单和永久的解决方案如下:
将这些行添加到 ~/.bashrc
:
export UID=$(id -u)
export GID=$(id -g)
重新加载您的shell:
$ source ~/.bashrc
修改你的docker-compose.yml
如下:
version: "3.7"
services:
db:
image: postgres
volumes:
- ./tmp/db:/var/lib/postgresql/data
user: "${UID}:${GID}"
...
我正在尝试 运行 使用 PostgreSQL 的 docker 映像,该映像的卷配置为持久化数据。
docker-compose.yml
version: '3.1'
services:
db:
image: postgres
restart: always
volumes:
- ./data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: example
当我启动容器时,我看到了输出
fixing permissions on existing directory /var/lib/postgresql/data ... ok
我无法再读取数据文件夹。
如果我提升自己并访问数据目录,我可以看到文件在那里。此外,命令 ls -ld data
给我
drwx------ 19 systemd-coredump root 4096 May 17 16:22 data
我可以使用 sudo chmod 755 data
手动设置目录权限,但这只有在我重新启动容器后才有效。
为什么会发生这种情况,我该如何解决?
这是因为 postgres 图像的 dockerfile 中写的内容。
从第 15 行到第 18 行,您将看到使用了组 999 和用户 999。我猜在您的主机中,它们分别映射到 systemd-coredump
和 root
.
您需要知道,每当您在图像中使用 user/group 时,如果您的主机中存在 uid/gid,那么它将被映射到它。
您可以从 postgres 映像 here 中阅读有关 docker 中心的文档。有一段 Arbitrary --user Notes 解释了它如何在此图像的上下文中工作。
另一个答案确实指出了问题的根本原因,但是它所指向的帮助页面没有包含解决方案。这是我想出的让这个对我有用的东西:
- 使用普通的 docker-compose 文件启动容器,这会创建带有硬编码 uid:gid (999:999) 的目录
version: '3.7'
services:
db:
image: postgres
container_name: postgres
volumes:
- ./data:/var/lib/postgresql/data
environment:
POSTGRES_USER: fake_database_user
POSTGRES_PASSWORD: fake_database_PASSWORD
- 停止容器并手动将所有权更改为您想要的uid:gid(我将在本示例中使用1000:1000
$ docker stop postgres
$ sudo chown -R 1000:1000 ./data
- 编辑您的 docker 文件以添加您想要的 uid:gid 并使用 docker-compose 再次启动它(注意
user:
)
version: '3.7'
services:
db:
image: postgres
container_name: postgres
volumes:
- ./data:/var/lib/postgresql/data
user: 1000:1000
environment:
POSTGRES_USER: fake_database_user
POSTGRES_PASSWORD: fake_database_password
您不能从一开始就使用 user:
的原因是,如果图像以不同的用户身份运行,则无法创建数据文件。
在 image documentation page 上,它确实提到了一个解决方案,即在提供 --user
选项时添加一个卷以将 /etc/passwd
文件在图像中显示为只读,但是,不适用于最新图像,因为我收到以下错误。事实上,三个提议的解决方案中 none 对我有用。
initdb: error: could not change permissions of directory "/var/lib/postgresql/data": Operation not permitted
一个更简单和永久的解决方案如下:
将这些行添加到 ~/.bashrc
:
export UID=$(id -u)
export GID=$(id -g)
重新加载您的shell:
$ source ~/.bashrc
修改你的docker-compose.yml
如下:
version: "3.7"
services:
db:
image: postgres
volumes:
- ./tmp/db:/var/lib/postgresql/data
user: "${UID}:${GID}"
...