如果 UID=999 或 GID=999 已被占用,会怎样?
PostgreSQL:在Docker容器中启动服务时如何解决“权限被拒绝”问题 — ep2(第2集)
开场在之前的帖子中,我分享了使用UID=999和GID=999来处理“Permission denied”问题的方法。不过,UID=999和GID=999可能已经被其他用户占用。
PostgreSQL: 如何解决在Docker容器中启动服务时出现的“权限被拒绝”问题 — 在使用绑定挂载卷启动PostgreSQL时,其中一个问题是设置合适的用户和组…medium.com如果你的主机系统已经有一个组的GID为999,这与PostgreSQL Docker容器中postgres
用户默认使用的GID冲突,有三种可能的解决办法可以解决“权限被拒绝”问题:
将目录的所有权改给一个不与现有的GID 999冲突的不同的用户和组。
1. 新建用户/组
sudo groupadd -g 2000 dk-postgres # 创建一个GID为2000的dk-postgres组
sudo useradd -u 2000 -g dk-postgres dk-postgres # 创建一个UID为2000,GID为2000,用户名为dk-postgres的用户
2. 更改目录的所有者:
sudo chown -R dk-postgres:dk-postgres ./pgdata
3. 使用正确的用户和组运行Docker容器:修改docker-compose.yml
文件中的设置以确保使用正确的用户和组ID。
version: '3.8'
services:
db:
image: postgres:latest
container_name: postgres_db
环境变量:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypassword
POSTGRES_DB: mydatabase
volumes:
- ./pgdata:/var/lib/postgresql/data
user: "2000:2000" # 使用新用户和组运行容器
第二种选择: 使用 Docker 卷而不是绑定挂载的方式
使用 Docker 管理的卷可以避免权限问题,因为 Docker 内部会处理这些权限。
改动**docker-compose.yml**
文件,
version: '3.8'
services:
db:
image: postgres:latest
container_name: postgres_db # 容器名称
environment:
POSTGRES_USER: myuser # 数据库用户
POSTGRES_PASSWORD: mypassword # 数据库密码
POSTGRES_DB: mydatabase # 数据库名称
volumes:
- pgdata:/var/lib/postgresql/data # 卷宗挂载位置
volumes:
pgdata:
driver: local # 驱动类型
选项 3:在容器内部修改 GID(全局标识符)
您可以创建一个自定义的Dockerfile来调整容器内postgres
用户的组标识符GID,以避免与已有用户冲突。
1. 自定义一个Dockerfile
FROM postgres 最新版本
RUN 执行 groupmod -g 2000 postgres 并且 \
usermod -u 2000 -g 2000 postgres
USER postgres
2. 创建自定义镜像
docker build -t 自定义的_postgres:latest .
3. 你可以修改这个**docker-compose.yml**
文件
version: '3.8'
services:
db:
image: custom_postgres:latest
container_name: postgres_db # 容器名称
environment:
POSTGRES_USER: myuser # POSTGRES_USER (Postgres 用户名)
POSTGRES_PASSWORD: mypassword # POSTGRES_PASSWORD (Postgres 密码)
POSTGRES_DB: mydatabase # POSTGRES_DB (Postgres 数据库名称)
volumes:
- ./pgdata:/var/lib/postgresql/data # 本地 pgdata 文件夹 和 容器内的 PostgreSQL 数据目录
这是一个 Docker Compose 配置,用于定义一个包含自定义 Postgres 镜像的容器。容器名称为 postgres_db,环境变量中设置了 Postgres 用户名、密码及数据库名称,同时将本地的 pgdata 文件夹挂载到容器的 PostgreSQL 数据目录中。