Yah, you heard me. This post is all about deploying your beautifully simple Flask App to your shared hosting account (e.g. GoDaddy, Funio); and it is a continuation of a previous post How to Deploy a Sinatra Ruby App to your Shared Hosting.
But Why? Haven't you heard of GoogleCloud, Bluemix, Heroku, Digital Ocean, RDCloud. Dude just use a Docker container at dotCloud, you make me sick with your foolery.
There are better ways to deploy your Flask application. And you should probably learn them as they are easier, more scalable, and overall better. However, great tools come with a price tag, and you might be already paying for a shared hosting account. So let's use that yo.
A word of caution though. Your shared hosting solution is probably the less efficient way to deploy an app. Often they are optimized for a PHP stack and provide Python apps through a limited (constrained workers) configuration of Passenger. Use this as a way to prototype your hobby apps, not for production.
Getting Started. Configuring CPANEL
Your shared hosting account probably uses CPANEL. Login and find a link to Install/Deploy a Python Application. If you don't see that, then Python is not installed/available in your plan. If you do see that link go ahead and click on it:
You should see a version of Python available in your plan. Configure the App Directory to point to where you want your code to live, in my case: public_html/exampleapppython. Configure the App URI where you want your app to be accessible, in my case "exampleapppython".
The image above shows the result of clicking "setup": it will create an application pointing to a python file (in my case myapp.py) that you can edit.
One important step left to do here is to add the Flask module, without it your application will crash and burn shamelessly. Search for "Flask" and add it.
If you started from scratch using CPANEL it would have created an app in the App Directory you specified with a similar structure:
/public myapp.py passenger_wsgi.py .htaccess
If you pointed your App Directory to an existing application the CPANEL script will only add a passenger_wsgi.py file and a .htaccess file.
The "public" directory is used for assets, the "myapp.py" file is your application entry point, "passenger_wsgi.py" is a script telling passenger how to interpret your application and what file to use to serve requests, your ".htaccess" file tells Apache the App URI, App Directory, and Python Version (location) you configured in CPANEL.
The Flask APP
The Flask application is really simple, but I have added a magic line that makes this Flask deal work (application = app). The passenger_wsgi script will look for your application code in a variable called "application" not "app" as used by Flask when you developed it.
from flask import Flask app = Flask(__name__) application = app # our hosting requires application in passenger_wsgi @app.route("/") def hello(): return "This is Hello World!\n" if __name__ == "__main__": app.run()
The Passenger WSGI file
This file created by CPANEL is also quite simple, it will load the "myapp.py" source and pass it to Passenger in the "application" object. Yes, I hear you: "Why didn't I just use "app" here instead of creating a redundant "application" object in myapp.py?". Because one day, when drunk, you'll run that CPANEL script again, which will overwrite this file and you'll pull your hair bald trying to figure out why you keep getting the error "application doesn't exist".
import imp import os import sys sys.path.insert(0, os.path.dirname(__file__)) wsgi = imp.load_source('wsgi', 'myapp.py') application = wsgi.application
The htaccess file
Finally, the file that tells Apache that this is a Python application, where it lives and where Python can be found.
PassengerAppRoot "/home/roberto/public_html/exampleapppython" PassengerBaseURI "/exampleapppython" PassengerPython "/home/roberto/virtualenv/public__html_exampleapppython/2.7/bin/python2.7"
Login to CPANEL, find the link "Deploy Python Application", configure your URI and APP location, click on "setup", install the "Flask" module. This will create a base application. Create your Flask application and bind it to "application". You're done.