title: How to deploy Python Flask app to Apache (Httpd) running on Amazon Linux EC2 instance
body: <p>I'm really struggling here. I have a simple Python Flask REST API that I've developed. The API runs fine in my local development environment (Mac OS X) and when directly executed via the console on my EC2 instance.</p>
  
  <p>I want to move this service into production and as such would like to host it behind Apache running on the EC2 instance. This is where I keep hitting a wall and I can't seem to get past the configurations and errors. I've research several articles online and questions here, none seem to be able to help me.</p>
  
  <p>I'm hoping someone here can please provide me with step-by-step directions on how to deploy my service to production behind Apache running on an Amazon Linux EC2 instance.</p>
  
  <p>Here are the steps I've taken:</p>
  
  <ol>
  <li>Launched a basic Amazon Linux EC2 instance.</li>
  <li>Apply updates to the instance, <strong>sudo yum update</strong></li>
  <li>Install Apache and WSIG, <strong>sudo yum install httpd24 mod24_wsgi</strong></li>
  <li>Start Apache, <strong>sudo service httpd start</strong></li>
  <li>Configure Apache to start automatically, <strong>sudo chkconfig httpd on</strong></li>
  <li>Test by hitting the DNS of my EC2 box. I successfully get the Amazon Linux AMI test page.</li>
  <li>Adjust permissions on /var/www as follows
  
  <ul>
  <li><strong>sudo groupadd www</strong></li>
  <li><strong>sudo usermod -a -G www ec2-user</strong></li>
  <li>Logon/off and confirm membership, <strong>groups</strong> </li>
  <li><strong>sudo chown -R root:www /var/www</strong></li>
  <li><strong>sudo chmod 2775 /var/www</strong></li>
  <li><strong>find /var/www -type d -exec sudo chmod 2775 {} \;</strong></li>
  <li><strong>find /var/www -type f -exec sudo chmod 0664 {} \;</strong></li>
  </ul></li>
  <li>Test by hitting DNS of my EC2 box - still good so far.</li>
  </ol>
  
  <p>Now that I know my instance is running, I would like to create two folders where I can test and run my Python Flask code. I do so as follows:</p>
  
  <ol>
  <li>I create two folders, one for development and one for production.
  
  <ul>
  <li>/var/www/rest-dev/</li>
  <li>/var/www/rest-prod/</li>
  </ul></li>
  <li>I setup a virtual environment within each of the folders and install Flask.
  
  <ul>
  <li><strong>virtualenv env</strong></li>
  <li><strong>env/bin/pip install Flask</strong></li>
  <li>I then place a copy of my service in each folder. </li>
  <li>Then I set permissions on app.py, <strong>chmod a+x app.py</strong></li>
  <li>I can successfully execute ./app.py and test the service by hitting the DNS name + port 5000. It works.</li>
  </ul></li>
  </ol>
  
  <p>Now this is where I get tripped up. My goal is to be able to hit <strong>api.example.com</strong> and have my service's root load up. In the example code below, "Hello, World!" should simply display.</p>
  
  <p>I've followed the tutorials found here with no luck.</p>
  
  <p><a href="http://peatiscoding.me/geek-stuff/mod_wsgi-apache-virtualenv/" rel="noreferrer">http://peatiscoding.me/geek-stuff/mod_wsgi-apache-virtualenv/</a></p>
  
  <p><a href="http://webpy.org/cookbook/mod_wsgi-apache" rel="noreferrer">http://webpy.org/cookbook/mod_wsgi-apache</a></p>
  
  <p><a href="http://www.jakowicz.com/flask-apache-wsgi/" rel="noreferrer">http://www.jakowicz.com/flask-apache-wsgi/</a></p>
  
  <p>After executing any of the steps in any of the articles above, I get an HTTP error page and nothing loads anymore, including the default Amazon Linux AMI test page. Below are the pieces of code and configurations that I've changed. I haven't changed my httpd.conf ... should I? There are probably several other things I'm missing.</p>
  
  <p><strong>Can someone please help me by providing me the necessary steps in detail to correct my mistakes?</strong></p>
  
  <p>Many thanks in advance!</p>
  
  <p>When I view the error_log for HTTPD, it lists errors like this:</p>
  
  <pre><code>mod_wsgi (pid=8270): Target WSGI script '/var/www/rest-dev/deploy.wsgi' cannot be loaded as Python module.
  mod_wsgi (pid=8270): Exception occurred processing WSGI script '/var/www/rest-dev/deploy.wsgi'.
  Traceback (most recent call last):
    File "/var/www/rest-dev/deploy.wsgi", line 16, in &lt;module&gt;
      from app import app as application
    File "/var/www/rest-dev/app.py", line 2, in &lt;module&gt;
      from flask import Flask
  ImportError: No module named flask
  </code></pre>
  
  <p>Here is my <strong>deploy.wsgi</strong> file, located in the rest-dev folder:</p>
  
  <pre><code>import os
  import sys
  import site
  
  # Add virtualenv site packages
  site.addsitedir(os.path.join(os.path.dirname(__file__),     'env/local/lib64/python2.7/site-packages'))
  
  # Path of execution
  sys.path.append('/var/www/rest-dev')
  
  # Fired up virtualenv before include application
  activate_env = os.path.expanduser(os.path.join(os.path.dirname(__file__), 'env/bin/activate_this.py'))
  execfile(activate_env, dict(__file__=activate_env))
  
  # import my_flask_app as application
  from app import app as application
  </code></pre>
  
  <p>Here is my vhost.conf file located in /etc/httpd/conf.d/</p>
  
  <pre><code>&lt;VirtualHost *:80&gt;
          ServerName api.example.com
  
          WSGIDaemonProcess webtool user=ec2-user group=www threads=5 home=/var/www/rest-dev/
          WSGIScriptAlias / /var/www/rest-dev/deploy.wsgi
  
          &lt;directory /var/www/rest-dev&gt;
                  WSGIProcessGroup webtool
                  WSGIApplicationGroup %{GLOBAL}
                  WSGIScriptReloading On
                  Order deny,allow
                  Allow from all
          &lt;/directory&gt;
  &lt;/VirtualHost&gt;
  </code></pre>
  
  <p>Here is my <strong>app.py</strong> example service code for reference:</p>
  
  <pre><code>#!env/bin/python
  from flask import Flask
  
  app = Flask(__name__)
  
  @app.route('/')
  def index():
      return "Hello, World!"
  
  if __name__ == '__main__':
      app.run(host='0.0.0.0', port=5000, debug=True)
  </code></pre>