By default, Helion Stackato uses the built-in Python Buildpack to deploy Python applications. To deploy applications using this buildpack, your application will need the following in the root directory of the application:
A list of module requirements in a manifest.yml,
requirements.txt (pip),
or requirements.pypm (pypm)
file.
A Procfile specifying the command to run the application server. For
example, the example-python-django Helion Stackato
sample has the following simple Procfile:
web: gunicorn stackato.wsgi -b 0.0.0.0:$PORT
This buildpack uses Python 2.7 by default. To specify Python 3.3, create
a runtime.txt file setting the version (python-3.3) and use
the $PYTHON_VERSION environment variable in the Procfile web:
command. For example:
web: python$PYTHON_VERSION app.py
For more information, see stackato-buildpack-python.
If your Python application is configured for running on Helion Stackato 2.10 or earlier, you can deploy it using the Legacy Buildpack, which provides an updated version of the old Python framework.
With the Legacy Buildpack, applications are run with uWSGI. Applications are started from a
top-level script called wsgi.py defining a global application
variable containing the WSGI application object. For a minimal sample
application, see wsgi-helloworld.
You may add additional arguments to uWSGI in your manifest.yml. For example:
processes:
web: $STACKATO_UWSGI --mount foo=app.py --import module
It is possible to serve static files with uWSGI.
Some applications require the user to specify the APP_URL. The following example obtains the correct urls:
import json
vcap_app = json.loads(os.environ['VCAP_APPLICATION'])
APP_URL = 'http://' + vcap_app['uris'][0]
Some minor edits are required to make your application work with a database. Python
database configurations are located inside settings.py.
Authentication details for your configured database services can be found in the os.environ variable,
under DATABASE_URL. Here is an example of getting the correct credentials.
import urlparse
DATABASES = {}
if 'DATABASE_URL' in os.environ:
url = urlparse.urlparse(os.environ['DATABASE_URL'])
DATABASES['default'] = {
'NAME': url.path[1:],
'USER': url.username,
'PASSWORD': url.password,
'HOST': url.hostname,
'PORT': url.port,
}
if url.scheme == 'postgres':
DATABASES['default']['ENGINE'] = 'django.db.backends.postgresql_psycopg2'
elif url.scheme == 'mysql':
DATABASES['default']['ENGINE'] = 'django.db.backends.mysql'
else:
DATABASES['default'] = {
'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
'NAME': 'dev.db', # Or path to database file if using sqlite3.
'USER': '', # Not used with sqlite3.
'PASSWORD': '', # Not used with sqlite3.
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
import json
vcap_services = json.loads(os.environ['VCAP_SERVICES'])
srv = vcap_services['mysql'][0]
cred = srv['credentials']
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': cred['name'],
'USER': cred['user'],
'PASSWORD': cred['password'],
'HOST': cred['hostname'],
'PORT': cred['port'],
}
}
Non-HTTP apps that run as a Helion Stackato application under the control of the Health Manager.
To deploy worker applications, you need to use the
command: key and set the
processes: web: key to Null (~).
name: python-app
framework:
type: python
runtime: python27
command: python worker.py
processes:
web: ~
It is possible to serve static files with uWSGI using processes: web: in the
manifest.yml file to specify directories that will be served statically
and not by the app.
To make a single directory serve statically, use --check-static:
processes:
web: $STACKATO_UWSGI --check-static $HOME/<directory>
To specify multiple directories with static files that do not share a common root, use --static-map:
processes:
web: $STACKATO_UWSGI --static-map /foo=$HOME/static --static-map /bar=$HOME/sub
In this case /foo/index.html would serve $HOME/static/index.html, and /bar/index.html
would serve $HOME/sub/index.html. If the file does not exist, then uWSGI will
forward the request to the app.
Note
Serving static files via uWSGI is only available for Perl and Python frameworks.
To use a different web server, instead of uWSGI, specify its startup
command in manifest.yml. Here's a sample manifest.yml used to
deploy a Django 1.4 application named dj14 using gunicorn:
name: dj14
framework:
type: python
processes:
web: gunicorn -b 0.0.0.0:$PORT dj14.wsgi
requirements:
pypm: [gunicorn]
pip: ["http://www.djangoproject.com/download/1.4-beta-1/tarball/#egg=django-1.4b1"]
The custom web server must bind to IP address 0.0.0.0 and
port $PORT. The same trick can be used to serve non-WSGI
applications (such as Tornado). See the bottle-py3 example
sample for an example.
Note
To install packages from custom repository/mirror. Use the PIP_OPTS or PYPM_OPTS environment variables.
Application dependencies such as web frameworks or modules from PyPI can be installed using PyPM and/or pip.
To install packages during application deployment with PyPM, add the
requirements to manifest.yml:
requirements:
pypm:
- tornado
- pymongo
See the manifest.yml of tornado-chat-mongo sample app for an example.
Alternatively, you can list the modules in a top-level
requirements-pypm.txt file. The format is similar, if not same, as
pip requirements files and
accepts version specification. The name of this file can be overridden
by setting the PYPM_REQUIREMENTS_FILE environment variable.
Definition pip
In addition or as alternative to PyPM, your application can also
make use of pip to install certain dependencies. The tornado-chat-mongo
sample installs pycurl using pip:
requirements:
pypm:
- tornado
- pymongo
pip:
- pycurl
If your application already contains a requirements.txt file, that file
will be automatically used to install dependencies. There is no need to specify
them manually in manifest.yml. The name of this file can be overridden
by setting the PIP_REQUIREMENTS_FILE environment variable.
Note
A bug in pip may
prevent the log file from being accessed by stackato logs.
Here is an example of pushing an app using PyPy.
First, clone the https://github.com/Stackato-Apps/werkzeug-debugger repository.
Then add a buildpack: entry to the manifest.yml file:
buildpack: git://github.com/mtigas/heroku-buildpack-pypy.git
Finally, push the app to Helion Stackato:
$ stackato push -n
Examples of deploying other frameworks are included in the GitHub samples repo: