benoitc / gunicorn

gunicorn 'Green Unicorn' is a WSGI HTTP Server for UNIX, fast clients and sleepy applications.
http://www.gunicorn.org
Other
9.87k stars 1.75k forks source link

Gunicorn 23.0 Django 5.1 ModuleNotFoundError: No module named 'cloudmonitor.wsgi' #3277

Closed juparker37 closed 3 months ago

juparker37 commented 3 months ago

Hello:

I have been struggling for two days now to migrate from Django runserver to Gunicorn for production. I have read through the Guincorn settings and built a config file and I continue to get the error ModuleNotFoundError: No module named 'cloudmonitor.wsgi' even though the Django wsgi.py seems to be correct. I have tried to run "gunicorn -c gunicorn.conf.py cloudmonitor.wsgi:application" in /home/jparker/, /home/jparker/cloudmonitor, /home/jparker/cloudmonitor/cloudmonitor, even in the directory with manage.py as noted in https://docs.gunicorn.org/en/stable/run.html#django.

`[2024-08-15 15:42:09 +0000] [2454119] [ERROR] Exception in worker process Traceback (most recent call last): File "/usr/lib64/python3.11/logging/config.py", line 573, in configure handler = self.configure_handler(handlers[name]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.11/logging/config.py", line 757, in configure_handler result = factory(**kwargs) ^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.11/logging/handlers.py", line 155, in init BaseRotatingHandler.init(self, filename, mode, encoding=encoding, File "/usr/lib64/python3.11/logging/handlers.py", line 58, in init logging.FileHandler.init(self, filename, mode=mode, File "/usr/lib64/python3.11/logging/init.py", line 1181, in init StreamHandler.init(self, self._open()) ^^^^^^^^^^^^ File "/usr/lib64/python3.11/logging/init.py", line 1213, in _open return open_func(self.baseFilename, self.mode, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FileNotFoundError: [Errno 2] No such file or directory: '/opt/djangoprojects/reports/bin/gunicorn.errors'

The above exception was the direct cause of the following exception:

Traceback (most recent call last): File "/home/jparker/.local/lib/python3.11/site-packages/gunicorn/arbiter.py", line 608, in spawn_worker worker.init_process() File "/home/jparker/.local/lib/python3.11/site-packages/gunicorn/workers/base.py", line 135, in init_process self.load_wsgi() File "/home/jparker/.local/lib/python3.11/site-packages/gunicorn/workers/base.py", line 147, in load_wsgi self.wsgi = self.app.wsgi() ^^^^^^^^^^^^^^^ File "/home/jparker/.local/lib/python3.11/site-packages/gunicorn/app/base.py", line 66, in wsgi self.callable = self.load() ^^^^^^^^^^^ File "/home/jparker/.local/lib/python3.11/site-packages/gunicorn/app/wsgiapp.py", line 57, in load return self.load_wsgiapp() ^^^^^^^^^^^^^^^^^^^ File "/home/jparker/.local/lib/python3.11/site-packages/gunicorn/app/wsgiapp.py", line 47, in load_wsgiapp return util.import_app(self.app_uri) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/jparker/.local/lib/python3.11/site-packages/gunicorn/util.py", line 370, in import_app mod = importlib.import_module(module) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.11/importlib/init.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "", line 1204, in _gcd_import File "", line 1176, in _find_and_load File "", line 1147, in _find_and_load_unlocked File "", line 690, in _load_unlocked File "", line 940, in exec_module File "", line 241, in _call_with_frames_removed File "/home/jparker/cloudmonitor/cloudmonitor/wsgi.py", line 13, in application = get_wsgi_application() ^^^^^^^^^^^^^^^^^^^^^^ File "/home/jparker/.local/lib/python3.11/site-packages/django/core/wsgi.py", line 12, in get_wsgi_application django.setup(set_prefix=False) File "/home/jparker/.local/lib/python3.11/site-packages/django/init.py", line 19, in setup configure_logging(settings.LOGGING_CONFIG, settings.LOGGING) File "/home/jparker/.local/lib/python3.11/site-packages/django/utils/log.py", line 76, in configure_logging logging_config_func(logging_settings) File "/usr/lib64/python3.11/logging/config.py", line 823, in dictConfig dictConfigClass(config).configure() File "/usr/lib64/python3.11/logging/config.py", line 580, in configure raise ValueError('Unable to configure handler ' ValueError: Unable to configure handler 'gunicorn' [2024-08-15 15:42:09 +0000] [2454119] [INFO] Worker exiting (pid: 2454119) `

I have read countless Stackoverflow posts, Reddit, posted on Django forums and still unable to resolve the issue. I am wondering if this is a bug.

Below are the details of my Gunicron config file, Django wsgi.py, settings.py and environment information.

Environment information:

Django 5.1.0 Gunicorn 23.0.0 Nginx Reverse Proxy RHEL 8 Virtual Machine

whereis python

python: /usr/bin/python /usr/bin/python2.7 /usr/bin/python3.11

