Running Django projects from virtualenv with Gunicorn >=19 - django

I saw news on docs.gunicorn.org for gunicorn v.19:
Deprecations
run_gunicorn, gunicorn_django and gunicorn_paster are now completely
deprecated and will be removed in the next release. Use the gunicorn
command instead.
I run my applications from virtual environments, created with virtualenv with this command in supervisor:
[program:my_app]
command=/var/www/.virtualenvs/my_app/bin/gunicorn_django -c /var/www/my_app/conf/gunicorn.conf.py
user=www-data
group=www-data
daemon=false
debug=false
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/www/my_app/log/supervisor.log
How should I change my settings to run my projects with the new version gunicorn?

The command line should be changed to the following
command=/var/www/.virtualenvs/my_app/bin/gunicorn my_app.wsgi:application -c /var/www/my_app/conf/gunicorn.conf.py
This is assuming that you have the file my_app/wsgi.py. Since Django 1.4, startproject has generated a wsgi.py file for you as part of your project. I'd assume you have this, but if not you can use the following snippet to create that file.
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_app.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
See https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/
You may need to ensure that the my_app directory is in your PYTHONPATH if it is not already, or you will get errors.
To test this out standalone on the command line with a new django project, the following should work assuming you have django and gunicorn already installed in you current environment.
django-admin.py startproject myproject
cd myproject
export PYTHONPATH=$PYTHONPATH:.
gunicorn myproject.wsgi:application -b localhost:8008

Related

Why is gunicorn running a module from a different directory?

Gunicorn 20.0.4 runs an app from a different directory. Folder structure:
folder0/
app.py
folder1/
app.py
In both app.py files there is a Flask app instance. In folder0, I run
$ gunicorn app:app
When I navigate to http://localhost:8000, I see the app from folder1 is running.
Why is this happening and how can I fix it?
Update 07/11/2020
The app from folder0 runs as expected with:
$ python3 app.py
When I rename folder1 and run gunicorn app:app in folder0, it can't find my module.
Update 07/12/2020
I opened a github issue about this here: https://github.com/benoitc/gunicorn/issues/2378

django: uwsgi not running with supervisor

This is my uwsgi ini file,
[uwsgi]
chdir=/root/projects/cbapis/cbapis
module=cbAPIs.wsgi:application
env = DJANGO_SETTINGS_MODULE=cbAPIs.settings.production
http=0.0.0.0:8002
workers=1
home=/root/projects/cbapis/cbapis/env
This is the django wsgi file,
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cbAPIs.settings.production")
application = get_wsgi_application()
When I run server with uwsgi, it runs fine,
uwsgi --ini cbapi_uwsgi_config.ini
Below is my supervisor conf for this project,
[program:djangocbapis]
command=uwsgi --ini /root/cbapi_uwsgi_config.ini
environment =
DJ_DEV_SERVER_DB_NAME="****",
DJ_DEV_SERVER_DB_USER="****",
DJ_DEV_SERVER_DB_HOST="*****",
DJ_DEV_SERVER_DB_PASSWORD="*****",
autostart=true
autorestart=true
user=root
priority=400
stderr_logfile=/var/app/cbapis/log/cbapis.log
When I run this uwsgi server via supervisor, it does not run. I get the following error in the log file,
--- no python application found, check your startup logs for errors ---
I have similar supervisor and uwsgi configuration for my other django projects in the same server, which are running fine with supervisor and uwsgi.
But I can't figure out why it cannot find python application while running with supervisor.
So, please help me in this matter.
Try to give full path to uwsgi like /usr/bin/uwsgi or /usr/local/bin/uwsgi. If you are on ubuntu/linux then type command which uwsgi to get full path. It will work.
[program:djangocbapis]
command=/usr/bin/uwsgi --ini /root/cbapi_uwsgi_config.ini
autostart=true
autorestart=true
user=root
priority=400
stderr_logfile=/var/app/cbapis/log/cbapis.log
setup the environment variable in uwsgi .ini file.
env = DJ_DEV_SERVER_DB_NAME="****",
env = DJ_DEV_SERVER_DB_USER="****",
env = DJ_DEV_SERVER_DB_HOST="*****",
env = DJ_DEV_SERVER_DB_PASSWORD="*****",

How to run Django app with Gunicorn/WSGI webserver?

