Docker中以非root用户运行Gunicorn时权限被拒求助
Docker非root用户运行Pipenv服务权限拒绝问题
问题场景
在Docker中执行以下操作时遇到权限错误:
- 以root用户创建/app目录、安装pipenv和gunicorn
- 同步依赖后创建普通用户appuser并切换
- 执行CMD启动gunicorn时触发权限拒绝
用户的Dockerfile
FROM python:3.10 ENV PYTHONUNBUFFERED 1 RUN mkdir /app WORKDIR /app RUN pip install pipenv RUN pipenv install gunicorn --skip-lock COPY Pipfile.lock ./ RUN pipenv sync RUN adduser -g "appuser" -u 1111 --disabled-password appuser USER 1111 WORKDIR /app COPY --chown=appuser:appuser ./app ./app CMD ["pipenv" , "run" , "gunicorn", ......]
报错信息
Traceback (most recent call last): File "/usr/local/bin/pipenv", line 8, in <module> sys.exit(cli()) File "/usr/local/lib/python3.10/site-packages/pipenv/vendor/click/core.py", line 1128, in __call__ return self.main(*args, **kwargs) File "/usr/local/lib/python3.10/site-packages/pipenv/cli/options.py", line 58, in main return super().main(*args, **kwargs, windows_expand_args=False) File "/usr/local/lib/python3.10/site-packages/pipenv/vendor/click/core.py", line 1053, in main rv = self.invoke(ctx) File "/usr/local/lib/python3.10/site-packages/pipenv/vendor/click/core.py", line 1659, in invoke return _process_result(sub_ctx.command.invoke(sub_ctx)) File "/usr/local/lib/python3.10/site-packages/pipenv/vendor/click/core.py", line 1395, in invoke return ctx.invoke(self.callback, **ctx.params) File "/usr/local/lib/python3.10/site-packages/pipenv/vendor/click/core.py", line 754, in invoke return __callback(*args, **kwargs) File "/usr/local/lib/python3.10/site-packages/pipenv/vendor/click/decorators.py", line 84, in new_func return ctx.invoke(f, obj, *args, **kwargs) File "/usr/local/lib/python3.10/site-packages/pipenv/vendor/click/core.py", line 754, in invoke return __callback(*args, **kwargs) File "/usr/local/lib/python3.10/site-packages/pipenv/cli/command.py", line 418, in run do_run( File "/usr/local/lib/python3.10/site-packages/pipenv/core.py", line 2735, in do_run ensure_project( File "/usr/local/lib/python3.10/site-packages/pipenv/core.py", line 520, in ensure_project if project.s.PIPENV_USE_SYSTEM or project.virtualenv_exists: File "/usr/local/lib/python3.10/site-packages/pipenv/project.py", line 252, in virtualenv_exists if os.path.exists(self.virtualenv_location): File "/usr/local/lib/python3.10/site-packages/pipenv/project.py", line 449, in virtualenv_location self._virtualenv_location = self.get_location_for_virtualenv() File "/usr/local/lib/python3.10/site-packages/pipenv/project.py", line 274, in get_location_for_virtualenv return str(get_workon_home().joinpath(self.virtualenv_name)) File "/usr/local/lib/python3.10/site-packages/pipenv/utils/shell.py", line 202, in get_workon_home os.makedirs(expanded_path, exist_ok=True) File "/usr/local/lib/python3.10/os.py", line 215, in makedirs makedirs(head, exist_ok=exist_ok) File "/usr/local/lib/python3.10/os.py", line 215, in makedirs makedirs(head, exist_ok=exist_ok) File "/usr/local/lib/python3.10/os.py", line 215, in makedirs makedirs(head, exist_ok=exist_ok) File "/usr/local/lib/python3.10/os.py", line 225, in makedirs mkdir(name, mode) PermissionError: [Errno 13] Permission denied: '/home/appuser'
错误原因
- Pipenv默认会将虚拟环境和配置文件放在当前用户的主目录(如
/root或/home/appuser) - 用root执行
pipenv install和pipenv sync时,虚拟环境相关文件属于root权限;切换到appuser后,Pipenv尝试访问/home/appuser目录,但该目录由root创建,appuser无读写权限 - 同时,appuser无法访问root创建的虚拟环境目录
解决方案
方案1:指定Pipenv虚拟环境到项目目录(推荐)
添加PIPENV_VENV_IN_PROJECT=1环境变量,让Pipenv把虚拟环境放在/app/.venv目录下,该目录已属于appuser,避免权限问题。
修改后的Dockerfile:
FROM python:3.10 ENV PYTHONUNBUFFERED 1 # 强制Pipenv将虚拟环境放在项目根目录的.venv文件夹中 ENV PIPENV_VENV_IN_PROJECT=1 RUN mkdir /app WORKDIR /app RUN pip install pipenv RUN pipenv install gunicorn --skip-lock COPY Pipfile.lock ./ RUN pipenv sync RUN adduser -g "appuser" -u 1111 --disabled-password appuser # 确保/app目录完全属于appuser RUN chown -R appuser:appuser /app USER 1111 COPY --chown=appuser:appuser ./app ./app CMD ["pipenv" , "run" , "gunicorn", "你的入口模块:应用实例"]
方案2:修复用户主目录权限
如果不想修改虚拟环境路径,可在创建用户后修改/home/appuser的权限,让appuser拥有读写权限:
# ... 保留原有步骤 ... RUN adduser -g "appuser" -u 1111 --disabled-password appuser # 修改/home/appuser目录权限为appuser所有 RUN chown -R appuser:appuser /home/appuser USER 1111 # ... 后续步骤 ...
说明
方案1更符合Docker镜像的隔离原则,虚拟环境随项目目录一起管理,避免依赖用户主目录的权限问题,也便于后续镜像维护。
内容的提问来源于stack exchange,提问作者Nimesha Premaraja
相关产品推荐
相关产品推荐

