How can I deploy Django Gunicorn under Apache proxy? - python

I've run through the documentation and am hitting the same pages over and over again. At present I've found documentation to run off an existing myapp.wsgi file, but documentation for how to make an appropriate wsgi file is a little harder to find.
If I want to make, proxied by Apache, the equivalent of, on an older version of Gunicorn etc.:
python manage.py run_gunicorn 0.0.0.0:8888
what should I be doing to supply a WSGI file for:
gunicorn project.wsgi:application
Thanks,

Why do you think you need a special wsgi file? You just use exactly the same one you would use for any other deployment.

I assume you're not asking about the content of the wsgi file (which is often pretty standard) but how to assemble a gunicorn command line that allows gunicorn to find/use the wsgi file for your project?
When deploying to a staging server, I recall having a problem getting the Python path set so that gunicorn could find the proper wsgi file for my app. Here is a trimmed version of the gunicorn command that I ended up using:
gunicorn --pythonpath /some_path/my_app/my_app my_app.wsgi:application
In plain English, starting from the right and working backward:
There is a function named application inside a the wsgi.py file
The wsgi.py file is inside a module named my_app (which in this case is a directory containing a __init__.py file)
The my_app module is located at /some_path/my_app/my_app, so this needs to be on the PYTHONPATH.
So the full path to your wsgi.py is:
/some_path/my_app/my_app/my_app/wsgi.py.
In the same directory as wsgi.py is a __init__.py file, which causes Python to recognize that directory as a module.

Related

What is the command for starting a WSGI server for Django?

I've developed an application in Django that I usually run in development mode:
python manage.py runserver
I do the same for my deployed instances - obviously a security issue that I now want to resolve.
From the Django docs, its not clear to me how to:
For simplicity sake, I picked wsgi (over asgi): https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ . From this page, its not clear to me how my 'runserver' command changes to run the wsgi server over the development server. Should I run the wsgi.py file? That doesn't seem to do anything.
From the page above, its not clear whether wsgi is actually a server, or more a platform/type of servers. Do I need to use uwsgi/uvicorn/etc. instead?
I'm testing on windows - uvicorn is unix only, so I tried uwsgi, but thats giving me this error message: AttributeError: module 'os' has no attribute 'uname' - I guess its Unix only as well
So I'm using the docker image I was already building for deployment - uwsgi is giving me issues again because my docker image has no compiler, so I try now with gunicorn.
that should be easy: gunicorn project.wsgi, which gives me:
ModuleNotFoundError: No module named 'project/wsgi'
my folder structure looks like:
root-folder
project
wsgi.py
settings.py
django_app_1
django_app_2
manage.py
As the manual says, the gunicorn command should work as long as you run the gunicorn command from the same location as manage.py - which is what I'm doing.
I guess I'm missing something very obvious - who knows what?
The wsgi.py file just gives you a WSGI compatible application that a WSGI HTTP server (such as Gunicorn) can run.
I guess you have to run gunicorn project.wsgi from the root folder (that one containing the project module).
Typically, the directory containing manage.py and the module in which wsgi.py resides are one and the same. But not in your case.

How to create mysite.wsgi file?

