我正在尝试使用 PostgreSQL 运行一个 docker 镜像,该镜像的卷配置为持久化数据。
version: '3.1'
services:
db:
image: postgres
restart: always
volumes:
- ./data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: example
当我启动容器时,我会看到输出
修复现有目录 /var/lib/postgresql/data 的权限 ... ok
数据文件夹对我来说不再可读。
如果我提升自己并访问数据目录,我可以看到文件在那里。此外,命令
ls -ld data
给了我
drwx------ 19 systemd-coredump root 4096 May 17 16:22 data
我可以使用
sudo chmod 755 data
手动设置目录权限,但这只能在我重新启动容器之前有效。
为什么会发生这种情况,我该如何解决?
另一个答案确实指出了问题的根本原因,但是它指向的帮助页面不包含解决方案。这是我想出的让这个工作对我有用的东西:
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
$ docker stop postgres
$ sudo chown -R 1000:1000 ./data
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:
的原因是,如果图像以不同的用户身份运行,则无法创建数据文件。
On the image documentation page, it does mention a solution to add a volume to expose the
/etc/passwd
file as read-only in the image when providing --user
option, 然而,这对我来说不起作用最新的图像,因为我收到以下错误。事实上,三个建议的解决方案都不适合我。
initdb: error: could not change permissions of directory "/var/lib/postgresql/data": Operation not permitted
这是因为postgres镜像的dockerfile里面写的是什么
从第 15 行到第 18 行,您将看到使用了组 999 和用户 999。我猜在您的主机中,它们分别映射到
systemd-coredump
和 root
.
你需要知道,每当你在图像中使用用户/组时,如果 uid/gid 存在于你的主机中,那么它将被映射到它。
您可以从 postgres 图像 here 阅读 docker hub 上的文档。有一个部分 Arbitrary --user Notes 解释了它如何在此图像的上下文中工作。
一个更简单和永久的解决方案如下:
将这些行添加到
~/.bashrc
:
export UID=$(id -u)
export GID=$(id -g)
重新加载你的外壳:
$ source ~/.bashrc
修改你的
docker-compose.yml
如下:
version: "3.7"
services:
db:
image: postgres
volumes:
- ./tmp/db:/var/lib/postgresql/data
user: "${UID}:${GID}"
...
这是我所做的:
services:
postgres:
image: postgres:15.1
restart: always
environment:
- POSTGRES_USER=my_user
- POSTGRES_PASSWORD=my_user
- POSTGRES_DB=my_user
user: root
ports:
- "5432:5432"
volumes:
- /home/my_user/volumes/postgres/data:/var/lib/postgresql/data
- /home/my_user/volumes/postgres/config:/etc/postgresql
postgres_setup:
image: postgres:15.1
user: root
volumes:
- /home/my_user/volumes/postgres/data:/var/lib/postgresql/data
- /home/my_user/volumes/postgres/config:/etc/postgresql
entrypoint: [ "bash", "-c", "chmod 750 -R /var/lib/postgresql/data && chmod 750 -R /etc/postgresql"]
depends_on:
- postgres
pgadmin4:
image: dpage/pgadmin4
restart: always
environment:
- [email protected]
- PGADMIN_DEFAULT_PASSWORD=my_user
- PGADMIN_LISTEN_ADDRESS=0.0.0.0
user: root
ports:
- "5050:80"
volumes:
- /home/my_user/volumes/pgadmin/data:/var/lib/pgadmin
depends_on:
- postgres_setup
postgres_setup 容器只是更改权限然后关闭
我一直在为类似的问题而苦苦挣扎,当我试图解决 postgres(每个容器的静态 uid,在 alpine 上默认配置为 70,在标准图像上为 999)和 docker 限制(没有卷的 uid 转换)时,答案打动了我.
答案是在不对 docker-compose.yml 用户进行任何更改的情况下利用 Linux ACL - 只需保留默认的内部容器用户 ID。
mkdir -p ./data
sudo setfacl -m u:$(id -u):rwx -R ./data/
docker-compose up -d
或
docker-compose up -d
sudo setfacl -m u:$(id -u):rwx -R ./data/
创建数据卷目录的顺序无关紧要,只要在创建后设置ACL,您作为用户就可以递归访问它。您当然可以添加其他权限。
要检查谁有权访问数据文件夹,只需运行:
getfacl ./data