Deploying Multiple Flask Apps On Server - apache

I am attempting to deploy a 2nd flask application to an apache webserver. I have added a 2nd listener to the httpd.conf file for 127.0.0.1:8868 because I am accessing the api through a gateway located on my machine. The first app I deployed was set up in a very similar fashion and works perfectly. The flask app works fine when launched from the .py file. I have attached excerpts from the httdpd.conf file, httpd-vhosts.conf file, and the web.wsgi file. It doesn't record any errors in the apache errors log and or the access logs. It will record it in the access and error logs if I have an error in the .wsgi file. Having both listeners enabled also seems to interfere with the first application listening on port 5000.
httpd listeners:
Listen 127.0.0.1:5000
Listen 127.0.0.1:8868
httpd-vhosts.conf:
<VirtualHost *:5000>
WSGIScriptAlias / C:/Users/me/web_apps/task_manager/app/index/web.wsgi
<Directory C:/Users/me/web_apps/task_manager>
Require all granted
</Directory>
</VirtualHost>
<VirtualHost *:8868>
WSGIScriptAlias / C:/Users/me/web_apps/template_autoupdate/app/index/web.wsgi
<Directory C:/Users/me/web_apps/template_autoupdate>
Require all granted
</Directory>
</VirtualHost>
web.wsgi
import sys
sys.path.insert(0, "C:/Users/me/web_apps/template_autoupdate/app")
from autoupdater import app as application

Related

Firebase from Flask deployment server