I am following this tutorial http://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html to setup django with nginx and uwsgi. But I am confused about this line:
uwsgi --http :8000 --module mysite.wsgi
In the tutorial there's nothing about mysite.wsgi file. What should be the content of this file?
Actually, that's not a filename.
That's a python module path.
The relevant file is actually mysite/wsgi.py (but to import it in a python interpreter, you'd have to import mysite.wsgi, hence the name used in command line).

Heroku looking for the wrong wsgi file. Django

I'm on Django, but I'm not sure if it matters. Anyway, I get an Application Error, and when I check the logs I see the error:
ImportError: No module named redlibros.wsgi
And it is fine cause the wsgi file is not name "redlibros.wsgi", I don't even know where it gets that name. The module is named
WSGI_APPLICATION = 'letrasclub.wsgi.application' # on my settings
web: gunicorn letrasclub.wsgi --log-file - # on my procfile
and on my folders it looks like this:
LetrasClub
letrasclub
wsgi.py
templates
static
...
Any idea where to find the error?
EDIT
Ok, some extra info: I have a different repo, with a different Heroku remote. I copied that repo, changed the app, created a new Heroku remote and then pushed to the new one.
So, if I write
git remote -v
heroku https://git.heroku.com/letrasclub2.git (fetch)
heroku https://git.heroku.com/letrasclub2.git (push)
origin https://github.com/Alejoss/LetrasClub2.0.git (fetch)
origin https://github.com/Alejoss/LetrasClub2.0.git (push)
Looks fine, if I go to the old app location and write the same command I get the old remote, the one that is related to the "redlibros.wsgi" app, perfect.
Now, why when I try to push the new app to the new heroku remote, I get the error that means Heroku is looking for the Old wsgi file, I changed the wsgi name, I changed the Procfile, I changed the wsgi file declaration on the settings, what am I missing?
You look at wrong project.
You look at https://github.com/Alejoss/redlibros (I guess it's Your project), not at https://github.com/Alejoss/LetrasClub2.0

How to deploy structured Flask app on AWS elastic beanstalk

After successfully deploying a test app using the steps outlined here:
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_Python_flask.html
I tried to deploy my actual flask application which has the following structure:
myApp/
runServer.py
requirements.txt
myApp/
__init__.py
helpers.py
clean.sh
static/
myApp.css
handlers/
__init__.py
views.py
templates/
layout.html
viewOne.html
viewTwo.html
Where views.py contains my url mappings.
I have tried initializing the eb instance in the root directory as well as within the myApp module and git aws.push but I get the following error on the AWS dashboard:
ERROR Your WSGIPath refers to a file that does not exist. and the application does not work (404 for any path).
How can I deploy the above Flask application to elastic beanstalk?
I encountered a similar problem deploying a Flask application to EB, with a similar directory structure, and had to do 2 things:
Update my manage.py to create an object of name application, not app
import os
from application import create_app, db
from flask.ext.script import Manager, Shell
application = create_app(os.getenv('FLASK_CONFIG') or 'default')
manager = Manager(application)
Create .ebextensions/myapp.config, and define the following block to point to manage.py
option_settings:
"aws:elasticbeanstalk:container:python":
WSGIPath: manage.py
"aws:elasticbeanstalk:container:python:staticfiles":
"/static/": "application/static/"
This let Elastic Beanstalk find the application callable correctly.
This is described briefly at the official docs, and is described in more detail in this blog post
EDIT - see project structure below
ProjectRoot
.ebextensions
application.config
application
main
forms.py
views.py
static
templates
tests
manage.py
requirements.txt
config.py
etc, etc
Add the following to .ebextensions/<env-name>.config:
option_settings:
"aws:elasticbeanstalk:container:python":
WSGIPath: myApp/handlers/views.py
Update:
If you don't have .ebextensions directory, please create one for the project. You can find more information of what can be done regarding the container configuration in Customizing and Configuring AWS Elastic Beanstalk Environments guide.
Your WSGIPath refers to a file that does not exist.
This error appears because Beanstalk, by default, looks for application.py. Check at Beanstalk web UI, Configuration > Software Configuration, WSGIPath is mapped to application.py
Update the WSGIPath as shown in the previous replies or rename to application.py file.
As of awsebcli 3.0, you can actually edit your configuration settings to represent your WSGI path via eb config. The config command will then pull (and open it in your default command line text editor, i.e nano) an editable config based on your current configuration settings. You'll then search for WSGI and update it's path that way. After saving the file and exiting, your WSGI path will be updated automatically.
WSGI configuration was painful for me. I did changed WSCI settings using eb config command but it did not work. Below you can fix this in 5 easy steps.
1- Moved app.py function to the root of the directory (where I runned eb init command.
2- Also renamed app.py as application.py and in that initilized application as application = Flask(__name__) not app = Flask(__name__)
3- eb deploy did not worked after this (in the same project) I tried to fix config by using eb config but it was too hairy to sort it out. Delete all .extensions, .gitignore etc from your project.
4- re initialize your project on EB with eb init and follow the prompts. when deployment is done, eb open would launch your webapp (hopefully!)
When I encountered this problem it was because I was using the GUI to upload a zip of my project files. Initially I was zipping the project level directory and uploading that zip to EB.
Then I switched to simply uploading a zip of the project files themselves-ie select all files and send those to a zip-and then the GUI upload utility was able to find my application.py file without a problem because the application.py file was not in a subfolder.
Well, In my case I followed the entire process and conventions but was still getting 404. The problem was my virtual environment. I was ignoring all environment config related folders/files in my .gitignore but not in .ebignore. After creating .ebignore and ignoring all the folders/files which were not related to project code, fixed the issue.

Configuring gunicorn for Django on Heroku

I'm trying to setup a test Django project on Heroku. Following the advice here and in the Heroku Getting Started I'm trying to use gunicorn instead of the Django dev server.
This was my first attempt at the Procfile:
web: gunicorn_django --workers=4 --bind=0.0.0.0:$PORT my_project/settings.py
worker: python my_project/manage.py celeryd -E -B --loglevel=INFO
This gave me this error:
ImportError: Could not import settings 'settings.py' (Is it on sys.path?): No module named py
I decided to take a different track and followed the advice here. Now my Procfile looked like this:
web: gunicorn_django -b 0.0.0.0:\$PORT -w 9 -k gevent --max-requests 250 --preload my_project.settings
(I also updated my requirements file to include gevent.) It gave me the same error:
ImportError: Could not import settings
Finally, I just set it to settings:
web: gunicorn_django -b 0.0.0.0:\$PORT -w 9 -k gevent --max-requests 250 --preload settings
But now I get this error:
Error: django project not found
The way my Django project is set up is that the settings.py file is in the parent directory of the repo -- I don't have the Django project under another directory. It's at the same level as the virtualenv and git files. Would that be a problem? I'm sure I'm doing something simple wrong -- any help would be much appreciated.
If I follow the instructions from Heroku here and change the Procfile to this:
web: gunicorn hellodjango.wsgi -b 0.0.0.0:$PORT
Nothing happens -- no errors in the logs, but no proceses run and the app just appears dead in the water.
I have just run into this same issue. In the procfile you copied from the Heroku guide, change hellodjango.wsgi to yourproject.wsgi
Looks like we all fall victim to blindly copy-pasting now and then, but in your (and my) defense, it looks like there's no *.wsgi file that's actually being opened, it's just how you signal to gunicorn that you want it to run your django project.
I had the same exact issue that you are having. The way I was able to finally get it working was to use the django app gunicorn.
I added gunicorn to the django settings.py
'gunicorn',
I then used this as my web entry in my Procfile.
web: python manage.py run_gunicorn -b 0.0.0.0:\$PORT -w 9 -k gevent --max-requests 250 --preload
You may have to alter you .manage.py if you use a different directory structure then I did. My app was in /app, and my python path was also /app.
I had this issue and landed up having to point directly to the python path and then set the settings reference.
In the end my Procfile looks like this:
web: gunicorn_django --pythonpath=/app/project --settings=settings
I had to run heroku run which showed the env variables and that's where I was able to find the /app which I prepended to my project name.
Do you have a requirements.txt in the root folder (containing the word django), as well as a settings.py? Those appear to the be the requirements for Django app detection, as documented here.

Categories