I want to run SSL for web server https://www.domainname.com on port 443 and python REST api server https://mgmt.domainname.com with Flask. I have configured Apache SSL and it is running on 443. I ran a simple python program from flask
import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'Howdy world!'
if __name__ == "__main__":
app.run(ssl_context='adhoc')
Output:
* Serving Flask app 'backend2'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on https://127.0.0.1:5000
Enabled the following:
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests
sudo systemctl restart apache2
Questions:
Can both web server and python program listen on 443? The only differentiation would be seperate URLs for web server and REST api. I read that I need to implement Apache mod_ssl. So modify existing /etc/apache2/sites-available/default-ssl.conf file for Reverse proxy
<IfModule mod_ssl.c> <VirtualHost _default_:443> DocumentRoot /srv/www/wordpress ServerName www.domain-name.com SSLEngine on SSLCertificateFile /root/cert/domainname.com.crt SSLCertificateKeyFile /root/cert/domainname.com.key ProxyPreserveHost On ProxyPass / http://IPAddr:443/ ProxyPassReverse / http://IPAddr:443/ </VirtualHost> </IfModule>
Don't know if this modification for Reverse Proxy is good enough or what else needs to be done?
Should I modify WSGI server with this code:
import wsgiserver def my_app(environ, start_response): status = '200 OK' response_headers = [('Content-type','text/plain')] start_response(status, response_headers) return ['WSGIserver is running!'] server = wsgiserver.WSGIServer(my_app, certfile='cert.pem', keyfile='privkey.pem') server.start()
Also going forward the REST api should be able to call different parts of Python program based on URL query path/parameters, which means some kind of routing needs to be set up using Apache mod_proxy and mod_ssl or some aspect of WSGI server? I want to know where and how to start: Configure Apache and or WSGI. I understand there are other issues that need to be resolved in either path. Please advise so I can start and move incrementally
EDITS: Followed the example URL given by @vidarlo Edited /etc/apache2/sites-available/default-ssl.conf and added VirtualHost code as suggested to forward the https://api.domainname.com to localhost:5000. Started a WSGI server on port 5000 like this: wsgi.py file contents:
import wsgiserver
def gs_app(environ, start_response):
status = '200 OK'
response_headers = [('Content-type','text/plain')]
start_response(status, response_headers)
return ['WSGIserver is running!']
server = wsgiserver.WSGIServer(gs_app, host='127.0.0.1', port=5000)
server.start()
Ran python3 wsgi.py & Verified the process is running on port 5000 Now when I access https:// https://api.domainname.com I get error popup in my console window like this:
ValueError('WSGI Applications must yield bytes')
Traceback (most recent call last):
File "/usr/local/lib/python3.8/dist-packages/wsgiserver.py", line 1394, in communicate
req.respond()
File "/usr/local/lib/python3.8/dist-packages/wsgiserver.py", line 848, in respond
self.server.gateway(self).respond()
File "/usr/local/lib/python3.8/dist-packages/wsgiserver.py", line 2347, in respond
raise ValueError("WSGI Applications must yield bytes")
ValueError: WSGI Applications must yield bytes