Docker部署Django项目遇PermissionError权限问题求助
解决Docker部署Django时的Python权限错误
问题场景
- 环境:Linux、Docker 18.09.0、基础镜像
python3:latest - 执行命令:
python3 manage.py runserver 0.0.0.0:8080 - 现象:MAC环境运行正常,Linux下报错
PermissionError: [Errno 1] Operation not permitted: '/usr/local/bin/python3',已尝试设置文件权限为777无效。
错误日志
web-1 | Operations to perform: web-1 | Apply all migrations: AlarmTransServer, admin, auth, contenttypes, sessions web-1 | Running migrations: web-1 | No migrations to apply. web-1 | Current environment is dev web-1 | Traceback (most recent call last): web-1 | File "/app/AlarmTransServer/manage.py", line 22, in <module> web-1 | main() web-1 | File "/app/AlarmTransServer/manage.py", line 18, in main web-1 | execute_from_command_line(sys.argv) web-1 | File "/usr/local/lib/python3.12/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line web-1 | utility.execute() web-1 | File "/usr/local/lib/python3.12/site-packages/django/core/management/__init__.py", line 436, in execute web-1 | self.fetch_command(subcommand).run_from_argv(self.argv) web-1 | File "/usr/local/lib/python3.12/site-packages/django/core/management/base.py", line 412, in run_from_argv web-1 | self.execute(*args, **cmd_options) web-1 | File "/usr/local/lib/python3.12/site-packages/django/core/management/commands/runserver.py", line 74, in execute web-1 | super().execute(*args, **options) web-1 | File "/usr/local/lib/python3.12/site-packages/django/core/management/base.py", line 458, in execute web-1 | output = self.handle(*args, **options) web-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ web-1 | File "/usr/local/lib/python3.12/site-packages/django/core/management/commands/runserver.py", line 111, in handle web-1 | self.run(**options) web-1 | File "/usr/local/lib/python3.12/site-packages/django/core/management/commands/runserver.py", line 118, in run web-1 | autoreload.run_with_reloader(self.inner_run, **options) web-1 | File "/usr/local/lib/python3.12/site-packages/django/utils/autoreload.py", line 673, in run_with_reloader web-1 | exit_code = restart_with_reloader() web-1 | ^^^^^^^^^^^^^^^^^^^^^^^ web-1 | File "/usr/local/lib/python3.12/site-packages/django/utils/autoreload.py", line 274, in restart_with_reloader web-1 | p = subprocess.run(args, env=new_environ, close_fds=False) web-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ web-1 | File "/usr/local/lib/python3.12/subprocess.py", line 548, in run web-1 | with Popen(*popenargs, **kwargs) as process: web-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ web-1 | File "/usr/local/lib/python3.12/subprocess.py", line 1026, in __init__ web-1 | self._execute_child(args, executable, preexec_fn, close_fds, web-1 | File "/usr/local/lib/python3.12/subprocess.py", line 1838, in _execute_child web-1 | self._posix_spawn(args, executable, env, restore_signals, web-1 | File "/usr/local/lib/python3.12/subprocess.py", line 1782, in _posix_spawn web-1 | self.pid = os.posix_spawn(executable, args, env, **kwargs) web-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ web-1 | PermissionError: [Errno 1] Operation not permitted: '/usr/local/bin/python3'
解决方案
1. 关闭Django自动重载
修改start.sh中的启动命令,添加--noreload参数:
APP_ENV=${APP_ENV} python3 manage.py runserver 0.0.0.0:8080 --noreload
自动重载机制需要重新启动Python进程,在Linux Docker环境下可能因安全限制被拦截,关闭后直接运行主进程即可绕过该问题。
2. 使用普通用户运行容器
在Dockerfile中添加创建普通用户并切换的步骤:
FROM python RUN apt-get update && apt-get install netcat-traditional RUN python -m pip install --upgrade pip ENV APP_HOME=/app/AlarmTransServer RUN mkdir -p ${APP_HOME} WORKDIR ${APP_HOME} ADD . ${APP_HOME} RUN chmod +x ./start.sh RUN pip install -r requirements.txt RUN pip install cryptography # 添加普通用户 RUN useradd -m django_user USER django_user EXPOSE 8080 ENTRYPOINT /bin/bash ./start.sh
默认root用户运行可能触发Linux安全模块(如SELinux)的权限限制,切换为普通用户可避免这类冲突。
3. 升级Docker版本
当前使用的Docker 18.09.0版本较旧,与Python 3.12的subprocess调用存在兼容性问题,建议升级到Docker 24.x及以上版本。
4. 调整Docker Compose安全配置
在docker-compose.yml的web服务中添加security_opt配置:
web: build: ./AlarmTransServer ports: - "8080:8080" networks: - db_network depends_on: - db restart: always tty: true stdin_open: true security_opt: - apparmor:unconfined
AppArmor的默认配置可能阻止进程创建操作,解除限制后允许subprocess正常调用Python可执行文件。
相关配置文件
Dockerfile
FROM python RUN apt-get update && apt-get install netcat-traditional RUN python -m pip install --upgrade pip ENV APP_HOME=/app/AlarmTransServer RUN mkdir -p ${APP_HOME} WORKDIR ${APP_HOME} ADD . ${APP_HOME} RUN chmod +x ./start.sh RUN pip install -r requirements.txt RUN pip install cryptography EXPOSE 8080 ENTRYPOINT /bin/bash ./start.sh
docker-compose.yml
version: "3" volumes: db_vol: networks: db_network: driver: bridge services: db: image: mysql env_file: - ./AlarmTransServer/.env networks: - db_network volumes: - db_vol:/var/lib/mysql:rw - ./compose/mysql/conf/my.cnf:/etc/mysql/my.cnf - ./compose/mysql/init:/docker-entrypoint-initdb.d/ ports: - "3306:3306" restart: always web: build: ./AlarmTransServer ports: - "8080:8080" # volumes: # - ./AlarmTransServer:/var/www/html/AlarmTransServer # - ./compose/uwsgi:/tmp # networks: - db_network depends_on: - db restart: always tty: true stdin_open: true
start.sh
#!/bin/bash while ! nc -z db 3306 ; do echo "Waiting for the MySQL Server" sleep 3 done python3 manage.py makemigrations&& python3 manage.py migrate&& APP_ENV=${APP_ENV} python3 manage.py runserver 0.0.0.0:8080 exec "$@"
内容的提问来源于stack exchange,提问作者Levy
相关产品推荐
相关产品推荐

