Django application structure, - python

I'm trying to deploy my Django project to Google AppEngine, however I can't figure out how to properly set up application entrypoint.
This is my whole project structure:
app.yaml
main.py
service:
manage.py
service-project:
wsgi.py
settings.py
...
service-app-1:
...
service-app-2:
...
How can I make it work? I tried to move main.py to service directory and use entrypoint: gunicorn --chdir /service main:application in app.yaml but it results in Error: can't chdir to '/service', I guess AppEngine doesn't allow to change directory.

You need to change entrypoint: gunicorn --chdir /service main:application to entrypoint: gunicorn --chdir ./service main:application in your app.yaml.
The reason you are seeing Error: can't chdir to '/service' is because gunicorn is trying to change directory to the service folder in your root directory.
Adding dot in front of the slash will make it change directory to the service folder in your project, this is because the dot refers to the current directory where your app.yaml is.

Related

How to deploy Flask app as package to App Engine?

I'm following various tutorials from Google Cloud to try and deploy my first Python Flask application to App Engine. I organized my app as a package instead of a module, after watching the tutorial from Corey Schafer on YouTube titled: "Python Flask Tutorial: Full-Featured Web App Part 5 - Package Structure"
So now, in my working directory, I have a structure like this:
1. Project folder
1.1 myapp folder
1.1.1 __pycache__
1.1.2 static folder
1.1.3 __init__.py
1.1.4 app.yaml
1.1.5 requirements.txt
1.1.6 something_else.py
1.2 run.py
My run.py file has the following code:
from myapp import app
if __name__ == '__main__':
app.run(debug=True)
My app.yaml file looks like this:
runtime: python37
handlers:
# This configures Google App Engine to serve the files in the app's static
# directory.
- url: /static
static_dir: static
# This handler routes all requests not caught above to your main app. It is
# required when static routes are defined, but can be omitted (along with
# the entire handlers section) when there are no static files defined.
- url: /.*
script: auto
Now I am not sure how to set up my app.yaml file to specify the entry point, and also make my app run when I deploy it to App Engine. I am currently running the gcloud app deploy command via the Google Cloud SDK after I cd into myapp folder first?
The deployment phase in the console goes well, but when I check the app's browsing link, I am faced with a 502 Bad Gateway error (as I'm also expecting).
Everything works fine locally, but the deployment isn't too straightforward for me now that my app is structured like a package. Any help is greatly appreciated.
In your app.yaml, you can specify a custom entrypoint like so:
runtime: python37
entrypoint: gunicorn -b :$PORT myapp:app
Where myapp:app corresponds to the module to import the WSGI app from (from myapp import app)
You should also move your app.yaml file to be in the project folder instead, and run gcloud app deploy from there instead.
More details here: https://cloud.google.com/appengine/docs/standard/python3/runtime

Issue running Python37 on Google App Engine

I know this question has been asked in some facet or another, but I have gone through readings as shown here and I am still not seeing where my issue is as I am still unable to publish my Django 2.1.1 app in the Python37 environment in Google App Engine:
Python 3 Django on App Engine Standard: App Fails to Start
Overall what I am attempting to do is publish a simple app engine app using:
gcloud app deploy
My application works locally but when I publish, it goes through without issue, but I get the annoying:
500 Server Error message
When I look at the logs in Google I get the same error as many others have gotten:
ModuleNotFoundError: No module named 'main'
here is my relevant directory structure
project_portal
project_portal
init.py
settings.py
urls.py
wsgi.py
main.py
app.yaml
requirements.txt
my app.yaml file
runtime: python37
entrypoint: gunicorn -b :$PORT project_portal.wsgi
env: standard
handlers:
- url: .*
secure: always
redirect_http_response_code: 301
script: project_portal.wsgi.application
my project_portal/wsgi.py file
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project_portal.settings')
application = get_wsgi_application()
from main.py in project root
from project_portal.wsgi import application
from requirements.txt
django == 2.1.1
Without an entrypoint defined, it will try to start from a file called main.py. Create one, at the same level as app.yamlwith some simple logic in it:
from project_portal.wsgi import application
Edit:
Since you have an entrypoint defined, it seems that is the issue. So, make sure you have gunicorn in your 'requirements.txt':
gunicorn==19.9.0
This did not help:
Try changing
entrypoint: gunicorn -b :$PORT project_portal.wsgi
to
entrypoint: gunicorn -b :$PORT project_portal.wsgi:application

Django Heroku Profile

I am having trouble running my django app on Heroku. Following is my file structures:
---django_blog
---media_cdn
---static_cdn
---Procfile
---requirements.txt
---runtime.txt
---src
---blog
---...
---settings.py
---manage.py
---...
So 'src' is actually is my project root, and 'blog' is my app. I tried made the procfile to be
web: blog.wsgi --log-file -
and
web: src.blog.wsgi --log-file -
But none of them works. When I checked the heroku logs file, I found this error:
ImportError: No module named 'blog'
From Heroku documentation:
First, and most importantly, Heroku web applications require a
Procfile.
This file (named Procfile) is used to explicitly declare your
application’s process types and entry points. It is located in the
root of your repository.
You need to be more specific about how you declare your process types, if you are using gunicorn for this you will declare --chdir because you want to run it from different folder:
web: gunicorn --chdir src myproject.wsgi --log-file -
On the other hand I'm not using gunicorn rather I declare it like this:
web: python myproject/manage.py runserver 0.0.0.0:$PORT --noreload
FYI - Switch to gunicorn in production!

How can I deploy Django Gunicorn under Apache proxy?

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.

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