Base path in paster configuration - python

I'm trying to deploy some Pyramid code to dotcloud. Unfortunately some paths are not mapped in the same way as in local paster deployment. When I'm running the development configuration with local server through paster serve ..., I can access static files configured in:
config.add_static_view('static', 'appname:static')
however on the dotcloud servers, when the scripts run via the following wsgi.py:
import os, sys
from paste.deploy import loadapp
current_dir = os.path.dirname(__file__)
application = loadapp('config:production.ini', relative_to=current_dir)
static content is searched for in a wrong directory. Instead of /home/dotcloud/current/static/pylons.css, it should look in /home/dotcloud/current/appname/static/pylons.css
Is there some part of wsgi configuration which can define the base directory? What am I missing? The application is run via nginx / uwsgi.
I tried to load config:../production.ini, relative_to=current_dir + '/appname' but that didn't change anything.

On DotCloud, URLs starting with /static are handled directly by nginx, not by uwsgi. That means that your code will never see those requests: they will be served straight away from the static/ subdirectory of your application.
One possible workaround is to setup a symlink from static to appname/static.
If you don't want to clutter your repository with such a symlink, you can use a postinstall script instead:
#!/bin/sh
# This creates the symlink required by DotCloud to serve static content from nginx
ln -s ~/current/appname/static ~/current/static
The symlink is sleek, but the postinstall scripts gives you the opportunity to drop in a comment in the file, to explain its purpose :-)
Future releases of DotCloud might offer a "naked configuration" toggle, where the nginx configuration won't include any special path handling, just in case you don't want them.
Meanwhile, if you want to see the nginx default configuration of your DotCloud service, you can just dotcloud ssh to your service, and inspect /etc/nginx/sites-enabled/default.

Related

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.

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.

Using Python Flask, AngularJS, test/production directories and serving requests

Here is the setup:
Using ngBoilerplate (grunt, bower, angular, the works...) to create a SAP application. On my localhost, it launches a NodeJS server so I can test the app. This all works fine minus the database/apis. Using Grunt, it will create a /build folder (which is all the non-minified source,assets, for debugging) and a /bin folder with the production code.
For the backend I have a Python flask app (which I'll use for REST API's) on Heroku. Inside the main Python script:
#app.route("/")
def index():
#index.html has the angular SAP
return make_response( open('build/index.html').read() )
I push the code to Heroku, it detects a Python app (which I believe is good as I will need Python to make my api requests), and it serves the correct index.html. I see Angular making requests to /vendor/angular.js /css/angular.css etc, when those files technically live in /build/vendor/angular.js.
I'm not sure if I'm suppose to tell Angular where to grab the files or if it's Python related.
Am I suppose to change the DOCROOT (WWW) like in LAMP land?
Do I change the routeprovider/urlrouterprovider in Angular to tell it to serve the files to a different location?
Or do I change what I'm doing in Python?
The project directory looks like:
hellworld.py
requirements.txt
runp-heroku.py
procfile
Gruntfile.js
build/ //test code
assets/
index.html
vendor/
bin/ //production code
assets/
index.html
vendor/
src/ //original code
assets/
index.html
vendor/
I never used Heroku, I usually get the Ubuntu server somewhere in the cloud and setup production manually. But the main point is that you production differs from development and you need a distinct config for production. You have two options:
Configure Flask's static_path
Or configure nginx to serve js/css you've built from the right dir

Making Django work with Apache

