// Tutorial //

How To Deploy a Flask Application on an Ubuntu VPS

Published on July 3, 2013
Default avatar
By Kundan Singh
Developer and author at DigitalOcean.
How To Deploy a Flask Application on an Ubuntu VPS
Not using Ubuntu 12.04?Choose a different version or distribution.

What the Highlighting Means

The lines that the user needs to enter or customize will be highlighed in this tutorial! The rest should mostly be copy-and-pastable.

Introduction

Flask is a micro-framework written in Python and based on the Werkzeug and Jinja2 template engine for developing web applications. It is intended for developing web apps quickly.

Setup

You need to have Apache already installed and running on your VPS. If this is not the case, follow Step One of our article on installing a LAMP stack on Ubuntu.

Step One— Install and Enable mod_wsgi

WSGI (Web Server Gateway Interface) is an interface between web servers and web apps for python. Mod_wsgi is an Apache HTTP server mod that enables Apache to serve Flask applications.

Open terminal and type the following command to install mod_wsgi:

sudo apt-get install libapache2-mod-wsgi python-dev

To enable mod_wsgi, run the following command:

sudo a2enmod wsgi 

Step Two – Creating a Flask App

In this step, we will create a flask app. We will place our app in the /var/www directory.

Use the following command to move to the /var/www directory:

cd /var/www 

Create the application directory structure using mkdir as shown. Replace "FlaskApp" with the name you would like to give your application. Create the initial directory FlaskApp by giving following command:

sudo mkdir FlaskApp

Move inside this directory using the following command:

cd FlaskApp

Create another directory FlaskApp by giving following command:

sudo mkdir FlaskApp

Then, move inside this directory and create two subdirectories named static and templates using the following commands:

cd FlaskApp
sudo mkdir static templates

Your directory structure should now look like this:

|----FlaskApp
|---------FlaskApp
|--------------static
|--------------templates

Now, create the __init__.py file that will contain the flask application logic.

sudo nano __init__.py 

Add following logic to the file:

from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
    return "Hello, I love Digital Ocean!"
if __name__ == "__main__":
    app.run()

Save and close the file.

Step Three – Install Flask

Setting up a virtual environment will keep the application and its dependencies isolated from the main system. Changes to it will not affect the cloud server's system configurations.

In this step, we will create a virtual environment for our flask application.

We will use pip to install virtualenv and Flask. If pip is not installed, install it on Ubuntu through apt-get.

sudo apt-get install python-pip 

If virtualenv is not installed, use pip to install it using following command:

sudo pip install virtualenv 

Give the following command (where venv is the name you would like to give your temporary environment):

sudo virtualenv venv

Now, install Flask in that environment by activating the virtual environment with the following command:

source venv/bin/activate 

Give this command to install Flask inside:

sudo pip install Flask 

Next, run the following command to test if the installation is successful and the app is running:

sudo python __init__.py 

It should display “Running on http://localhost:5000/” or "Running on http://127.0.0.1:5000/". If you see this message, you have successfully configured the app.

To deactivate the environment, give the following command:

deactivate

Step Four – Configure and Enable a New Virtual Host

Issue the following command in your terminal:

sudo nano /etc/apache2/sites-available/FlaskApp

NOTE: Newer versions of Ubuntu (13.10+) require a ".conf" extension for VirtualHost files -- run the following command instead:

sudo nano /etc/apache2/sites-available/FlaskApp.conf

Add the following lines of code to the file to configure the virtual host. Be sure to change the ServerName to your domain or cloud server's IP address:

<VirtualHost *:80>
		ServerName mywebsite.com
		ServerAdmin admin@mywebsite.com
		WSGIScriptAlias / /var/www/FlaskApp/flaskapp.wsgi
		<Directory /var/www/FlaskApp/FlaskApp/>
			Order allow,deny
			Allow from all
		</Directory>
		Alias /static /var/www/FlaskApp/FlaskApp/static
		<Directory /var/www/FlaskApp/FlaskApp/static/>
			Order allow,deny
			Allow from all
		</Directory>
		ErrorLog ${APACHE_LOG_DIR}/error.log
		LogLevel warn
		CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Save and close the file.

Enable the virtual host with the following command:

sudo a2ensite FlaskApp

Step Five – Create the .wsgi File

Apache uses the .wsgi file to serve the Flask app. Move to the /var/www/FlaskApp directory and create a file named flaskapp.wsgi with following commands:

cd /var/www/FlaskApp
sudo nano flaskapp.wsgi 

Add the following lines of code to the flaskapp.wsgi file:

#!/usr/bin/python
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,"/var/www/FlaskApp/")

from FlaskApp import app as application
application.secret_key = 'Add your secret key'

Now your directory structure should look like this:

|--------FlaskApp
|----------------FlaskApp
|-----------------------static
|-----------------------templates
|-----------------------venv
|-----------------------__init__.py
|----------------flaskapp.wsgi

Step Six – Restart Apache

Restart Apache with the following command to apply the changes:

sudo service apache2 restart 

You may see a message similar to the following:

Could not reliably determine the VPS's fully qualified domain name, using 127.0.0.1 for ServerName 

This message is just a warning, and you will be able to access your virtual host without any further issues. To view your application, open your browser and navigate to the domain name or IP address that you entered in your virtual host configuration.

You have successfully deployed a flask application.

Article Submitted by: Kundan Singh

Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.

Sign up
About the authors
Default avatar
Developer and author at DigitalOcean.

Still looking for an answer?

Was this helpful?
10 Comments

I have followed everything step by step and it works fine with the ‘Hello World’ app you use an example; but, when I upload my own application and try it in my browser, ****the page is loading indefinitely (‘waiting for host…’) ****so I do not get any errors to help me debug. Any idea what this could be??

Thanks for this amazing article!

No point of installing virtualenv if you do this:

sudo pip install virtualenv 

That command installs packages globally.

This tutorial needs a bit renowation. But … let’s try to patch it :)

Today, january 2016, you are probably interested in python 3

  1. libapache2-mod-wsgi should be libapache2-mod-wsgi-py3

  2. python-pip should be python3-pip

  3. “sudo pip install virtualenv” should be “sudo pip3 install virtualenv” (there is more options for ve but some didn’t work for me)

  4. "sudo pip install Flask " > "sudo pip3 install Flask "

Now serious stuff …

apache config between <virtualhost> must have:

WSGIDaemonProcess <flaskapp> user=flask group=www-data threads=5 python-path=/var/www/<flaskapp>:/var/www/<flaskapp>/<flaskapp>/venv/lib/python3.4/site-packages

example:

<VirtualHost *:80> ServerName mywebsite.com ServerAdmin admin@mywebsite.com WSGIDaemonProcess <flaskapp> user=flask group=www-data threads=5 python-path=/var/www/<flaskapp>:/var/www/<flaskapp>/<flaskapp>/venv/lib/python3.4/site-packages WSGIScriptAlias / /var/www/FlaskApp/flaskapp.wsgi <Directory /var/www/FlaskApp/FlaskApp/> Order allow,deny Allow from all </Directory> Alias /static /var/www/FlaskApp/FlaskApp/static <Directory /var/www/FlaskApp/FlaskApp/static/> Order allow,deny Allow from all </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>

But this will only work if you have additional 2 lines in flaskapp.wsgi:

activate_this = ‘/var/www/<flaskapp>/<flaskapp>/venv/bin/activate_this.py’ exec(compile(open(activate_this,“rb”).read(),activate_this, ‘exec’), dict(file=activate_this))

There is alternative, you can put next line in apache config outside of <virtualhost>:

#WSGIPythonPath /var/www/<flaskapp>/<flaskapp>/venv/lib/python3.4/site-packages

Above code was my day … farewell :)

This tutorial needs a bit renowation. But … let’s try to patch it :)

Today, january 2016, you are probably interested in python 3

  1. libapache2-mod-wsgi should be libapache2-mod-wsgi-py3

  2. python-pip should be python3-pip

  3. “sudo pip install virtualenv” should be “sudo pip3 install virtualenv” (there is more options for ve but some didn’t work for me)

  4. "sudo pip install Flask " > "sudo pip3 install Flask "

Now serious stuff …

apache config between <virtualhost> must have:

WSGIDaemonProcess <flaskapp> user=flask group=www-data threads=5 python-path=/var/www/<flaskapp>:/var/www/<flaskapp>/<flaskapp>/venv/lib/python3.4/site-packages

example:

<VirtualHost *:80> ServerName mywebsite.com ServerAdmin admin@mywebsite.com WSGIDaemonProcess <flaskapp> user=flask group=www-data threads=5 python-path=/var/www/<flaskapp>:/var/www/<flaskapp>/<flaskapp>/venv/lib/python3.4/site-packages WSGIScriptAlias / /var/www/FlaskApp/flaskapp.wsgi <Directory /var/www/FlaskApp/FlaskApp/> Order allow,deny Allow from all </Directory> Alias /static /var/www/FlaskApp/FlaskApp/static <Directory /var/www/FlaskApp/FlaskApp/static/> Order allow,deny Allow from all </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>

But this will only work if you have additional 2 lines in flaskapp.wsgi:

activate_this = ‘/var/www/<flaskapp>/<flaskapp>/venv/bin/activate_this.py’ exec(compile(open(activate_this,“rb”).read(),activate_this, ‘exec’), dict(file=activate_this))

There is alternative, you can put next line in apache config outside of <virtualhost>:

#WSGIPythonPath /var/www/<flaskapp>/<flaskapp>/venv/lib/python3.4/site-packages

Above code was my day … farewell :)

This tutorial needs a bit renowation. But … let’s try to patch it :)

Today, january 2016, you are probably interested in python 3

  1. libapache2-mod-wsgi should be libapache2-mod-wsgi-py3

  2. python-pip should be python3-pip

  3. “sudo pip install virtualenv” should be “sudo pip3 install virtualenv” (there is more options for ve but some didn’t work for me)

  4. "sudo pip install Flask " > "sudo pip3 install Flask "

Now serious stuff …

apache config between <virtualhost> must have:

WSGIDaemonProcess <flaskapp> user=flask group=www-data threads=5 python-path=/var/www/<flaskapp>:/var/www/<flaskapp>/<flaskapp>/venv/lib/python3.4/site-packages

example:

<VirtualHost *:80> ServerName mywebsite.com ServerAdmin admin@mywebsite.com WSGIDaemonProcess <flaskapp> user=flask group=www-data threads=5 python-path=/var/www/<flaskapp>:/var/www/<flaskapp>/<flaskapp>/venv/lib/python3.4/site-packages WSGIScriptAlias / /var/www/FlaskApp/flaskapp.wsgi <Directory /var/www/FlaskApp/FlaskApp/> Order allow,deny Allow from all </Directory> Alias /static /var/www/FlaskApp/FlaskApp/static <Directory /var/www/FlaskApp/FlaskApp/static/> Order allow,deny Allow from all </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>

But this will only work if you have additional 2 lines in flaskapp.wsgi:

activate_this = ‘/var/www/<flaskapp>/<flaskapp>/venv/bin/activate_this.py’ exec(compile(open(activate_this,“rb”).read(),activate_this, ‘exec’), dict(file=activate_this))

There is alternative, you can put next line in apache config outside of <virtualhost>:

#WSGIPythonPath /var/www/<flaskapp>/<flaskapp>/venv/lib/python3.4/site-packages

Above code was my day … farewell :)

I’m not able to use the packages installed in my virtualenv while running my web application. The error says “ImportError: No module named …” However, if I directly run the python file in /var/www/, it runs perfectly.

but how to create many flask application running at the same time ?

for those with " ImportError: No module named flask", as said here http://flask.pocoo.org/docs/deploying/mod_wsgi/, I added the following lines to my wsgi file : activate_this = ‘/path/to/env/bin/activate_this.py’ execfile(activate_this, dict(file=activate_this))

for those with " ImportError: No module named flask", as said here http://flask.pocoo.org/docs/deploying/mod_wsgi/, I added the following lines to my wsgi file : activate_this = ‘/path/to/env/bin/activate_this.py’ execfile(activate_this, dict(file=activate_this))

for those with " ImportError: No module named flask", as said here http://flask.pocoo.org/docs/deploying/mod_wsgi/, I added the following lines to my wsgi file : activate_this = ‘/path/to/env/bin/activate_this.py’ execfile(activate_this, dict(file=activate_this))