Docker容器没有权限写入宿主机目录的解决方案

 更新时间:2021年03月24日 14:35:57   作者:catoop  
这篇文章主要介绍了Docker容器没有权限写入宿主机目录的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

在应用docker容器的时候,更多的时候我们会把宿主机的目录挂载到docker容器中。

在宿主机的文件夹权限隶属于root时,我们需要将文件夹的权限用户进行 chown 设置,才能保证目录的内容的正常写入,

下面是一个例子:

使用的是docker版本的jenkins,运行后,出现如下错误:

[root@localhost CICD]# docker logs -f jenkins 
touch: cannot touch '/var/jenkins_home/copy_reference_file.log': Permission denied
Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?

我jenkins挂载的目录是 /opt/jenkins/xxxxx,root 用户创建,而 jenkins user的uid为1000

所以需要进行 chown 设置,如下:

sudo chown -R 1000:1000 /opt/jenkins

然后重启容器,错误就没有了。

补充:介绍两种从 Docker 容器写入卷时的文件权限处理方式

说在前面

容器常常用作原生安装工具的替代品。在主机上使用具有所需版本的容器要比使用过时的工具好的多。但是,只要容器与主机系统进行交互,文件会留下错误或损坏的权限。

幸运的是,解决该问题的方法并不需要使用脚本。

问题描述

当容器挂载一个本地目录并将文件写入其中时,其所有权由容器内的用户决定:

nicholas@host:~/source$ mkdir source
nicholas@host:~/source$ docker run -it --rm --volume $(pwd):/source --workdir /source ubuntu
root@a031d11c9515:/source# mkdir subdir
root@a031d11c9515:/source# touch subdir/newfile
root@a031d11c9515:/source# exit
exit
nicholas@host:~/source$ ls -lR
.:
total 4
drwxr-xr-x 2 root root 4096 Jul 16 19:35 subdir
 
./subdir:
total 0
-rw-r--r-- 1 root root 0 Jul 16 19:35 newfile
nicholas@host:~/source$ rm -rf subdir/
rm: cannot remove 'subdir/newfile': Permission denied

另外,您还可能无法删除这些目录和拥有错误所有权的文件。

解决方案1:从容器中删除

一个非常常见的解决方案是从容器内部更改文件和目录的所有权:

nicholas@host:~/source$ docker run -it --rm --volume $(pwd):/source --workdir /source ubuntu
root@d1c3bee8bb2b:/source# ls -al
total 12
drwxrwxr-x 3 1000 1004 4096 Jul 16 19:35 .
drwxr-xr-x 1 root root 4096 Jul 16 19:39 ..
drwxr-xr-x 2 root root 4096 Jul 16 19:35 subdir
root@d1c3bee8bb2b:/source# chown 1000:1000 subdir/ -R
root@d1c3bee8bb2b:/source# ls -l
total 4
drwxr-xr-x 2 1000 1000 4096 Jul 16 19:35 subdir
root@d1c3bee8bb2b:/source# exit
exit
nicholas@host:~/source$ ls -l
total 4
drwxr-xr-x 2 nicholas lpadmin 4096 Jul 16 19:35 subdir
nicholas@host:~/source$

这种方法的缺点是需要添加额外的逻辑,以及您需要知道运行该容器用户的用户 ID 和组 ID。

解决方案2:创建拥有正确所有权的文件

第二种解决方案更简洁,它将使用容器内的正确所有权创建文件和目录。Docker 提供了一个参数来设置容器内用户的用户 ID 和组 ID:

nicholas@host:~/source$ docker run -it --rm --volume $(pwd):/source --workdir /source --user $(id -u):$(id -g) ubuntu
groups: cannot find name for group ID 1004
I have no name!@bf7f355f3b65:/source$ touch newfile
I have no name!@bf7f355f3b65:/source$ exit
exit
nicholas@host:~/source$ ls -l
total 4
-rw-r--r-- 1 nicholas nicholas  0 Jul 16 19:42 newfile
drwxr-xr-x 2 nicholas lpadmin 4096 Jul 16 19:35 subdir
nicholas@host:~/source$

这种方法可以很好的帮您解决用户 ID 和组 ID 的错误。

请注意,出于安全目的,在容器内以 root 身份运行是最糟糕的做法。Dockerfile 应始终使用 USER 指令从而避免直接使用 root 权限。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

相关文章

  • 什么是docker Docker入门教程第一篇

    什么是docker Docker入门教程第一篇

    什么是docker?这篇文章主要为大家分享了Docker简介与入门教程第一篇,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • docker运行项目的方法

    docker运行项目的方法

    在本篇文章里小编给大家分享的是关于docker运行项目的方法和实例,需要的朋友们学习参考下。
    2020-03-03
  • ubuntu系统使用docker gitlab 磁盘空间满的问题及解决

    ubuntu系统使用docker gitlab 磁盘空间满的问题及解决

    这篇文章主要介绍了ubuntu系统使用docker gitlab 磁盘空间满的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • 详解基于docker搭建lanproxy内网穿透服务

    详解基于docker搭建lanproxy内网穿透服务

    这篇文章主要介绍了详解基于docker搭建lanproxy内网穿透服务,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • Docker 制作tomcat镜像并部署项目的步骤

    Docker 制作tomcat镜像并部署项目的步骤

    这篇文章主要介绍了Docker 制作tomcat镜像并部署项目 ,讲解如何制作自己的tomcat镜像,并使用tomcat部署项目,需要的朋友可以参考下
    2022-10-10
  • 记 -bash: docker-compose: command not found 的问题解决方法

    记 -bash: docker-compose: command not&nbs

    这篇文章主要介绍了记 -bash: docker-compose: command not found 的问题解决方法,本文给大家介绍的非常详细对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2024-01-01
  • docker部署code-server的方法

    docker部署code-server的方法

    这篇文章主要介绍了docker部署code-server的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • Docker如何实现修改Docker0网桥默认网段

    Docker如何实现修改Docker0网桥默认网段

    这篇文章主要介绍了Docker如何实现修改Docker0网桥默认网段,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • 在Docker环境中部署和运行One API的操作方法

    在Docker环境中部署和运行One API的操作方法

    随着技术的发展,API 作为服务连接的桥梁,变得越来越重要,One API 是一种流行的 API 管理平台,能够帮助我们更好地管理、监控和扩展 API 服务,本文给大家介绍了如何在 Docker 环境中部署和运行 One API,需要的朋友可以参考下
    2024-11-11
  • docker如何删除悬空镜像

    docker如何删除悬空镜像

    文章介绍了如何使用Docker命令删除悬空镜像,以提高服务器空间利用率,通过使用docker image命令结合filter和awk工具,可以过滤出没有Tag的镜像,并将其删除,总结了两种方法,一种是通过管道和awk命令,另一种是使用更简单的docker rmi命令
    2025-02-02

最新评论