in development mode with Flask, I am successfully able to read and write data to Firestore using the firebase admin module. However, once I deploy the app on Apache 2 using mod_wsgi, everything works fine (firebase app initialization doesn't throw any error) until I start getting a document, where the code gets stuck and the page loads forever.
Flask function where the problem occurs in __init__.py:
#app.route('/users/<user>')
def login(user=None):
if not user:
abort(404)
userRef = db.collection('users').document(user)
print("1") # This runs.
userDoc = userRef.get() # The code gets stuck here. No error message is ever returned or stored in the error log.
print("2") # This never runs.
flaskapp.wsgi
#!/usr/local/bin/python3.8
import sys
import os
import logging
logging.basicConfig(stream=sys.stderr)
os.chdir("/var/www/html/example.com/FlaskApp/")
sys.path.insert(0,"/var/www/html/example.com/FlaskApp/")
from __init__ import app as application
example.com.conf
LoadModule wsgi_module "/home/username/.local/lib/python3.8/site-packages/mod_wsgi/server/mod_wsgi-py38.cpython-38-x86_64-linux-gnu.so"
WSGIPythonHome "/usr/local"
<VirtualHost *:80>
# Admin email, Server Name (domain name), and any aliases
ServerAdmin username#example.com
ServerName example.com
ServerAlias www.example.com
# Index file and Document Root (where the public files are located)
DirectoryIndex index.html index.php
DocumentRoot /var/www/html/example.com/public_html
WSGIScriptAlias / /var/www/html/example.com/FlaskApp/flaskapp.wsgi
<Directory /var/www/html/example.com/FlaskApp/>
Require all granted
</Directory>
Alias /static /var/www/html/example.com/FlaskApp/static
<Directory /var/www/html/example.com/FlaskApp/static/>
Require all granted
</Directory>
# Log file locations
LogLevel warn
ErrorLog /var/www/html/example.com/log/error.log
CustomLog /var/www/html/example.com/log/access.log combined
</VirtualHost>
Do you know how to make Firebase get() works in a deployed Flask app? Thank you for your help!
Seems like WSGI needs to be forced to use the main Python interpreter. Therefore, you'll need to add application-group=%{GLOBAL} to the end of your ``WSGIScriptAlias line on example.com.conf, so that the line now reads:
WSGIScriptAlias / /var/www/html/example.com/FlaskApp/flaskapp.wsgi application-group=%{GLOBAL}
After that, restart Apache with the terminal command systemctl restart apache and your problem should be solved.

Puppet apache configuration file on ubuntu ec2

I am using puppet to provision an AWS AMI using packer and then launch the AMI.
Puppet does all the configuration and package installations upon baking the AMI which includes installing and configuring apache and wsgi.
By the time I launch the AMI my application (a Flask application) would have already been downloaded and configured by Puppet as well as my apache configuration file at /etc/apache2/sites-available/xxxx.conf . I make use of the Puppet template to configure the apache configuration file and as such it is a Ruby template (xxxx.conf.erb) ,the apache configuration template file looks like this :
<VirtualHost *:<%= #port -%>>
ServerName <%= #servername %>
ServerAdmin admin#example.com WSGIScriptAlias / /var/www/Porfolio/xxxxx.wsgi
<Directory /var/www/Porfolio/> Order allow,deny Allow from all </Directory> Alias /static /var/www/Porfolio/static <Directory /var/www/Porfolio/static/> Order allow,deny Allow from all </Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
I have set the variable servername = $::hostname (using facter) and port = 80
When i launch the AMI and I access the public IP address of the server of the ec2 instance, it takes me to the default ubuntu webpage instead of my web Flask application.
I will have to ssh into my server and change the apache configuration file at
/etc/apache2/sites-available/xxxx.conf to become :
<VirtualHost *:<%= #port -%>>
ServerName 52.91.143.90
ServerAdmin admin#example.com
WSGIScriptAlias / /var/www/Porfolio/culturely.wsgi
<Directory /var/www/Porfolio/>
Order allow,deny
Allow from all
</Directory>
Alias /static /var/www/Porfolio/static
<Directory /var/www/Porfolio/static/>
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
This means i have to manually type in the public IP address of the ec2instance in order to get my Flask web page to display when the public Ip address is accessed on a browser. This ofcourse defeats the level of automation I am trying to achieve.
The public IP address only becomes available after I launch the AMI, is there a way i can re-configure my apache configuration file to make it automatically goto my web application instead of the default ubuntu web page ? without having me to ssh into the server and manually change it after it is launched
There is a fact ec2_public_ipv4, use this to set the address
I have found a solution to my problem. I was creating a new apache configuration file with puppet at packer time, a point at which the public IP address that will be assigned to ec2 instance is unavailable.
So instead of creating a new apache configuration file, I modified the default one at /etc/apache2/sites-available/000-default.conf . I left the variable servername = $::fqdn . Now whenever I launch the AMI and visit the assigned public IP address of the ec2-instance, it navigates to my Flask application and not the default ubuntu web page anymore.

using flask virtualenv on remote host (not locally)

I have a CentOS 7 WSGI enables Apache Httpd server (on a VirtualBox machine) and it serves my developing Flask site at http://www.myflask.com on port 80.
Since I can't debug there (even if I tried everything I could), like I can on a local version set in a virutalenv at http://127.0.0.1:5000, I was trying to do this:
setting up a virtualenv (with flask installed) on the VB server, called myflaskv (/var/www/myflaskv)
putting myflask dir into myflaskv (/var/www/myflaskv/myflask)
I did end with the following httpd.conf virtual host section:
<VirtualHost *:80>
DocumentRoot "/var/www/myflaskv/myflask"
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory "/var/www/myflaskv/myflask">
Options Indexes FollowSymLinks MultiViews
Order deny,allow
Allow from all
</Directory>
WSGIScriptAlias / /var/www/myflaskv/myflask/index.wsgi
ServerName www.myflask.com:80
</VirtualHost>
I can load the page http://www.myflask.com (even with virtualenv activated) but I can't load the page http://www.myflask.com:5000 as I would suppose to debug.
So I tried to add a virtualhost on port 5000:
<VirtualHost *:5000>
DocumentRoot "/var/www/myflaskv/myflask"
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory "/var/www/myflaskv/myflask">
Options Indexes FollowSymLinks MultiViews
Order deny,allow
Allow from all
</Directory>
WSGIScriptAlias / /var/www/myflaskv/myflask/index.wsgi
ServerName www.myflaskv.com:5000
</VirtualHost>
supposing that this way I could load http://www.myfaskv.com, and instead I can't (ERR_CONNECTION_REFUSED).
By the way I temporarly disactivated ip-tables and se-linux.
So is there a way to load from browser the 127.0.0.1:5000 ip address of a remote host?
Or there is a better way to debug flask in an wsgi apache dev environment?
If you want to access the url from outside the box, you will have to run the server at 0.0.0.0:5000.
The url http://127.0.0.1:5000 cannot be accessed from outside the box you are running it in.
When you use wsgi to access your app, the error messages and stack traces are written to the web server error log, by default at /var/log/apache2/error.log. You don't need to use the virtualenv web server. Just write any debug output you need to a local log file (if you have debugging input you want to print) and look for the stack traces in the apache error log.

Can't get apache2.4 to pass requests to web2py using mod_wsgi

I'm having a hell of a time setting up a web2py server in a way that allows me to access the admin and appadmin interfaces from anywhere other than localhost, which is a requirement for me because the web2py server is hosted in a cloud location without a browser or X server. I understand that to access web2py's admin or appadmin interfaces from outside localhost that I must use SSL/HTTPS.
The web2py documentation seems to declare two different ways to do this. First, from the general web2py startup tutorial:
The administrative interface, admin, is only accessible from localhost
unless you run web2py behind Apache with mod_proxy. If admin detects a
proxy, the session cookie is set to secure and admin login does not
work unless the communication between the client and the proxy goes
over HTTPS
This lead me to search the web for how to setup web2py behind and apache which lead me to the web2py deployment recipes page, where it describes setting up web2py behind apache using mod_wsgi instead of mod_proxy. These are the instructions I'm currently following exactly, with the exception of updating the /etc/apache2/sites-available/web2py file to apache2.4 syntax and modifying the ServerName directive's value to "foo.bar.com" (omitted: the domain name of cloud box containing the server, this is replaced with foo.bar.com throughout this question).
However, when I get to the
When you restart Apache, it should pass all the requests to web2py without going through the Rocket wsgiserver.
part of the that web2py+apache+mod_wsgi tutorial, apache does not appear to be passing anything to web2py for me. I went ahead and moved the wsgihandler.py file as the next step in the tutorial describes, and here's my current state:
If I browse to foo.bar.com:80 from another machine, I get the Apache2 Ubuntu Default Page (the "It works!" page).
If I browse to foo.bar.com:8000 (web2py port), I the web2py server's default interface, but with no access to admin or appadmin because of the unsecure channel.
If I try to browse to foo.bar.com:443, I get the generic "Index of /" apache server
page. On this page "/" contains one directory link "html", which
is a link to the Apache2 Ubuntu Default Page (the "It works!" page).
Other information:
I have an untouched instance of web2py installed at /home/www-data/web2py except that I've moved /home/www-data/web2py/handlers/wsgihandler.py to /home/www-data/web2py/wsgihandler.py
The contents of my /etc/apache2/site-available/ directory are:
000-default.conf (not touched by me)
default-ssl.conf (not touched by me)
web2py (created by me)
I've manually started up web2py with python ~/web2py/web2py.py --ip 10.7.166.27 (that's the IP for foo.bar.com (real domain name omitted))
apache2 is running as user www-data
The server OS is Ubuntu Server 14.04 x64
This is my /etc/apache2/sites-available/web2py file:
<VirtualHost *:80>
ServerName foo.bar.com
WSGIDaemonProcess web2py user=www-data group=www-data display-name=%{GROUP}
WSGIProcessGroup web2py
WSGIScriptAlias / /home/www-data/web2py/wsgihandler.py
<Directory /home/www-data/web2py>
AllowOverride None
Require all denied
<Files wsgihandler.py>
Require all granted
</Files>
</Directory>
AliasMatch ^/([^/]+)/static/(.*) /users/www-data/web2py/applications/$1/static/$2
<Directory /users/www-data/web2py/applications/*/static/>
Order Allow,Deny
Allow from all
</Directory>
<Location /admin>
Require all denied
</Location>
<LocationMatch ^/([^/]+)/appadmin>
Require all denied
</LocationMatch>
CustomLog /private/var/log/apache2/access.log common
ErrorLog /private/var/log/apache2/error.log
</VirtualHost>
<VirtualHost *:443>
ServerName foo.bar.com
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/server.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
WSGIProcessGroup web2py
WSGIScriptAlias / /users/www-data/web2py/wsgihandler.py
<Directory /users/www-data/web2py>
AllowOverride None
Require all denied
<Files wsgihandler.py>
Require all granted
</Files>
</Directory>
AliasMatch ^/([^/]+)/static/(.*) /users/www-data/web2py/applications/$1/static/$2
<Directory /users/www-data/web2py/applications/*/static/>
Require all granted
</Directory>
CustomLog /private/var/log/apache2/access.log common
ErrorLog /private/var/log/apache2/error.log
</VirtualHost>
Alright! I found my stupid mistake while writing this up. I had never bothered to properly configure apache itself:
/etc/apache2/sites-available/000-default.conf and /etc/apache2/sites-available/default-ssl.conf were why I was seeing what I was seeing when browsing to foo.bar.com:80 and foo.bar.com:443 respectively.
apache2.4 seems to require the .conf on configuration files, I didn't have that so I renamed /etc/apache2/sites-available/web2py to /etc/apache2/sites-available/web2py.conf
I didn't have a symlink to /etc/apache2/sites-available/web2py at /etc/apache2/sites-enabled/web2py, so I made one.
So, as of now:
When I browse to foo.bar.com:80 I get the same Apache2 Ubuntu Default Page, BUT
When I browse to foo.bar.com:80/web2py I get an internal server error which the apache logs tell me is a python import error from wsgihandler.py, which means the apache<->mod_wsgi<->web2py link is up and running
When I browse to foo.bar.com:443/web2py I get Chrome's yellow screen complaining about my self-signed certificate and after clicking through I get a permissions-denied page, presumably because of something I haven't set up yet in web2py/SSL
This means my original question is answered, but I might come back here and comment/edit if I get stumped again getting SSL to work.