`python -m pip show gunicorn

Name: gunicorn Version: 23.0.0 Summary: WSGI HTTP Server for UNIX Home-page: https://gunicorn.org Author: Author-email: Benoit Chesneau benoitc@gunicorn.org License: MIT Location: /home/jparker/.local/lib/python3.11/site-packages Requires: packaging Required-by: `

python -m pip show django Name: Django Version: 5.1 Summary: A high-level Python web framework that encourages rapid development and clean, pragmatic design. Home-page: https://www.djangoproject.com/ Author: Author-email: Django Software Foundation <foundation@djangoproject.com> License: BSD-3-Clause Location: /home/jparker/.local/lib/python3.11/site-packages Requires: asgiref, sqlparse Required-by: dj-database-url, django-cors-headers, django-filter, djangorestframework

whereis gunicorn

gunicorn: /home/jparker/.local/bin/gunicorn

echo $PATH

/home/user/.local/bin:/home/user/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin

gunicorn.conf.py

#!/usr/bin/python
import gunicorn
import multiprocessing
import os
wsgi_app = "cloudmonitor.wsgi:application"
bind = "192.168.46.69:9450"
daemon = 'False'
pythonpath = '/usr/bin/python,/home/jparker/.local/bin/gunicorn,/home/jparker/cloudmonitor/cloudmonitor'
forwarded_allow_ips = '*'
workers = multiprocessing.cpu_count() * 2 + 1
worker_class = 'sync'
worker_connections = 1000
timeout = 30
keepalive = 2
default_proc_name = 'gunicorn_httpd'
certfile = "/opt/gunicorn_httpd/certs"
keyfile = "/opt/gunicorn_httpd/certs/private"
ca_certs = ""
def ssl_context(conf, default_ssl_context_factory):
    import ssl
    context = default_ssl_context_factory()
    context.minimum_version = ssl.TLSVersion.TLSv1_3
    return context
do_handshake_on_connect = 'true'
cert_reqs = "2"
limit_request_line = '8190'
disable_redirect_access_to_syslog = 'False'
errorlog = "/opt/gunicorn_httpd/logs/httpd_error.log"
accesslog = "/opt/gunicorn_httpd/logs/httpd_access.log"
loglevel = 'info'
syslog = 'False'
syslog_addr = 'udp://localhost:514'
syslog_facility = 'user'

settings.py

import os

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cloudmonitor.settings')

import environs

from pathlib import Path

from environs import Env

env = Env()

env.read_env()

BASE_DIR = Path(__file__).resolve().parent.parent

SECRET_KEY = env.str("SECRET_KEY")

DEBUG = env.bool("DEBUG", default=False)

ALLOWED_HOSTS = ['192.168.46.69', 'localhost', '127.0.0.1']

INSTALLED_APPS = [

'dashboard',

'authentication',

'rest_framework',

'django_filters',

'corsheaders',

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles',

]

CORS_ORIGIN_ALLOW_ALL = True

MIDDLEWARE = [

'django.middleware.security.SecurityMiddleware',

'django.contrib.sessions.middleware.SessionMiddleware',

'corsheaders.middleware.CorsMiddleware',

'django.middleware.common.CommonMiddleware',

'django.middleware.csrf.CsrfViewMiddleware',

'django.contrib.auth.middleware.AuthenticationMiddleware',

'django.contrib.messages.middleware.MessageMiddleware',

'django.middleware.clickjacking.XFrameOptionsMiddleware',

]

ROOT_URLCONF = 'cloudmonitor.urls'

WSGI_APPLICATION = 'cloudmonitor.wsgi.application'

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_TZ = True

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

wsgi.py

import os

from django.core.wsgi import get_wsgi_application
os.environ.setdefault(‘DJANGO_SETTINGS_MODULE’, ‘cloudmonitor.settings’)
application = get_wsgi_application()
pajod commented 3 months ago

The pythonpath with an entry where two consecutive directories carry the same name, and the one containing /bin/ (what?) makes me think you are launching gunicorn without chdir or configuring venv, yet the directories your import paths refer to are not part of your pythonpath.

juparker37 commented 3 months ago

The pythonpath with an entry where two consecutive directories carry the same name, and the one containing /bin/ (what?) makes me think you are launching gunicorn without chdir or configuring venv, yet the directories your import paths refer to are not part of your pythonpath.

Are you talking about the gunicorn.conf.py file with pythonpath? I am not using a venv as this project runs in the /home/ directory and global python is 3.11.

ls -la /home/jparker/.local/bin/

django-admin fonttools httpx mkdocs numpy-config pip3.11 pyftsubset watchmedo dotenv ghp-import jp.py mkdocs-get-deps pip pycache/ sqlformat wheel f2py gunicorn markdown_py normalizer pip3 pyftmerge ttx

juparker37 commented 3 months ago

python

Python 3.11.9 (main, Jun 19 2024, 10:02:06) [GCC 8.5.0 20210514 (Red Hat 8.5.0-22)] on linux

>>> import django
>>> django
<module 'django' from '/home/jparker/.local/lib/python3.11/site-packages/django/__init__.py'>
juparker37 commented 3 months ago

Rebuilt project using VENV, issues resolved.