catch all domain requests for python web app (Flask) with apache - python

The current situation is that I have a flask app which runs like a charm if I send my requests to the IP address of the server or docker container.
The app runs in a docker container with ubuntu 18.04 and apache2.4.
This container is implemented in my local development environment where all other apps running in docker containers as well. All containers sharing the same network. So they are able to communicate.
The main problem is that the especially the container which includes the python app only responds if I call it by its IP address. If I call it by its domain name (docker-compose generated) the apache responds with a error 400 and bad request.
That means the container receives the request and led it to the apache but the apache cannot route it to the default virtualhost.
I've tried some things but nothing worked.
ServerName localhost and ServerAlias *
ServerName null and ServerAlias *
Without ServerName and ServerAlias
My current .conf is:
<VirtualHost *:80>
#ServerName null
#ServerAlias *
Options Indexes FollowSymLinks
WSGIDaemonProcess basicflaskapp user=bflaskappuser group=www-data threads=5
WSGIScriptAlias / /var/www/BasicFlaskApp/BasicFlaskApp.wsgi
<Directory /var/www/BasicFlaskApp>
WSGIProcessGroup basicflaskapp
WSGIApplicationGroup %{GLOBAL}
WSGIScriptReloading on
Options FollowSymLinks MultiViews
AllowOverride All
# For Apache 2.4
Require all granted
</Directory>
ErrorLog /var/www/BasicFlaskApp/error.log
</VirtualHost>
This is the one and only .conf. There is no other .conf which could be used.
That means for me that this .conf will be default.
I won't define a fixed domain name because it changed sometimes in my development and production development.
Does anybody has an idea how to fix this?

Related

Django : stop access to my web app from being accessed on port 8000 and access only using the IP

I have deployed my Django web app on a digital ocean droplet. The python server is running on port 8000.
python manage.py runserver 0.0.0.0:8000
I have configured apache web server to serve the requests.
/etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
ServerAdmin webmaster#localhost
DocumentRoot /etc/myproject
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
#Serving static files
Alias /static/ /etc/myproject/static/
<Directory /etc/myproject/static>
Require all granted
</Directory>
<Directory /etc/myproject/myproject>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess myproject python-path=/etc/myproject python-home=/etc/myprojectenv
WSGIProcessGroup myproject
WSGIScriptAlias / /etc/myproject/myproject/wsgi.py
</VirtualHost>
Now when I am accessing my web app using the IP address X.X.X.X, I am able to see my app, however the app is also accessible on port 8000, X.X.X.X:8000.
I want to prevent my app from being accessed on any other port except being accessed ousing IP. How can I do that?
Okay I was missing a point here that I don't need to run Django server as well when I have configured Apache web server to serve my requests. All request are served by the mod_wsgi Apache module. The mod_wsgi package provides an Apache module that implements a WSGI compliant interface for hosting Python based web applications on top of the Apache web server.

Apache 2.4 - multiple WSGI Virtual Hosts (different ports) hangs after few requests from one to another on Windows 10

I'm trying to host two different apps on different Virtual Hosts with different ports on Windows 10. Problem is that apache completely hangs after few requests from one app to another.
Hosting them on one Virtual Host with different paths seems to solve the problem, and so does disabling requests.
Both apps are Python Flask web servers.
httpd.conf
Listen 80
Listen 3000
ServerName localhost
<VirtualHost *:80>
WSGIScriptAlias / F:\path\to\server.wsgi
<Directory F:\path\to>
Require all granted
</Directory>
</VirtualHost>
<VirtualHost *:3000>
WSGIScriptAlias / F:\another\path\to\server.wsgi
<Directory F:\another\path\to>
Require all granted
</Directory>
</VirtualHost>
AcceptFilter http none
AcceptFilter https none
Seems that i found the solution:
If you using C modules in your apps then add this line inside VirtualHost
WSGIApplicationGroup %{GLOBAL}
Slow page loading on apache when using Flask
https://modwsgi.readthedocs.io/en/develop/user-guides/application-issues.html#python-simplified-gil-state-api

Problems with deploying Flask application on Apache 2.4

