You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker部署Django+DRF项目遇PyO3模块初始化错误求助

问题:Docker化Django+DRF项目启动时出现PyO3初始化错误

我正在开发一个包含DRF的Docker化Django项目,此前运行一切正常,但今日执行docker-compose up -d启动容器后,日志中突然出现ImportError: PyO3 modules may only be initialized once per interpreter process错误,完全不清楚原因。

相关错误日志

patients    | [uWSGI] getting INI configuration from /patients/src/_settings/local-test/uwsgi.ini
patients    | [uwsgi-static] added mapping for /static/ => /static/
patients    | *** Starting uWSGI 2.0.21 (64bit) on [Fri Jun  2 13:59:34 2023] ***
patients    | compiled with version: 10.2.1 20210110 on 02 June 2023 10:11:18
patients    | os: Linux-5.19.0-42-generic #43~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Apr 21 16:51:08 UTC 2
patients    | nodename: 9be86066078d
patients    | machine: x86_64
patients    | clock source: unix
patients    | pcre jit disabled
patients    | detected number of CPU cores: 8
patients    | current working directory: /patients/src
patients    | detected binary path: /usr/local/bin/uwsgi
patients    | uWSGI running as root, you can use --uid/--gid/--chroot options
patients    | setgid() to 33
patients    | *** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
patients    | chdir() to /patients/src
patients    | your memory page size is 4096 bytes
patients    | detected max file descriptor number: 1048576
patients    | building mime-types dictionary from file /etc/mime.types...1476 entry found
patients    | lock engine: pthread robust mutexes
patients    | thunder lock: disabled (you can enable it with --thunder-lock)
patients    | uwsgi socket 0 bound to TCP address :8080 fd 3
patients    | uWSGI running as root, you can use --uid/--gid/--chroot options
patients    | setgid() to 33
patients    | *** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
patients    | Python version: 3.9.16 (main, May 23 2023, 14:17:54)  [GCC 10.2.1 20210110]
patients    | Python main interpreter initialized at 0x5640005ce9b0
patients    | uWSGI running as root, you can use --uid/--gid/--chroot options
patients    | setgid() to 33
patients    | *** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
patients    | python threads support enabled
patients    | your server socket listen backlog is limited to 100 connections
patients    | your mercy for graceful operations on workers is 60 seconds
patients    | mapped 618762 bytes (604 KB) for 4 cores
patients    | *** Operational MODE: preforking+threaded ***
patients    | WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0x5640005ce9b0 pid: 1 (default app)
patients    | mounting /patients/src/patients/wsgi.py on /patients
patients    | Traceback (most recent call last):
patients    |   File "/patients/src/patients/wsgi.py", line 16, in <module>
patients    |     application = get_wsgi_application()
patients    |   File "/usr/local/lib/python3.9/site-packages/django/core/wsgi.py", line 12, in get_wsgi_application
patients    |     django.setup(set_prefix=False)
patients    |   File "/usr/local/lib/python3.9/site-packages/django/__init__.py", line 24, in setup
patients    |     apps.populate(settings.INSTALLED_APPS)
patients    |   File "/usr/local/lib/python3.9/site-packages/django/apps/registry.py", line 114, in populate
patients    |     app_config.import_models()
patients    |   File "/usr/local/lib/python3.9/site-packages/django/apps/config.py", line 301, in import_models
patients    |     self.models_module = import_module(models_module_name)
patients    |   File "/usr/local/lib/python3.9/importlib/__init__.py", line 127, in import_module
patients    |     return _bootstrap._gcd_import(name[level:], package, level)
patients    |   File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
patients    |   File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
patients    |   File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
patients    |   File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
patients    |   File "<frozen importlib._bootstrap_external>", line 850, in exec_module
patients    |   File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
patients    |   File "/patients/src/./patient/models.py", line 3, in <module>
patients    |     from django_cryptography.fields import encrypt
patients    |   File "/usr/local/lib/python3.9/site-packages/django_cryptography/fields.py", line 9, in <module>
patients    |     from django_cryptography.core.signing import SignatureExpired
patients    |   File "/usr/local/lib/python3.9/site-packages/django_cryptography/core/signing.py", line 10, in <module>
patients    |     from cryptography.exceptions import InvalidSignature
patients    |   File "/usr/local/lib/python3.9/site-packages/cryptography/exceptions.py", line 9, in <module>
patients    |     from cryptography.hazmat.bindings._rust import exceptions as rust_exceptions
patients    | ImportError: PyO3 modules may only be initialized once per interpreter process

docker-compose.yml配置

version: '3'
services:
    patients:
      container_name: patients
      image: patients:latest
      restart: always
      volumes:
        - ./:/patients/
      env_file: 
        - patients.env
      command: ["uwsgi", "--ini", "/patients/src/_settings/local-test/uwsgi.ini"]
      ports:
        - 8003:8080
      build: ./

uwsgi.ini配置

[uwsgi]
http-socket = :8080
chdir =/patients/src
master = 1
processes = 2
threads = 2
static-map = /static/=/static/
mount =/patients=/patients/src/patients/wsgi.py
manage-script-name = true
buffer-size = 65535
module=patients.wsgi
vacuum = True
gid = www-data
env = PYTHONDONTWRITEBYTECODE=1

排查与解决方案

1. 调整uWSGI应用加载模式

PyO3模块要求每个Python解释器进程只能初始化一次,而uWSGI默认预加载模式会在master进程初始化应用后,将内存复制给worker进程,导致PyO3模块被重复初始化。

修改uwsgi.ini,添加以下配置:

lazy-apps = true

该选项会让每个worker进程单独初始化应用,避免master进程预加载带来的重复初始化问题。

2. 移除重复的应用挂载配置

你的uwsgi.ini中同时配置了mount和module,会导致应用被初始化两次,触发PyO3错误。建议保留其中一种配置:

  • 若不需要挂载到子路径,直接删除mount和manage-script-name两行,仅保留module=patients.wsgi;
  • 若需要挂载到/patients路径,删除module=patients.wsgi,确保只通过mount初始化一次应用。

3. 锁定依赖版本

可能是cryptography或django-cryptography依赖更新后引入了PyO3相关变化,尝试将这些依赖锁定到之前正常运行的版本。比如在requirements.txt中添加:

cryptography==39.0.1
django-cryptography==1.1

根据自身环境调整具体版本号。

4. 清理Docker缓存重新构建镜像

Docker缓存的旧依赖或编译文件可能导致问题,执行以下命令重新构建镜像:

docker-compose build --no-cache
docker-compose up -d

内容的提问来源于stack exchange,提问作者Muhammad Safwan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 04:12:38