Flask App Deployment in Windows (Apache-Server, mod_wsgi)

Thilina Madumal
4 min readJan 23, 2019

Flask is a WSGI (Web Server Gateway Interface) compatible micro web framework written in Python. The easy learning curve and wide adoption have made Flask, one of the first choices for REST-API development in python. Due to the wide adoption, we can find a lot of tutorials and blog posts on ‘How to Deploy Flask Apps in Linux Servers’ in contrast to ‘Flask App Deployment in Windows’. However, there can be situations where one want to deploy one’s Flask applications on Windows-Servers too. In such a scenario someone might find this blog post handy and helpful.

Prerequisites

Before starting the guide you need to make sure that your Windows machine has following installed.

  1. Visual C++ Redistributable for Visual Studio
  2. Visual C++ Build Tools (https://visualstudio.microsoft.com/visual-cpp-build-tools/)
  3. python3
  4. python3-pip
  5. virtualenv
  6. puthon-setuptolls

Installing Apache HTTP Server

Since we are focusing on production deployment the recommended mechanism is to deploy the application behind a battle-tested, production-ready web-server. If I am trying to deploy a Flask application in a Linux machine I would prefer Nginx Web-Server but for Windows machines, I would go with Apache HTTP Server. Well, let’s install Apache HTTP Server on our windows machine.

Here the number 24 is because we are using version 2.4, so intuitively we can understand what this location will be for a different version.

  • Typically the structure of the extracted folder is as follows,
Apache24        dir    
Readme.txt file
--Win64VC15-- file

Note: Installation instructions can also be found in the Readme.txt which resides in the extracted folder.

Running Apache HTTP Server as a Windows Service

  • Open command prompt terminal as administrator.
  • Change directory into <Apache24-Home>\bin.
cd C:\Apache24\bin
  • Install Apache Server as a windows server.
httpd.exe -k install
  • Open the windows service manager.
services.msc
  • Look for Apache2.4 (or your installed version). There we can start, restart, and stop the service as we wish.
  • Now go to http://localhost and it should say, ‘It Works!’

Installing mod_wsgi

Before installing mod_wsgi, we need to get the code for our Flask application into the deployment machine and then create a python3 virtualenv (say flask-app-env) for the application. After that, we need to install required flask and other dependencies into flask-app-env.

  • Open a command prompt and activate flask-app-env and keep the environment activated throughout the following instructions.
  • Install mod_wsgi package.
pip install mod_wsgi

Configuring mod_wsgi in Apache Server.

  • Run the following command to get the configuration of the installed mod_wsgi for Apache Server.
mod-wsgi-express module-config

The above command would output something like the following;

LoadFile "c:/users/curwsl/appdata/local/programs/python/python37/python37.dl"LoadModule wsgi_module  "d:/flo2d-rest-service/flo2d/flo2d-venv/lib/site-packages/mod_wsgi/server/mod_wsgi.cp37-win_amd64.pyd"WSGIPythonHome "d:/flo2d-rest-service/flo2d/flo2d-venv"
  • Copy the output of the above command and paste it in <Apache24-Home>\conf\httpd.conf. We can paste at the very end of the file.
  • Deactivate flask-app-env and close the command prompt.

Note: For further details please refer to https://github.com/GrahamDumpleton/mod_wsgi#connecting-into-apache-installation

Configuring Apache Server to Deploy the Falsk App

Making the Apache Server Listen to a Desired Port

The first thing we need to do is to make the Apache Server listen to the port that we plan to expose the Flask App through. By default, Apache Server listens to the port 80 (the default HTTP port).

However, if we want to make Apacher Server listen to a particular port do the following;

  • Add “Listen <port>” to <Apache24 root>/conf/httpd.conf

Configure a Virtual Host for the Flask App

In Apache 2.4 Server virtual host configurations are placed in the <Apache24-Home>\conf\extra\httpd-vhosts.conf file. Thus we need to edit that particular file.

  • Open <Apache24-Home>\conf\extra\httpd-vhosts.conf for editing.
  • Add the following virtual host configuration segment with corresponding changes into <Apache24-Home>\conf\extra\httpd-vhosts.conf.
<VirtualHost *:5000>
ServerAdmin admin-name-here
ServerName server-name-here(e.g localhost:5000)
WSGIScriptAlias / "D:/myapp/app/index/web.wsgi"
DocumentRoot "D:/myapp/app"
<Directory "D:/myapp/app/index">
Order deny,allow
Allow from all
Require all granted
</Directory>
ErrorLog "D:/myapp/app/logs/error.log"
CustomLog "D:/myapp/app/logs/access.log" common
</VirtualHost>

In the above configuration, there are three important things.

  1. ServerName
  2. WSGIScriptAlias
  3. Directory privileges (i.e what we have within <Directory> </Directory> tag)

ServerName is the domain name for our Flask App. It can be a purchased one or just localhost.

WSGIScriptAlias specifies what script should be executed when the Apache Server get a request for <domain-name> root (e.g http://localhost:5000/).

<Directory/> is there for security purposes. Directory tag should allow the access to the WSGI-Script(i.e. web.wsgi)’s residing directory but not beyond that.

Note: Here D:/myapp/app is the root directory of the flask application code. From now on I would call it <flask-app-home>.

Include the virtual-hosts file (i.e. httpd-vhosts.conf) into httpd.conf

  • Search for “httpd-vhosts.conf” in <Apache24 root>/conf/httpd.conf
  • Uncomment the ‘Include’ line
  • Or simply add the following lines;
# Virtual hosts
Include conf/extra/httpd-vhosts.conf

Create web.wsgi in <flask-app-root>/index/

You need to create a web.wsgi file with the following content in the <flask-app-home>/index/ directory.

import sys

sys.path.insert(0, 'D:/myapp/app')

from your_app_script import app as application

Obviously your your_app_script.py should look something like the following;

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
return "Hello World"

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

That’s all folks. Happy Falsking on Windows! :D

Resources:

  1. https://www.storehubs.com/Blog/deploy-python-flask-application-apache-windows-server/
  2. https://github.com/GrahamDumpleton/mod_wsgi
  3. https://modwsgi.readthedocs.io/en/develop/user-guides/quick-configuration-guide.html
  4. https://stackoverflow.com/questions/10081062/django-virtual-host-setup-apache-mod-wsgi

--

--