I'm trying to deplay my Flask application on a RHEL7 Apache 2.4 server.
File structure is the following inside /var/www/html
/app
app.wsgi
/app
app.py
/templates
/static
In my /etc/httpd/conf/httpd.conf I have the following code to set up my project:
<VirtualHost *>
ServerName 10.65.112.75:443
WSGIDaemonProcess app user=apache group=apache threads=5 home=/var/www/html/app/app
WSGIScriptAlias / /var/html/app/app.wsgi
<Directory /var/www/html/app/app/>
WSGIProcessGroup app
WSGIApplicationGroup %{GLOBAL}
WSGIScriptReloading On
Order deny,allow
Require all granted
</Directory>
Alias /static /var/www/html/app/app/static/
<Directory /var/www/html/app/app/static/>
Order deny,allow
Require all granted
</Directory>
And my app.wsgi contains the following:
#!/usr/bin/python
import sys
sys.path.insert(0, "/var/www/html/app/app/")
from app import app as application
The code for the project itself can be found in my github repository here.
I do not get any errors when trying to browse the server. It just doesnt do anything. Running my script from the terminal works, though.
Thanks for the help.
There are various things which aren't right.
You have:
WSGIScriptAlias / /var/html/app/app.wsgi
whereas it appears it should be:
WSGIScriptAlias / /var/www/html/app/app.wsgi
And:
<Directory /var/www/html/app/app/>
appears it should be:
<Directory /var/www/html/app>
Your VirtualHost definition also looks wrong. You have:
<VirtualHost *>
ServerName 10.65.112.75:443
If you really want this to be for HTTPS connections, you are missing all the SSL directives to add a SSL certificate.
ServerName would also usually be a fully qualified domain name and not an IP:PORT. The port number would usually be in the VirtualHost directive. For example, for HTTP, use:
<VirtualHost *:80>
ServerName my.host.name
where my.host.name is the full public host name for your machine which you use in the URL, not an IP address.

Django app hangs when attempting to connect to database via Apache

