How to Solve Error Message gunicorn[8881]: ModuleNotFoundError: No module named ‘app’ when running Django Application using Gunicorn Daemon

Posted on

Introduction

As an introduction, the main purpose in the beginning is to have a Django application running using gunicorn daemon. The reference to achieve it exist in another article in this link. It is an article with the title of ‘How to Install Django on CentOS 7’. Unfortunately, upon configuring Django application to run with the help of gunicorn daemon, another error message appear. The appearance occurs upon running gunicorn as a daemon. Morevoer, the error message itself is very clear. It is informing that there are no module named ‘app’ as an example. The ‘app’ name can just be anything depends on the Django application. But as an example in this article, it will just use ‘app’ for the sake of a reference. The error message appear in the following sequence of execution :

[root@localhost system]# systemctl stop gunicorn
Warning: gunicorn.service changed on disk. Run 'systemctl daemon-reload' to reload units.
[root@localhost system]# systemctl daemon-reload
[root@localhost system]# systemctl stop gunicorn
[root@localhost system]# systemctl start gunicorn
[root@localhost system]# systemctl status gunicorn
● gunicorn.service - gunicorn daemon
Loaded: loaded (/usr/lib/systemd/system/gunicorn.service; disabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Thu 2021-11-18 02:45:27 UTC; 4s ago
Process: 8881 ExecStart=/home/django/myproject/env/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/django/myproject/myproject.sock app.wsgi:application (code=exited, status=3)
Main PID: 8881 (code=exited, status=3)

Nov 18 02:45:27 localhost gunicorn[8881]: File "<frozen importlib._bootstrap>", line 994, in _gcd_import
Nov 18 02:45:27 localhost gunicorn[8881]: File "<frozen importlib._bootstrap>", line 971, in _find_and_load
Nov 18 02:45:27 localhost gunicorn[8881]: File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
Nov 18 02:45:27 localhost gunicorn[8881]: ModuleNotFoundError: No module named 'app'
Nov 18 02:45:27 localhost gunicorn[8881]: [2021-11-18 02:45:27 +0000] [8884] [INFO] Worker exiting (pid: 8884)
Nov 18 02:45:27 localhost gunicorn[8881]: [2021-11-18 02:45:27 +0000] [8881] [INFO] Shutting down: Master
Nov 18 02:45:27 localhost gunicorn[8881]: [2021-11-18 02:45:27 +0000] [8881] [INFO] Reason: Worker failed to boot.
Nov 18 02:45:27 localhost systemd[1]: gunicorn.service: main process exited, code=exited, status=3/NOTIMPLEMENTED
Nov 18 02:45:27 localhost systemd[1]: Unit gunicorn.service entered failed state.
Nov 18 02:45:27 localhost systemd[1]: gunicorn.service failed.
[root@localhost system]#

In order to make sure that the gunicorn daemon is not running, the sequence activity above started with stopping the gunicorn daemon :

[root@localhost system]# systemctl stop gunicorn

But apparently, a warning message appear informing that every modification to the systemd daemon file must execute a certain command to reload the changes in that file. It is done by typing the following command :

[root@localhost system]# systemctl daemon-reload

Continue on after is just repeating the same routine for stopping, starting and checking the status of the gunicorn daemon. Apparently, it is not starting because of some error appear. In summary, the error is showing that the module executed by gunicorn is not found.

Solution

So, how is the solution to solve the problem exist in the introduction part ?. Before moving on to the solution, the following is the actual configuration of the gunicorn daemon. It exist in ‘/usr/lib/systemd/system/’ with the name of ‘gunicorn.service’ and it has the following content below :

[Unit]
Description=gunicorn daemon
After=network.target

[Service]
User=django
Group=nginx
WorkingDirectory=/home/django/myproject/project/app
ExecStart=/home/django/myproject/env/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/django/myproject/app/app.sock app.wsgi:application

[Install]
WantedBy=multi-user.target

This content is also referring from the article exist in this link. Referring from that article, the above gunicorn daemon script is having several modifications to adjust it to the environment. But apparently, it is not enough for the Django application execution to run successfully using the gunicorn daemon with the above script. The following is the actual structure of the Django project :

[django@localhost myproject]$ tree -L 2
.
├── apps
│   ├── app
│   ├── authentication
│   ├── config.py
│   ├── __init__.py
│   └── __pycache__
├── app.yaml
├── CHANGELOG.md
├── core
│   ├── asgi.py
│   ├── core
│   ├── db.sqlite3
│   ├── __init__.py
│   ├── __pycache__
│   ├── settings.py
│   ├── static
│   ├── staticfiles
│   ├── templates
│   ├── urls.py
│   └── wsgi.py
├── db.sqlite3
├── docker-compose.yml
├── Dockerfile
├── gunicorn-cfg.py
├── LICENSE.md
├── manage.py
├── media
│   ├── banner
│   ├── dashboard-atlantis-dark-intro.gif
│   ├── dashboard-atlantis-dark-screen-1.png
│   ├── dashboard-atlantis-dark-screen-2.png
│   ├── dashboard-atlantis-dark-screen-3.png
│   ├── dashboard-atlantis-dark-screen-4.png
│   ├── dashboard-atlantis-dark-screen-5.png
│   ├── dashboard-atlantis-dark-screen-6.png
│   ├── dashboard-atlantis-dark-screen-login.png
│   ├── dashboard-atlantis-dark-screen.png
│   └── dashboard-atlantis-dark-screen-register.png
├── package.json
├── Procfile
├── README.md
├── requirements.txt
├── runtime.txt
├── staticfiles
├── admin
├── assets
├── ckeditor
├── favicon.ico
└── sitemap.xml

25 directories, 42 files
[django@localhost project]$

So, according to the Django project or Django application structure, the project root folder is in ‘/home/django/myproject’. Furthermore, the content inside myproject is a modification of a Django project or Django application using a dashboard theme layout called ‘Atlantis’. It has several default applications with the name of ‘app’ and ‘core’. So, the above error message actually hinting that it cannot found the correct module when it run with the help of ‘gunicorn’. Apparently, the most important configuration lines for locating the correct module exist as follows :

WorkingDirectory=/home/django/myproject/project/app
ExecStart=/home/django/myproject/env/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/django/myproject/app/app.sock app.wsgi:application

Comparing with the content from another article, it should be as follows :

WorkingDirectory=/home/django/myproject
ExecStart=/home/django/myproject/env/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/django/myproject/app.sock core.wsgi:application 

As a conclusion, the ‘WorkingDirectory’ must be the top root level of the project folder. On the other hand, the value of the ExecStart variable will consist of ‘gunicorn’ command with several parameters. But the most important thing is the wsgi parameter. The name of ‘core.wsgi:application’ has the ‘app’ part where it is actually the main project folder. It is where there is the existance of ‘wsgi.py’ file. It is available in the core folder. The other parameter can be adjusted accordingly.

Leave a Reply