在将Docker容器从主机A迁移到主机B之后,启动uwsgi服务后发现有报错
*** Operational MODE: preforking ***
Traceback (most recent call last):
File "./my_django_app/wsgi.py", line 12, in <module>
from django.core.wsgi import get_wsgi_application
File "/home/admin/venv2/lib/python2.7/site-packages/django/__init__.py", line 3, in <module>
from django.utils.version import get_version
File "/home/admin/venv2/lib/python2.7/site-packages/django/utils/version.py", line 3, in <module>
import datetime
ImportError: No module named datetime
unable to load app 0 (mountpoint='') (callable not found or import error)
*** no app loaded. going in full dynamic mode **
照理Docker容器迁移应该时完全一致才对,为何会出现找不到模块datetime
呢?
此外,通过WEB访问显示错误Internal Server Error
尝试了两次迁移Docker容器,出现的报错信息完全一样。
- 去除uwsgi,直接通过Django访问是正常的
python manage.py runserver 0:8000
是什么原因导致的加载错误?
容器从主机A迁移到主机B,由于主机B上的用户uid/gid和主机A迁移过来的容器中uid/gid不同同,我曾经做过一次通过工具usermod和groupmod修改用户帐号名/uid/gid
不过,第二次尝试迁移Docker容器,没有执行过更改用户uid/gid,一样报错。
- 尝试手工启动uwsgi:(
my_django_app
是Django项目)
cd my_django_app
uwsgi --socket /home/admin/venv2/sock --chmod-socket=664
有提示信息
*** Operational MODE: single process ***
*** no app loaded. going in full dynamic mode ***
*** uWSGI is running in multiple interpreter mode ***
访问web,再次出现Internal Server Error
修改 my_django_app_uwsgi.ini
[uwsgi]
# Django-related settings
# the base directory (full path)
chdir = /home/admin/my_django_app
# Django's wsgi file
app = my_django_app
module = %(app)
# the virtualenv (full path)
home = /home/admin/venv2
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 10
# the socket (use the full path to be safe
socket = /home/admin/venv2/sock
# ... with appropriate permissions - may be needed
# chmod-socket = 664
# clear environment on exit
vacuum = true
将其中的原先没有生效的段落(实际没有这个配置)
# Django's wsgi file
module = my_django_app.wsgi
修改成
# Django's wsgi file
app = my_django_app
module = %(app)
再次启动提示
*** Operational MODE: preforking ***
unable to load app 0 (mountpoint='') (callable not found or import error)
*** no app loaded. going in full dynamic mode ***
这个问题是因为参考Flask and uWSGI - unable to load app 0 (mountpoint='') (callable not found or import error)
因为uWSGI期望的变量名是application
,这个变量在my_django_app/wsgi.py
中可以看到
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_django_app.settings")
application = get_wsgi_application()
参考 How to use Django with uWSGI 应该修改成:
# Django's wsgi file
module = my_django_app.wsgi:application
此时报错重新出现:
*** Operational MODE: preforking ***
Traceback (most recent call last):
File "./my_django_app/wsgi.py", line 12, in <module>
from django.core.wsgi import get_wsgi_application
File "/home/admin/venv2/lib/python2.7/site-packages/django/__init__.py", line 3, in <module>
from django.utils.version import get_version
File "/home/admin/venv2/lib/python2.7/site-packages/django/utils/version.py", line 3, in <module>
import datetime
ImportError: No module named datetime
unable to load app 0 (mountpoint='') (callable not found or import error)
*** no app loaded. going in full dynamic mode ***
应该是Django加载datetime
模块问题,是否我迁移容器时候出现了数据丢失?
在my_django_app_uwsgi.ini
中添加一行可以使得服务启动后后台运行,并生成日志
daemonize = /home/admin/venv2/my_django_app.log
日志中报错同上
目前基本判断还是Docker迁移的问题,这次排查对daemonize方式运行uwsgi有了了解,另外摸索了Django的配置,看来官方文档配置是最准确的,还需要再改进改进。
ImportError: No module named datetime提到了解决方法,原因是操作系统升级以后导致的问题。
我的容器迁移应该没有操作系统变化才对。不过,virtualenv的环境中的python是2.7.14版本,而操作系统似乎升级过(当前是CentOS 5.11),python版本是2.4.3
mv ~/venv2 ~/venv2.bak
virtualenv venv2
source venv2/bin/activate
但是,我发现重新创建一次virtualenv虚拟环境,显示的Python版本依然是 2.7.14
- 重新从项目中获取需要的模块重新安装
参考了 Rebuilding a Virtualenv 使用以下方法找出依赖的软件包:
source venv2.bak/bin/activate
cd my_project # 进入项目目录
pip freeze > requirements.txt
然后重新安装需要的依赖
pip install -r requirements.txt
- 安装uWSGI
pip install uwsgi
经过重建virtualenv,以及重新安装了uwsgi之后,确实可以正确运行了。不过,我也发现使用pip freeze > requirements.txt
并没有完全包含所有使用的模块。例如,使用到的django-url-filter
没有列出,手工安装
pip install django-url-filter