使用docker exec时的权限最佳实践及容器文件写入权限问题问询
问题原因
你遇到的权限报错是因为:Docker默认创建的工作目录、COPY复制的文件所有者均为root,你切换到app用户后,/app目录的权限为rwxr-xr-x,普通用户只有读和执行权限,没有写权限,因此无法创建新文件。
疑问解答
是否需要给/app目录设置app所有者?
按需选择:
- 开发环境:可以将整个
/app目录设为app所有,方便调试时修改文件、新增临时内容 - 生产环境:不建议这么做,遵循最小权限原则,仅给应用运行时需要写入的特定子目录(如日志目录、临时文件目录)分配
app的写权限即可,代码、依赖等不需要修改的内容保持root所有,降低攻击面。
新增非root用户的意义是什么?
非root用户运行容器是容器安全的核心最佳实践之一:即使容器内的应用存在漏洞被攻击者利用,攻击者最多只能拿到普通用户的权限,无法修改系统配置、安装恶意软件、越权访问宿主机资源,能大幅降低安全风险。
修复方案
方案1:开发环境,整个/app目录归app所有
调整Dockerfile顺序,在COPY指令中增加--chown参数指定文件所有者:
FROM node:14.16.0-alpine3.13 # 第一步:创建用户和用户组 RUN addgroup app && adduser -S -G app app WORKDIR /app ENV PATH /app/node_modules/.bin:$PATH # 复制依赖声明文件,指定所有者为app COPY --chown=app:app package*.json ./ RUN npm install # 复制剩余代码,指定所有者为app COPY --chown=app:app . . ENV APP_URL=http://api.myapp.com EXPOSE 3000 # 最后切换到app用户运行应用 USER app CMD ["npm", "start"]
注:Docker的COPY指令不受当前USER影响,默认复制的文件所有者为root,必须显式加--chown参数修改归属
方案2:生产环境,仅开放必要目录写权限
假设你的应用仅需要在/app/logs目录写入日志,单独给该目录授权即可:
FROM node:14.16.0-alpine3.13 RUN addgroup app && adduser -S -G app app WORKDIR /app ENV PATH /app/node_modules/.bin:$PATH COPY package*.json ./ RUN npm install COPY . . # 单独创建需要写入的目录,修改所有者为app RUN mkdir logs && chown -R app:app logs ENV APP_URL=http://api.myapp.com EXPOSE 3000 USER app CMD ["npm", "start"]
临时解决方式
如果需要临时在已运行的容器中添加文件,可在exec时指定root用户进入:docker exec -it -u root 187 sh
操作完成后退出即可,无需修改镜像配置。
最佳实践总结
- 所有生产容器必须以非root用户运行,禁止使用root用户启动应用进程
- 仅给应用运行时必须写入的目录分配写权限,不需要修改的代码、依赖文件保持root所有
- 不要为了省事给目录设置777权限,避免出现越权操作风险
- COPY文件时按需使用
--chown参数,避免后续额外执行chown增加镜像层体积
内容的提问来源于stack exchange,提问作者Nothing here
相关产品推荐
相关产品推荐

