WebFaction
Community site: login faq

I'm looking for a simple, straightforward way to install Flask.

It should also be able to support the application being mounted on a URL Path other than "/" if needed.

asked 12 Mar '13, 22:12

ryans's gravatar image

ryans ♦♦
5.0k42753
accept rate: 43%


If you're just wanting to install a new Python 3.4 Flask application, you can install it in its own virtual environment using something like:

pyvenv-3.4 myflask
myflask/bin/pip3.4 install flask

To serve it, create a Custom Application (Listening on Port) and run the flask application on the assigned port within the virtual environment (a watchdog script makes it easy to do this reliably).

Since it's a virtual environment, it's also extremely easy to deploy an app that you've developed locally.

permanent link

answered 06 Sep '14, 08:25

ryans's gravatar image

ryans ♦♦
5.0k42753
accept rate: 43%

Step 1

First, install a "mod_wsgi 3.4/Python 2.7" app from one-click installer. Do not name the application "flask"; use something else. In this example, I'll name it "myflask".

Then, mount it to a website record. I'll use "/" for my URL Path to mount it at the root of the domain, but you could mount it at a different URL Path as well; for example "/foo".

Step 2

Next, open an SSH session. Enter the following commands to deploy flask.

#!/bin/bash

# First, fill in these variables with your Application Name and URL Path:

APPNAME="myflask"
URLPATH="/"

# Step 2
# deploy the app
cd $HOME
mkdir -p $HOME/lib/python2.7
easy_install-2.7 flask
rm -r $HOME/webapps/$APPNAME/htdocs
mkdir $HOME/webapps/$APPNAME/$APPNAME
touch $HOME/webapps/$APPNAME/$APPNAME/__init__.py
touch $HOME/webapps/$APPNAME/$APPNAME/index.py
echo "import sys" > $HOME/webapps/$APPNAME/wsgi.py
echo "sys.path.insert(0, '$HOME/webapps/$APPNAME')" >> $HOME/webapps/$APPNAME/wsgi.py
echo -e "from $APPNAME import app as application\n" >> $HOME/webapps/$APPNAME/wsgi.py
sed -i "s^WSGILazyInitialization On^WSGILazyInitialization On\nWSGIScriptAlias / $HOME/webapps/$APPNAME/wsgi.py^" $HOME/webapps/$APPNAME/apache2/conf/httpd.conf
sed -i "s^AddHandler wsgi-script .py^AddHandler wsgi-script .py\n    RewriteEngine on\n    RewriteBase /\n    WSGIScriptReloading On^" $HOME/webapps/$APPNAME/apache2/conf/httpd.conf
sed -i "s/htdocs/$APPNAME/g" $HOME/webapps/$APPNAME/apache2/conf/httpd.conf

cat << EOF >> $HOME/webapps/$APPNAME/$APPNAME/__init__.py
from flask import Flask
app = Flask(__name__)

EOF

if [[ "$URLPATH" != "/" ]]; then
cat << EOF >> $HOME/webapps/$APPNAME/$APPNAME/__init__.py
class WebFactionMiddleware(object):
    def __init__(self, app):
        self.app = app
    def __call__(self, environ, start_response):
        environ['SCRIPT_NAME'] = '$URLPATH'
        return self.app(environ, start_response)

app.wsgi_app = WebFactionMiddleware(app.wsgi_app)

EOF
fi

cat << EOF >> $HOME/webapps/$APPNAME/$APPNAME/__init__.py
@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()
EOF

# Step 3
$HOME/webapps/$APPNAME/apache2/bin/restart

Hope that helps!

Acknowledgements: I incorporated pieces of the Flask WSGI guide, Flask WebFaction Snippet, and Flask Hello World example to create this guide.

permanent link
This answer is marked "community wiki".

answered 12 Mar '13, 22:16

ryans's gravatar image

ryans ♦♦
5.0k42753
accept rate: 43%

edited 12 Mar '13, 22:31

Awesome reference and resource Ryan. Thank you for posting what you learned.

Any guidance on how I could modify/update your script to allow the application to use virtualenvwrapper?

Chris K.

