89

I'm installing a previously built website on a new server. I'm not the original developer.

I've used Gunicorn + nginx in the past to keep the app alive (basically following this tutorial), but am having problems with it here.

I source venv/bin/activate, then ./manage.py runserver 0.0.0.0:8000 works well and everything is running as expected. I shut it down and run gunicorn --bind 0.0.0.0:8000 myproject.wsgi:application, and get the following:

[2016-09-13 01:11:47 +0000] [15259] [INFO] Starting gunicorn 19.6.0
[2016-09-13 01:11:47 +0000] [15259] [INFO] Listening at: http://0.0.0.0:8000 (15259)
[2016-09-13 01:11:47 +0000] [15259] [INFO] Using worker: sync
[2016-09-13 01:11:47 +0000] [15262] [INFO] Booting worker with pid: 15262
[2016-09-13 01:11:47 +0000] [15262] [ERROR] Exception in worker process
Traceback (most recent call last):
  File "/var/www/myproject/venv/lib/python3.5/site-packages/gunicorn/arbiter.py", line 557, in spawn_worker
    worker.init_process()
  File "/var/www/myproject/venv/lib/python3.5/site-packages/gunicorn/workers/base.py", line 126, in init_process
    self.load_wsgi()
  File "/var/www/myproject/venv/lib/python3.5/site-packages/gunicorn/workers/base.py", line 136, in load_wsgi
    self.wsgi = self.app.wsgi()
  File "/var/www/myproject/venv/lib/python3.5/site-packages/gunicorn/app/base.py", line 67, in wsgi
    self.callable = self.load()
  File "/var/www/myproject/venv/lib/python3.5/site-packages/gunicorn/app/wsgiapp.py", line 65, in load
    return self.load_wsgiapp()
  File "/var/www/myproject/venv/lib/python3.5/site-packages/gunicorn/app/wsgiapp.py", line 52, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/var/www/myproject/venv/lib/python3.5/site-packages/gunicorn/util.py", line 357, in import_app
    __import__(module)
ImportError: No module named 'myproject.wsgi'
[2016-09-13 01:11:47 +0000] [15262] [INFO] Worker exiting (pid: 15262)
[2016-09-13 01:11:47 +0000] [15259] [INFO] Shutting down: Master
[2016-09-13 01:11:47 +0000] [15259] [INFO] Reason: Worker failed to boot.

I believe it has something to do with the structure of the whole application. Before, I've built apps with the basic structure of:

myproject
├── manage.py
├── myproject
│   ├── urls.py
│   ├── views.py
│   ├── component1
│   │   ├── urls.py
│   │   └── views.py
│   ├── component2
│   │   ├── urls.py
│   │   └── views.py
├── venv
│   ├── bin
│   └── ...

This one, instead, has a structure like:

myproject
├── apps
│   ├── blog
│   │   ├── urls.py
│   │   ├── views.py
│   │     └── ...
│   ├── catalogue
│   │   ├── urls.py
│   │   ├── views.py
│   │     └── ...
│   ├── checkout
│   │   ├── urls.py
│   │   ├── views.py
│   │     └── ...
│   ├── core
│   │   ├── urls.py
│   │   ├── views.py
│   │     └── ...
│   ├── customer
│   ├── dashboard
│   └──  __init__.py
├── __init__.py
├── manage.py
├── project_static
│   ├── assets
│   ├── bower_components
│   └── js
├── public
│   ├── emails
│   ├── media
│   └── static
├── settings
│   ├── base.py
│   ├── dev.py
│   ├── __init__.py
│   ├── local.py
│   └── production.py
├── templates
│   ├── base.html
│   ├── basket
│   ├── blog
│   └── ....
├── urls.py
├── venv
│   ├── bin
│   ├── include
│   ├── lib
│   ├── pip-selfcheck.json
│   └── share
└── wsgi.py

So, there's no 'main' module running the show, which is what I expect gunicorn is looking for.

Any thoughts?

wsgi.py:

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")

application = get_wsgi_application()
Josh Correia
  • 3,807
  • 3
  • 33
  • 50
Good Idea
  • 2,481
  • 3
  • 18
  • 25
  • 1
    Where is `myproject.wsgi`? What are its contents? – Plasma Sep 13 '16 at 01:22
  • 1
    @Plasma i just updated the question to include the contents of `wsgi.py` -- from what I understand this is what gunicorn is looking for, am I mistaken? – Good Idea Sep 13 '16 at 01:39
  • If you run gunicorn by doing `gunicorn --bind 0.0.0.0:8000 myproject.wsgi:application`, then gunicorn will look for the file `myproject.wsgi` and use the variable called `application` in that file. – Plasma Sep 13 '16 at 01:40
  • 1
    I just tried this with a bare django install, the difference being that `venv` is one directory above the app. So we have: `[...]/myproject/venv` and `[...]/myproject/myproject/wsgi.py` --- this works. (there's no `myproject.wsgi`) – Good Idea Sep 13 '16 at 01:49

6 Answers6

120

Your error message is

ImportError: No module named 'myproject.wsgi'

You ran the app with

gunicorn --bind 0.0.0.0:8000 myproject.wsgi:application

And wsgi.py has the line

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")

This is the disconnect. In order to recognize the project as myproject.wsgi the parent directory would have to be on the python path... running

cd .. && gunicorn --bind 0.0.0.0:8000 myproject.wsgi:application

Would eliminate that error. However, you would then get a different error because the wsgi.py file refers to settings instead of myproject.settings. This implies that the app was intended to be run from the root directory instead of one directory up. You can figure this out for sure by looking at the code- if it uses absolute imports, do they usually say from myproject.app import ... or from app import .... If that guess is correct, your correct commmand is

gunicorn --bind 0.0.0.0:8000 wsgi:application

If the app does use myproject in all of the paths, you'll have to modify your PYTHONPATH to run it properly...

PYTHONPATH=`pwd`/.. gunicorn --bind 0.0.0.0:8000 myproject.wsgi:application
Paul Becotte
  • 9,767
  • 3
  • 34
  • 42
  • 3
    Thanks a lot, this line worked for me : `PYTHONPATH=`pwd`/.. gunicorn --bind 0.0.0.0:8000 myproject.wsgi:application` – akdeveloper May 16 '17 at 09:34
  • 2
    My hangup was that the naming convention is that of python and not the directory structure. ex: `myproject.wsgi` corresponds to `myproject/wsgi.py` and not the file `myproject.wsgi` where `wsgi` is the extension. Thanks for the helpful answer! – Asher Mancinelli Sep 01 '18 at 03:18
  • Does `myproject` in `myproject.wsgi` stands for the folder name? or the Django project name? In my case, the folder name is different, and I can't use both names – otong Mar 15 '19 at 08:16
  • That is a `fully qualified module name`. In the usual case, the first name in this path will be the top directory that contains a `__init__.py` file. – Paul Becotte Mar 15 '19 at 15:57
  • (it would be the same path you would use with `from myproject.wsgi import application`) – Paul Becotte Mar 15 '19 at 16:05
  • Can you help me explain what to do you mean by PYTHONPATH=pwd/.. gunicorn --bind 0.0.0.0:8000 myproject.wsgi:application ? I've added the PYTHONPATH="home/user/pyapps/myproject/" to the venv/bin/activate and then run gunicorn bin as: gunicorn --bind 0.0.0.0:8000 myproject.wsgi:application . in my venv the sockets runs smoothly until i restart it. Help here boys really appreciated! =) @AsherMancinelli – Seb Jun 08 '19 at 05:15
  • if wsgi.py is in the myproject folder AND there is a `__init__.py` file in that folder, in order for `myproject.wsgi:application` to be the correct path, your PYTHONPATH variable would need to contain `/home/user/pyapps`. It works because the first module you specified in your gunicorn command 'myproject' is found in the folder specified by PYTHONPATH. – Paul Becotte Jun 09 '19 at 14:56
  • The way you have it set, `myproject` is on the search path. So when you do `myproject.wsgi` is looks inside `myproject` for a folder called `myproject` (and doesn't find it). – Paul Becotte Jun 09 '19 at 14:58
  • `PYTHONPATH` environment variable works for me, alternatively, pass it that in with the `--pythonpath` parameter, which also works. https://docs.gunicorn.org/en/stable/settings.html#pythonpath – Devy Nov 12 '19 at 07:46
  • Hi @PaulBecotte I have a very similar problem can you help me please??? https://stackoverflow.com/questions/62886575/gunicorn-start-failing-no-module-found – Guillermo Zooby Jul 15 '20 at 14:43
  • I have a similar issue and i've been stucked for days. Any help will be appreciated please. https://stackoverflow.com/questions/63465541/django-vuejs-app-deployed-to-heroku-showing-application-error-on-page?noredirect=1#comment112420587_63465541 – banky Aug 27 '20 at 10:29
  • 1
    For those of you who have come here that are not using the command line to start gunicorn, use the variable name `chdir` followed by `= "/my/path/"` to change to your django project directory in your config file. – Shmack May 31 '22 at 20:05
6

For my side, My project structure is

myproject
├── manage.py
├── myproject
│   ├── wsgi.py
│   ├── ..
Dockerfile
docker-composer.yml

So in docker-composer.yml, when command

gunicorn myproject.wsgi:application --bind 0.0.0.0:8000

i get following error

ModuleNotFoundError: No module named 'myproject.wsgi'

What we have to do is, we must run gunicorn command inside folder, not project root. This is the working code

sh -c "cd ./myproject && gunicorn myproject.wsgi:application --bind 0.0.0.0:8000"

Before gunicorn command, we have to change directory with "cd ./project". Inside the "myproject" directory, gunicorn can recognise our projects clearly.

Abdullah Özel
  • 121
  • 1
  • 3
  • This was exactly what I was looking for. Changing directories using the shell instead of using gunicorn's `--chdir` option. – Nicholas Obert Aug 27 '21 at 06:23
  • For me I was deploying on digitalocean, and this is the correct answer, and i didn't need to bind the port `cd ./myproject && gunicorn myproject.wsgi:application` – Fed Sep 10 '21 at 09:34
3

Run these command after replacing your python working directory path.

# Go to your current working directory
cd /path/to/folder

# Activate your virtual environment. Ignore if already in activated mode
source /path/to/virtualenv/bin/activate

# Install gunicorn in virtualenv
pip3 install gunicorn

# Run this command. Replace PORT and app name accordingly
gunicorn --bind 0.0.0.0:5000 wsgi:app
Sateesh
  • 1,327
  • 9
  • 12
1

If you are using supervisor then you have to set environment in supervisor config file as bellow.

environment=HOME="/home/to/your/project/root"

Zubair Hassan
  • 776
  • 6
  • 14
0

I faced a similar problem. The gunicorn was being run by a globally installed package, not the one that was installed in the virtual environment. This answer helped me to figure it out.

Muhammmed Nihad
  • 161
  • 1
  • 1
  • 12
0

I was facing similar issue. I recreated the virtual environment and install gunicorn using pip3 (not using apt) and it worked fine

shyam yadav
  • 214
  • 1
  • 10