I have my existing Django application running locally on my MacBook. It's directory structure looks something like this:
myproject/
mySite/
__init__.py
settings.py
urls.py
wsgi.py
myApp1/
__init__.py
models.py
views.py
manage.py
requirements.txt
Up until now, I have been using the Django toy webserver to run my app: ./manage.py runserver 0.0.0.0:8000. But now I want to use gunicorn instead. So I'm following the instructions here.
I do source myVirtualenv/bin/activate && cd myproject && gunicorn mySite.wsgi. I get the following error:
File "/usr/local/Cellar/python/2.7.12_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
File "myproject/MyApp2/models.py", line 11, in <module>
from caching.base import CachingManager, CachingMixin
ImportError: No module named caching.base
When I run ./manage.py runserver 0.0.0.0:8000 from the same location it works perfectly fine.
Why? Am I doing something wrong?
Does Django-Cache-Machine not work with Gunicorn/WSGI? How to work around this issue?
To run your project using gunicorn, try the following:
activate your virtualenv
go to your project's directory
run gunicorn mySite.wsgi:application --bind 127.0.0.1:8000
If the commands work fine, than my you are setup. Otherwise, try the following tutorial. I always use this tutorial myself, when setting up a new project for production. Try it. Setting up Django with Nginx, Gunicorn and Supervisor
You seem to have installed gunicorn globally rather than within the virtualenv, so the executable is pointing to the global Python and its site-packages directory rather than the one within the virtualenv. Reinstall gunicorn locally.

Django and gunicorn: Specify path to django.wsgi file in environment specific folders for Heroku

I have my project based on the django startproject: https://github.com/lincolnloop/django-startproject/
Here is my procfile:
web: gunicorn <myproject>.wsgi:application
Right now I have my set up like this:
[myproject]
---[conf]
------[local]
---------settings.py
------[qa]
---------settings.py
---[server_configs]
------[local]
---------django.wsgi
------[qa]
---------django.wsgi
My django.wsgi looks like this:
import os
import sys
import django.core.handlers.wsgi
sys.path.append('/app')
sys.path.append('/app/myproject')
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.conf.qa.settings'
application = django.core.handlers.wsgi.WSGIHandler()
I want to use the qa/django.wsgi for Heroku, but I am getting an error saying:
ImportError: No module named [myproject].wsgi
I have already gone through and tried solutions in this post: Configuring gunicorn for Django on Heroku but with no luck on my end.
Right now my PYTHONPATH is /app and have already tried Gunicorn+Django+Heroku. Python Path Issue with no luck either.
I had a similar problem once. Basically, you're running gunicorn from your root directory, but your wsgi is in [my_project]/[server_configs]/[qa]/.
There are two ways to go about it. If each of those directories has an init.py file, you can call it like a normal python module. Use:
web: gunicorn [myproject].[server_configs].[qa].django.wsgi:application
If they don't have init.py files (I didn't), you'll need your Procfile to switch into the proper directory. Try:
web: sh -c 'cd [server_configs]/[qa] && gunicorn django.wsgi:application'
Basically this is running a command in your shell to (1) change directories and (2) run gunicorn.
Heroku allows you to use environment variables in your Procfile. If you define an environment variable on Heroku, like so: heroku config:set WSGI_PATH=path/to/my/file/wsgi.py, then in your Procfile do: gunicorn $WSGI_PATH:application you should be good to go!

Django runserver error when specifying port

I have recently become accustomed to doing the following in my django projects so that I can test bowser compatibility on various OS (i.e. non-linux):
$ sudo ./manage.py runserver 0.0.0.0:80
This allows me to access the project through any machine on the network.
However, I just setup a new machine and this command issues the following error:
Traceback (most recent call last):
File "manage.py", line 8, in <module>
from django.core.management import execute_from_command_line
ImportError: No module named django.core.management
I understand that django is having trouble finding the module, what I don't understand is that plain old:
$ sudo ./manage.py runserver
Runs fine. All I am doing here is changing the port, surely? And, of course, it worked fine in the past.
N.B.
1. I am using Django 1.4
2. I have tried within a virtualenv and on system and I get the same result.
3. I do not have django installed system wide (just in virtualenvs)
Any help would be much appreciated.
I guess the sudo command will run the process in the superuser context, and the superuser context lack virtualenv settings.
You may try to call the python binary at your virtualenv explicitly, for example:
sudo $(which python) manage.py runserver 0.0.0.0:80
Make a shell script to set the virtualenv and call manage.py runserver, then sudo this script instead.
#!/bin/bash
source /home/darwin/.virtualenvs/foo/bin/activate
cd /path/to/project/foo
python manage.py runserver 0.0.0.0:80
Replace /home/darwin/.virtualenvs/foo with the root of your actual virtualenv and /path/to/project/foo with the root of your project.
Here's another solution, instead of creating shell script, just specify which python executable you want to use in the command:
Assuming that your virtualenv container is called .virtualenvs and there's an env called myproject in it, this is command you have to write:
$ sudo ~/.virtualenvs/myproject/bin/python manage.py runserver 0.0.0.0:80
Building upon #Paulo_Scardine's anwser:
If you want to keep your virtualenv environment variables, you can add the -E option to the sudo command:
sudo -E $(which python) manage.py runserver 0.0.0.0:80
Here's another solution, instead of creating shell script, just specify which python executable you want to use in the command:
Assuming that your virtualenv container is called venv in your project home directory, this is command you have to write:
sudo /home/mahome/PycharmProjects/sampleproject/venv/bin/python manage.py runserver 127.0.1.1:80
Run
manage.py runserver 0.0.0.0:8000
ie. run the server in different port and not the default port 80
while accessing the url use the port number