(15 Aug '13, 00:54) chrislkeller chrislkeller's gravatar image

Hi Chris, First of all, let me say that the use of virtualenv is not recommended and it is usually much better to just configure things as described in the above post. But if you really want to add extra layers of abstraction and complexity into your app, here is how you can do it.

(15 Aug '13, 11:25) likebike likebike's gravatar image

Well written Ryans.

I noticed you put everything into the 'init.py' file (markup kills the underscores, sorry) instead of the index.py that you created in step 2. One can easily put the code in index.py and have the page still load if you modify the wsgi file to:

from $APPNAME.index import app as application

This allows the 'init.py' to remain empty or have additional package information in it, instead of code. This also helps avoiding confusion or conflicts when further code is developed.

(13 Sep '13, 09:36) pbulsink pbulsink's gravatar image

Thanks SO MUCH Ryan. It worked like a charm. Love and peace, Joe

(06 Mar '15, 00:57) jdor jdor's gravatar image

Thanks for the effort releasing this - worked great!

(01 Aug '16, 20:48) Baron Baron's gravatar image

I've created a project that automates creating a local Flask development environment, a production Flask environment on Webfaction, and hooks the two together. At the end of the automation you'll have a local Git repo with a Python virtualenv with Flask installed, a deployed minimal working Flask app, and a Fabric deployment script.

Check it out on GitHub

permanent link

answered 26 Feb '16, 04:04

edgewood's gravatar image

edgewood
413
accept rate: 0%

This is the best resource I've found: Deploying a Flask Project on Webfaction

All it's missing is a middleware snippet if you intend to serve from somewhere other than "/". Luckily, the author of Flask has provided such a snippet

This might not differ tremendously from @ryans solution, but most of the time I'm trying to push an existing project onto WF, so creating it on the fly in the command line like that isn't practical nor is it consistent with how I've ever done any development.

Seeing things broken down in steps and by file, like in the post that I've linked to, is much more intuitive to me.

permanent link

answered 03 Sep '14, 19:34

mattparrilla's gravatar image

mattparrilla
113
accept rate: 0%

Hi there,

any chance someone can add clear step-by-step instructions on how to set the static folder on Flask to be served by nginx? I cannot find any simple, straightforward solution.

Edit: After searching around, I found this answer which allowed me to find the solution:

  1. On the Control Panel, select Aplications and create a new application Symbolic link to static-only app. Then, on the Extra Info write the path to the static folder you which to be served by nginx. You must use the full path, as in /home/username/webapps/myapp/myapp/static.
  2. Then, on Websites, select your Flask application, and on Contents add the application you created with the symbolic link. When you select the application, it will ask you for the URL, and there you should write the url of the static folder. For instance, if your Flask app is at myflask.myurl.com, and your static folder is called static, the url for the static folder will be myflask.myurl.com/static.

Done!

permanent link

answered 02 Feb '15, 18:27

joaoventura's gravatar image

joaoventura
112
accept rate: 0%

edited 02 Feb '15, 18:45

Where are the logs in such an application? I can't seem to find anything for troubleshooting purposes.

permanent link

answered 10 Aug '15, 15:10

walton's gravatar image

walton
111
accept rate: 0%

Your app's access and error logs can be found in ~/logs/user, with the names access_appname.log and error_appname.log.

(10 Aug '15, 15:15) seanf ♦♦ seanf's gravatar image

I've just written a small step-by-step tutorial on my personal blog on how to setup Flask on webfaction. You can find it here: http://joaoventura.net/blog/2016/flask-webfaction/

The idea is simple, and I'll write a condensed version here, should my blog disappear someday:

  • An example with a simple Flask application inside myproject/src/server.py. Since it has no __init__.py, the src folder is not a python package. This is relevant because the src folder must be added to sys.path later on.

  • In the example, Flask is installed locally on a virtual environment (and it will be installed also on a venv in the WebFaction server). Use "pyvenv-3.5 virtualenv" to create the venv, activate it and then pip install.

The local directory structure should look like:

myproject/
    - src/
        - myserver.py
    - virtualenv/
  • In the WebFaction control panel create an mod_wsgi application with the latest Python version (I use 3.5 at this time).

  • Ssh into your webfaction account and cd into ~/webapps/myproject/. Create the virtual environment the same way, activate it and install Flask.

  • Copy your src folder to ~/webapps/myproject/.

  • Configure apache and wsgi index.py:

Use vim to open the apache configuration file (myproject/apache2/conf/httpd.conf) and do the following changes:

Load the alias module:

LoadModule rewrite_module    modules/mod_rewrite.so
LoadModule setenvif_module   modules/mod_setenvif.so
LoadModule wsgi_module       modules/mod_wsgi.so
LoadModule unixd_module      modules/mod_unixd.so
LoadModule alias_module      modules/mod_alias.so           # <- Added this one

Modify the Directory section:

Directory /home/myusername/webapps/myproject/htdocs
    Options +ExecCGI
    AddHandler wsgi-script .py
    RewriteEngine On                    # <- Added this
    RewriteBase /                       # <- this
    WSGIScriptReloading On              # <- and this..
/Directory

Add the following lines at the end of the file so that your url's don't have "/index.py/" as prefix and that the static folder is served by apache:

# This will ensure that <my-domain>/static points to the flask static directory
Alias /static/ /home/myusername/webapps/myproject/src/static/

# This points to the file that launches the site
Alias / /home/myusername/webapps/myproject/htdocs/index.py/

Finally open htdocs/index.py with vim and do the following changes:

import os
import sys

CURRENT_FILE = os.path.abspath(__file__)
CURRENT_DIR = os.path.dirname(CURRENT_FILE)
PROJECT_DIR = os.path.dirname(CURRENT_DIR)

# Add project top-dir to path (since it has no __init__.py)
sys.path.append(PROJECT_DIR + '/src/')

# Add virtualenv to path
sys.path.append(PROJECT_DIR + '/virtualenv/lib/python3.5/site-packages/')

# Export the Flask app object from the project as wsgi application object
from myserver import app as application

Save files, make sure the server restarts (./apache2/bin/restart) and everything should work..

permanent link
This answer is marked "community wiki".

answered 05 May '16, 21:03

joaoventura's gravatar image

joaoventura
112
accept rate: 0%

edited 05 May '16, 21:06

Thanks for sharing!

However, I'll recommend a couple of changes:

  • Instead of crufting up your index.py with deployment-specific items for your sys.path, you can instead add those directories to the WSGIPythonPath directive in httpd.conf.
  • Instead of making an alias to serve static assets from your back-end Apache, you should instead create a static-only symlink app in our control panel, pointing at your /home/myusername/webapps/myproject/src/static/ directory, and then add that app to your site using /static as the URL path. Doing so will make your app faster and will reduce its memory footprint, since your Apache won't be doing the extra work of serving your static content.
(05 May '16, 21:09) seanf ♦♦ seanf's gravatar image

Hi Sean, you're right!

In my blog post I talk a little bit about the WSGIPythonPath and the WSGIDaemonProcess, although I still prefer to have python "things" in python files. Regarding your other suggestion about creating a static-only app to serve the static content, it is definitely the recommend way..

(05 May '16, 23:13) joaoventura joaoventura's gravatar image

Hello,

I followed joaoventura tutorial and was able to deploy my flask app, nonetheless it needed a few tweaks:

  • I needed to add "Options +ExecCGI" to my Directory section in httpd.conf
  • I needed to create a main.py to point in index.py, it imports the app, views and models needed.
  • I needed to move all my static files from myapp/static to /static/.
  • I needed to remove index.py from the line "Alias / /home/<username>/webapps/<myapp>/htdocs/index.py" in httpd.conf.
  • I added the virtualenv to the WSGIDaemonProcess declaration - as it wasnt loading in any other way..

now the app is running except I got index.py as suffix in all my urls, even if in my httpd.conf I have the WSGIScriptAlias declaration: "WSGIScriptAlias / /home/<username>/webapps/<myapp>/htdocs/index.py"

Obviously that <username> and <myapp> are just generic references..

Can anyone help me solving this issue? Why WSGIScriptAlias isn't working???

Thx,

All the best,

ktk

permanent link

answered 10 Nov '16, 11:25

ktk's gravatar image

ktk
111
accept rate: 0%

Here is a complete httpd.conf for your setup:

ServerRoot "/home/USERNAME/webapps/APPNAME/apache2"

LoadModule authz_core_module modules/mod_authz_core.so
LoadModule dir_module        modules/mod_dir.so
LoadModule env_module        modules/mod_env.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule mime_module       modules/mod_mime.so
LoadModule rewrite_module    modules/mod_rewrite.so
LoadModule setenvif_module   modules/mod_setenvif.so
LoadModule wsgi_module       modules/mod_wsgi.so
LoadModule unixd_module      modules/mod_unixd.so
LoadModule alias_module      modules/mod_alias.so

LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
CustomLog /home/USERNAME/logs/user/access_APPNAME.log combined
ErrorLog /home/USERNAME/logs/user/error_APPNAME.log

DirectoryIndex index.py
DocumentRoot /home/USERNAME/webapps/APPNAME/htdocs

Listen 55555
KeepAlive Off
SetEnvIf X-Forwarded-SSL on HTTPS=1
ServerLimit 1
StartServers 1
MaxRequestWorkers 5
MinSpareThreads 1
MaxSpareThreads 3
ThreadsPerChild 5

# this sets up your virtualenv
WSGIPythonHome /home/USERNAME/webapps/APPNAME/ENV_DIR

# python-path here is for your Flask project, nothing else.
WSGIDaemonProcess APPNAME processes=2 threads=12 python-path=/home/USERNAME/webapps/APPNAME/APPNAME
WSGIProcessGroup APPNAME
WSGIRestrictEmbedded On
WSGILazyInitialization On

# this is for your static assets
Alias /static/ /home/USERNAME/webapps/APPNAME/APPNAME/static/

# this serves your app
WSGIScriptAlias / /home/USERNAME/webapps/APPNAME/htdocs/index.py

Be sure to change the Listen port number, USERNAME, APPNAME, and ENV_DIR to the correct values for your app.

Also, there's no need to modify sys.path in your index.py - your Python path is configured entirely in the httpd.conf above.

Hope that helps!

(11 Nov '16, 01:50) seanf ♦♦ seanf's gravatar image

Hello seanf, Sorry for this delayed answer...

1st) Thx for the config file!!! 2nd) What do you mean by the sys.path in the index.py file??? Then my index.py file just looks like:

from main import app as application

Could it be? If yes, something is wrong because I keep having a gateway timeout error!!! Do you have an idea???

All the best,

MFC

(01 Dec '16, 15:28) ktk ktk's gravatar image

Also, now my root domain doesnt resolve: it redirects to index.py which returns a 404!

all other urls are working except the root url...

Any ideas??

All the best

(01 Dec '16, 15:43) ktk ktk's gravatar image

1st) Thx for the config file!!! 2nd) What do you mean by the sys.path in the index.py file??? Then my index.py file just looks like:

from main import app as application

Could it be? If yes, something is wrong because I keep having a gateway timeout error!!! Do you have an idea???

What I mean is that you don't need to set sys.path in your index.py at all. The Python search path is set in your httpd.conf.

The timeout is probably due to a Python C extension module, some of which are known to cause timeouts when used under mod_wsgi. There's a clear explanation of the problem (direct from the author of mod_wsgi) available at http://serverfault.com/a/514251/109598

The solution is simple - add the following to the app's httpd.conf:

WSGIApplicationGroup %{GLOBAL}

Be sure to restart the app's Apache after making that change.

Also, now my root domain doesnt resolve: it redirects to index.py which returns a 404!

We'd have to take a look at your actual code to assist with that. Please open a support ticket for further assistance.

(01 Dec '16, 19:47) seanf ♦♦ seanf's gravatar image

Hello seanf!

Again, thx for your help I trully appreciate it!

I checked the logs and in fact the problem was way simpler: 1st problem: an error in my config was pointing the server name wrongly; 2nd problem: also in my config file was preventing the images to load, the app kept trying till it got a timeout I've set; After correcting these issues theh app restarted smoothly..

Just for info: Yes, my index.py now only have the line that initiates the app..

Again seanf, thx for your help!!!

permanent link

answered 02 Dec '16, 07:33

ktk's gravatar image

ktk
111
accept rate: 0%

Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Question tags:

×41

question asked: 12 Mar '13, 22:12

question was seen: 12,030 times

last updated: 02 Dec '16, 07:33

WEBFACTION
REACH US
SUPPORT
AFFILIATE PROGRAM
LEGAL
© COPYRIGHT 2003-2016 SWARMA LIMITED - WEBFACTION IS A SERVICE OF SWARMA LIMITED
REGISTERED IN ENGLAND AND WALES 5729350 - VAT REGISTRATION NUMBER 877397162
5TH FLOOR, THE OLD VINYL FACTORY, HAYES, UB3 1HA, UNITED KINGDOM