mod_wsgi with Flask app: ImportError: No module named flask

In CentOS 6.4, I created python virtual environment in /var/www/html/venv folder. Then after activating the virtual environment, I installed all necessary python libraries for my flask application. I checked, that Flask libraries were in /var/www/html/venv/lib/python2.7/site-packages folder. I've already installed and loaded mod_wsgi. Now in my flask app, which is in /var/www/html/truckman/wsgi folder, I created truckman.wsgi file with the following content:
activate_this = '/var/www/html/venv/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))
import sys
sys.path.insert(0, '/var/www/html/truckman/wsgi/')
from app import app as application
import config
application.config.from_object(config.Dev)
Also, in /etc/httpd/conf/httpd.conf I added:
<VirtualHost *>
WSGIScriptAlias / /var/www/html/truckman/wsgi/truckman.wsgi
<Directory /var/www/html/truckman/wsgi>
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
Now, in /var/www/html/truckman/wsgi folder, I created run.py file with the following content:
from app import app as application
import config
application.config.from_object(config.Dev)
if __name__ == "__main__":
application.run(port=5001)
Now I tested my app with flask's development server; if I execute "python run.py", my app works as expected. I can browse to localhost:5001, and the app's initial page shows up.
Then I tested my app with mod_wsgi: First killed run.py process, and restarted httpd service, and after that browsed to localhost; but it returned: "500 Internal Server Error". In /etc/httpd/logs/error_log file I found the following error message: "ImportError: No module named flask". What's wrong with my settings?
Try adding the path to your python 2.7 folder in your virtual environment.
sys.path.insert(1, '/path/to/virtualenv/lib/python2.7')
The .conf should be something like this:
<VirtualHost *>
ServerName example.com
WSGIScriptAlias / /var/www/firstapp/hello.wsgi
WSGIDaemonProcess hello python-path=/var/www/firstapp:/var/www/firstapp/env/lib/python2.7/site-packages
<Directory /var/www/firstapp>
WSGIProcessGroup hello
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
Preferably in /etc/apache2/sites-available/hello.conf, so this part can be the root of the problem.
You can check a working example code in: Hello world from flask.