I am having difficulty troubleshooting this issue. I have a Django app running on an Ubuntu 14.04 server (with Apache 2.4 and mod_wsgi for Python 3.4). It connects to SQL Server via pymssql.
In development, the app works fine. I query the database, and the database returns the expected results.
In production (under the Apache user), however, the script hangs at the exact point that a database query is made. My browser (Chrome or Firefox) shows a spinning wheel that continues to spin as long as the browser window is open.
I have the following in my apache2.conf file:
ServerName localhost
# WSGIDaemonProcess application
WSGIPythonPath /home/production_code/python3env/lib/python3.4/site-packages:/home/production_code/school
# WSGIProcessGroup application
WSGIScriptAlias / /home/production_code/school/school/wsgi.py
# Python virtualenv home
WSGIPythonHome /home/production_code/python3env
# Include the virtual host configurations:
IncludeOptional sites-enabled/*.conf
And the following in my sites-enabled/000-default.conf file:
<VirtualHost *:80>
ServerAdmin *****#school.edu
ServerName localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Alias /static/ /home/production_code/school/static/
<Directory /home/production_code/school/>
Require all granted
</Directory>
<Directory /home/production_code/school/>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
<Directory /home/production_code/school/static>
Require all granted
</Directory>
</VirtualHost>
Does anyone have any idea what might be causing this or how I might troubleshoot this? The Apache error logs and access logs are not particularly helpful in this situation, since a response to the request is never rendered. Similarly, Django debugging is also not useful here.
Instead of:
# WSGIDaemonProcess application
WSGIPythonPath /home/production_code/python3env/lib/python3.4/site-packages:/home/production_code/school
# WSGIProcessGroup application
use:
WSGIDaemonProcess application python-path=/home/production_code/python3env/lib/python3.4/site-packages:/home/production_code/school
WSGIProcessGroup application
WSGIApplicationGroup %{GLOBAL}
A key part of this is the WSGIApplicationGroup directive, with it being set to %{GLOBAL}.
This is to get around faulty third party extension modules for Python that don't work in sub interpreters and which can fail with a dead lock or crash.
See:
https://code.google.com/p/modwsgi/wiki/ApplicationIssues#Python_Simplified_GIL_State_API
It is also recommend you go back to using daemon mode. It is generally not a good idea to use embedded mode.
http://blog.dscpl.com.au/2012/10/why-are-you-using-embedded-mode-of.html

Multiple Django Apps on one Server

How is it possible to serve out multiple Django apps on multiple domains?
For example I have
djangoapp1.com and djangoapp2.com
I then have two separate apps in two separate locations
/srv/www/djangoapp1
/srv/www/djangoapp2
I am running Apache2 with mod_wsgi and I currently have the following in its httpd.conf
WSGIScriptAlias / /srv/www/app1/app1/wsgi.py
WSGIPythonPath /srv/www/app1
<Directory /srv/www/app1/system>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
I also then obviously have the virtual host and I get the django default install page, but now I want to serve up my second app, can anybody point me in the right way to do this?
Django V: 1.4.1
There are many approaches you can take here, and no simple answer - it depends on your requirements and constraints.
The Simplest Thing That Could Possibly Work is very likely the approach suggested by #Hedde - to define the WSGI configuration per-site inside a virtualhost.
A second and possibly more flexible approach would be to run each Django application inside it's own containing application server e.g. gunicorn (hopefully in a virtualenv to isolate application specific dependencies) on different ports and then use Apache or even Nginx as a proxy for application traffic.
This involves a more complicated server environment to manage, but gives you the advantage of being able to manage your applications individually.
You can reconfigure your available workers, upgrade application versions, make changes to settings.py etc for one application at a time rather than having to restart a single monolithic process.
In addition, although it is, of course possible, monitoring virtualhosts within the same Apache process is more complex than monitoring individual application server instances separately.
YMMV
You can use Apache's VirtualHosts
There's plenty examples for Django, e.g. here
One of the ways to run multiple django apps on a single server is to run one app on one port each.
How to run two apps on two different ports?
As recommended by Django, I am using wsgi to interface between apache and Django code. Tricky thing here is that you cannot use wsgi in "embedded" mode. In embedded some os resources are shared and hence leads to race conditions. Solution is to use wsgi in daemon mode. In daemon mode, as the name suggests, wsgi runs as separate processes and hence no shared resources. Your two django apps will be unaware of each other.
This is how my configuration looks. I am running apps on port 8082 and 8083. Notice the lines with WSGIDaemonProcess and WSGIProcessGroup and process-group=pas
Listen 8082
<VirtualHost *:8082>
WSGIDaemonProcess djangoapp1 processes=2 threads=15 display-name=%{GROUP}
WSGIProcessGroup djangoapp1
WSGIScriptAlias /apis /home/apis/djangoapp1/xyz/config.wsgi process-group=djangoapp1
WSGIApplicationGroup %{GLOBAL}
<Directory /home/apis/djangoapp1>
Options +ExecCGI
<Files config.wsgi>
Require all granted
</Files>
</Directory>
</VirtualHost>
Listen 8083
<VirtualHost *:8083>
WSGIDaemonProcess djangoapp2 processes=2 threads=15 display-name=%{GROUP}
WSGIProcessGroup djangoapp2
WSGIScriptAlias /apis /home/apis/discovery_api/nykaa/config.wsgi process-group=djangoapp2
WSGIApplicationGroup %{GLOBAL}
<Directory /home/apis/djangoapp2>
Options +ExecCGI
<Files config.wsgi>
Require all granted
</Files>
</Directory>
</VirtualHost>
How to serve both the apps on port 80 ?
<VirtualHost *:80>
ProxyPreserveHost On
ProxyRequests Off
ServerName example.com
ServerAlias localhost
ProxyPassMatch "^/(apis/v1/hello$.*)" "http://127.0.0.1:8082/$1"
ProxyPassMatch "^/(apis/v1/hi$.*)" "http://127.0.0.1:8082/$1"
ProxyPassMatch "^/(apis/v1/wassup$.*)" "http://127.0.0.1:8083/$1"
ProxyPassMatch "^/(apis/v1/howdy$.*)" "http://127.0.0.1:8083/$1"
</VirtualHost>
Two ways to access wassup and hello API:
http://example.com:8083/apis/v2/wassup?q=howsitgoing
http://example.com/apis/v2/wassup?q=howsitgoing
http://example.com:8082/apis/v2/hello?q=how are you
http://example.com/apis/v2/hello?q=howareyou
Django Code
As recommended on Django website I have replaced
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings")
to
os.environ["DJANGO_SETTINGS_MODULE"] = "{{ project_name }}.settings"
Please see if this is helpful
in apache2.conf or htppd.conf
# Virtual hosts setup
NameVirtualHost *
<VirtualHost *>
ServerName example1.com
............
WSGIScriptAlias / /..../path/to/wsgi1.py
</VirtualHost>
<VirtualHost *>
ServerName example2.com
............
WSGIScriptAlias / /..../path/to/wsgi2.py
</VirtualHost>
in wsgi1.py
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings1' # or projectnaame.settings1
in wsgi2.py
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings2' # or projectname.settings2
In settings1.py & settings2.py you can make necessary databases and other configurations

Categories

Resources