目录
GitLab Docker Compose 迁移后 Redis 权限问题排查与解决
GitLab Docker Compose 迁移后 Redis 权限问题排查与解决
在一次 GitLab 从旧环境迁移到新环境的过程中,我遇到了一个棘手的问题:GitLab 服务迁移后无法启动,日志中不断报 Redis 相关的权限错误。本文记录了问题的排查过程及最终解决方法,供有类似场景的同学参考。
问题背景
部署方式:Docker Compose + GitLab CE 17.3.7
迁移方式:直接将原环境的
./config
、./data
、./logs
数据目录拷贝到新环境启动命令:
docker compose up -d
迁移完成后,GitLab 容器无法正常启动。
错误日志
查看容器日志:
docker logs gitlab
发现 gitlab-kas
组件连接 Redis 失败:
Program aborted: redis client: dial unix /var/opt/gitlab/redis/redis.socket: connect: connection refused
进一步查看 Redis 日志(宿主机 ./logs/redis/current
):
Fatal error loading the DB: Permission denied. Exiting.
核心错误:Redis 无法访问数据文件和 socket,导致启动失败。
原因分析
1. 检查 Redis 数据目录权限
ls -ld ./data/redis
ls -l ./data/redis
输出示例:
drwxr-x--- 2 unbound systemd-coredump 4096 Aug 1 13:51 ./data/redis
-rw------- 1 unbound systemd-coredump 1861801 Aug 1 09:46 dump.rdb
可以看到,目录和文件属主属组为 unbound systemd-coredump
,而容器内 Redis 用户是 gitlab-redis
,UID/GID 为 997:
docker run --rm gitlab/gitlab-ce:17.3.7-ce.0 id gitlab-redis
# uid=997(gitlab-redis) gid=997(gitlab-redis) groups=997(gitlab-redis)
按理说执行以下命令可以修复:
sudo chown -R 997:997 ./data/redis
但实际执行后属主没有变化,依然是 unbound systemd-coredump
。
2. 为什么 chown 不生效?
宿主机文件系统是 ext4,理论上支持 UID/GID 修改
实际 UID 映射冲突:宿主机的 UID 997 对应
unbound
,容器内 UID 997 对应gitlab-redis
结果:即便改成 997:997,容器内仍然无法访问
解决方案
临时解决方案:开放权限
直接给 Redis 数据目录全权限,让容器内 Redis 用户可以访问:
sudo chmod -R 777 ./data/redis
然后重启容器:
docker compose down
docker compose up -d
此方法简单粗暴,能快速恢复服务。
根本解决方案
长期来看,应该修复 UID/GID 对齐问题或避免权限冲突:
删除 Redis 数据目录(仅适合不需要保留 Redis 缓存的情况):
sudo rm -rf ./data/redis/* docker compose up -d
让 GitLab 重新初始化 Redis。
修改容器内用户 UID/GID:
构建自定义镜像,将gitlab-redis
用户 UID/GID 改为宿主机对应值(如unbound
的 UID)。调整宿主机 UID 映射或专用磁盘挂载:
使用单独分区或确保宿主机与容器 UID 一致。
补充:内存 overcommit 警告
迁移过程中还会看到 Redis 的警告:
Memory overcommit must be enabled!
可以通过设置内核参数解决:
echo 'vm.overcommit_memory=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
总结
问题本质:Docker 容器内的 UID/GID 与宿主机不一致,导致数据目录权限失效
快速解决:
chmod -R 777 ./data/redis
长期方案:删除 Redis 数据重建,或调整 UID/GID 对齐
这种问题在直接迁移数据卷的场景下很常见,建议迁移前明确 UID/GID 映射或使用备份恢复方式迁移。