Docker 部署 MongoDB 启动失败:Operation not permitted 问题排查实录

4 阅读2分钟

一、问题背景

在使用 docker-compose 部署 MongoDB 4.4 版本时,更换了宿主机数据目录后,容器反复启动失败,查看容器日志出现权限拒绝、WiredTiger 引擎无法启动的致命错误。

尝试过给挂载目录添加 :rw 读写权限、修改目录归属,均无法解决问题,最终通过排查文件系统属性、容器运行用户完成修复。

二、问题现象

1. 核心报错日志

WiredTiger error, attr: {"error":1,"message":".../data/db/WiredTiger.wt: handle-open: open: Operation not permitted"}
Fatal assertion 28595 Terminating. reason: 1: Operation not permitted

2. 宿主机数据目录状态

数据文件完整,但容器内无权限读写:

[root@shengjyt-zhgl-xcint-01 compents]# ls ./mongodb/data/
# 大量 .wt 数据文件、WiredTiger 引擎文件

3. 文件扩展属性检查

[root@shengjyt-zhgl-xcint-01 compents]# lsattr ./mongodb/data
--------------e----- ./mongodb/data/index-6--512033199807281574.wt
...
# 所有文件无不可变属性,但容器仍无权限访问

4. SELinux 状态

服务器已禁用 SELinux,排除安全策略拦截:

[root@shengjyt-zhgl-xcint-01 compents]# sudo setenforce 0
setenforce: SELinux is disabled

三、根因分析

  1. Docker 容器用户权限不匹配 MongoDB 官方镜像(mongodb-community-server:4.4-ubuntu2004)默认使用非 root 用户运行,宿主机数据目录归属为 root,容器内进程无读写权限;
  2. 挂载权限 :rw 无效 :rw 仅为 Docker 挂载标记,不解决 Linux 系统级的文件用户归属/权限问题;
  3. 异常关机残留锁文件 数据目录存在未清理的锁文件,加剧启动异常。

四、完整解决方案

环境说明

  • 系统:CentOS 7.x
  • MongoDB 镜像:mongodb/mongodb-community-server:4.4-ubuntu2004
  • 部署方式:docker-compose
  • 问题:更换数据目录后启动失败,Operation not permitted

步骤1:彻底停止容器并清理残留文件

# 停止并删除容器
docker-compose down mongodb

# 清理 MongoDB 锁文件(关键)
rm -rf ./mongodb/data/mongod.lock
rm -rf ./mongodb/data/WiredTiger.lock

步骤2:移除文件系统限制属性

防止文件被系统保护,导致无法读写:

# 递归移除不可修改、仅追加属性
sudo chattr -R -i ./mongodb/data
sudo chattr -R -a ./mongodb/data

步骤3:修改 docker-compose 配置(终极方案)

强制容器以 root 用户 运行,彻底绕过所有权限限制:

mongodb:
  image: mongodb/mongodb-community-server:4.4-ubuntu2004
  user: root  # 核心修复:以root用户运行容器
  ports:
    - "27017:27017"
  environment:
    - MONGO_INITDB_ROOT_USERNAME=root
    - MONGO_INITDB_ROOT_PASSWORD=xxx
  volumes:
    - /etc/localtime:/etc/localtime:ro
    - ./mongodb/data:/data/db  # 无需加:rw,默认读写
  restart: always

步骤4:重启容器验证

# 启动容器
docker-compose up -d mongodb

# 查看日志,确认启动成功
docker-compose logs -f mongodb

五、修复结果

执行完成后,MongoDB 容器正常启动,无权限报错,数据完整可访问。