I have a test django project that I have been using the django development server for. I want to start using an actual apache server to properly simulate a production environment. I am using Mac OS X.
I have been using this tutorial here, but in the first set of instructions I am getting a 403 from localhost. The browser says I do not have permission to access / on the server.
When I comment out the apache config line from the tutorial, WSGIScriptAlias / /Users/username/Projects/django_books/django_books/django.wsgi I can access localhost.
This is the contents of my django.wsgi file:
import os
import sys
os.environ['DJANGO_SETTINGS_MODULE'] = 'django_books.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
path = '/Users/username/Projects/django_books/django_books'
if path not in sys.path:
sys.path.append(path)
What is causing the 403 and why can't I see my django application?
EDIT
Directory structure:
django_books
apache (empty directory right now)
random_book
__init__.py
models.py
views.py
django_books
__init__.py
django.wsgi
settings.py
urls.py
views.py
wsgi.py
media
static
css
style.css
manage.py
2ND EDIT
Permissions on all the directories:
/Users/username/Projects/django_books/django_books/django.wsgi
-rw-r--r--
/Users/username/Projects/django_books/django_books
drwxr-xr-x
/Users/username/Projects/django_books/
drwxr-xr-x
/Users/username/Projects/
drwxr-xr-x
/Users/username/
drwxr-xr-x+
/Users/
drwxr-xr-x
According to my small experience I think you must add the following lines "just below the import sys line to place your project on the path" (so juste under "import sys") like it's said in the tutorial you quote. Also, erase the second "django_books" in your path because you want to link to your site not the app in your site ;-) ("mysite" in the tutorial, not mysite/mysite)
import os
import sys
path = '/Users/username/Projects/django_books'
if path not in sys.path:
sys.path.append(path)
os.environ['DJANGO_SETTINGS_MODULE'] = 'django_books.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
Bye
It's likely an issue related either to your Apache installation, python library, or the filesystem's permissions.
Testing Apache
You don't say it in your question, but I assume from your link you are working with Apache2 and mod_wsgi.
You can test if Apache and mod_wsgi (or your wsgi module) are working properly by placing a dummy wsgi script in the place of django.wsgi . This script (stolen from mod_wsgi's docs) doesn't rely on Django and helps make sure that Apache can read and execute the wsgi script:
# test version of django.wsgi
def application(environ, start_response):
status = '200 OK'
output = 'Hello World!'
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
And restart apache
sudo service apache2 restart
Go ahead and test the page. Did it work? Great. Undo the changes to the django.wsgi script, restart Apache and test again. If the Django site still doesn't work, we need to keep looking. If the test script didn't work, there may be a problem with your Apache installation. Check apache's error log for more information about what happened. On linux it's commonly at /var/log/apache2/error.log . mod_wsgi could be improperly installed, the script's daemon may not have appropriate permission to the wsgi file.
Correcting permission errors
Apache may not be able to read and execute the wsgi file. Running ls -l in the wsgi file's directory as indicated in other answers will tell you the user and group a file belongs to (and if that user and group can read, write, or execute a given file). It's common for a default installation to have the wsgi permissions like so:
-rw------- 1 www-data www-data 1470 Aug 29 16:00 django.wsgi
If you want to use a different user for the daemon process, you need to make sure that the apache conf file defines WSGIDaemonProccess
WSGIScriptAlias / /Users/username/Projects/django_books/django_books/django.wsgi
WSGIDaemonProcess wsgi_user processes=2 threads=15 display-name=%{GROUP}
WSGIProcessGroup wsgi_group
Testing changes to these files and restarting Apache can help narrow down what's up. Keep checking the Apache log files.
Apache Configuration
Django's tutorial on setting up mod_wsgi is good, but read through mod_wsgi's wiki as well. There are a lot of helpful things to consider in your apache conf file besides WSGIScriptAlias. Make sure there is a tag pointing to the folder with your wsgi file. If there are non-public files (like django project files) in that directory, either use the apache directory (update your apache conf file) or add a tag under the node to keep those other files private. While you're in there, you may notice other things that look wrong, like an improperly configured servername, multiple virtual hosts, or other errors.
Testing Python
If you're using virtualenv (do it), make sure that
1. The WSGIDaemonProcess variable defines the appropriate site-packages and the wsgi script's location in the variable's python-path attribute
2. The daemon has rights to read the site packages in your virtualenv.
3. Your wsgi script properly imports django and your site's settings.
Logging Apache
You can increase the level of logging reported by Apache by adding a few lines to your Apache conf file. This setup gives you very verbose logging that you may want during deployment (make sure to make a log folder):
LogLevel info
ErrorLog /Users/username/Projects/django_books/logs/apache_error.log
CustomLog /Users/username/Projects/django_books/logs/apache_access.log combined
I would suspect that the www-data (or whatever user apache is running as) doesn't have access to /Users/username/Projects/django_books/django_books.
su to that user and try and access that directory and the wsgi file within it.
To print all the relevant permissions:
ls -ld /Users /Users/username /Users/username/Projects /Users/username/Projects/django_books /Users/username/Projects/django_books/django_books /Users/username/Projects/django_books/django_books/django.wsgi
You should also check the apache error logs, they might tell you what is going wrong.

Deploying a Pyramid application using uWSGI and Cherokee

I'm attempting to setup a generic Pyramid project to work with uWSGI through Cherokee, but constantly get a "no app loaded" error. All the research I've done doesn't really give me much to go on. Anyone have any ideas? Please note that I 'am' using a virtualenv via virtualenvwrapper.
This is from my development.ini
[uwsgi]
socket = 127.0.0.1:2626
master = true
processes = 1
virtualenv = /home/user/.virtualenvs/pyramid/
pythonpath = /home/user/Projects/ConventionMeStatic
And this is the command I've been trying to use to launch it: /usr/bin/uwsgi --ini development.ini --plugin python.
I can post any further details but there have been no other changes made to the project itself.
You have specified a virtualenv and a pytonpath, but you have not specified which app to load.
If you have a single-file app you can load that file with the --wsgi-file option, if you have a deployment.ini file you can use the --paste option as described here
http://projects.unbit.it/uwsgi/wiki/UsePaste
or the --ini-paste shortcuts described in examples section of the uwsgi wiki

Categories