## Deploying to Production ### TODO: Document Jenkins CI/CD setup. ### Apache httpd `mod_wsgi` Our preferred environment for running Django apps is with `mod_wsgi` under Apache httpd. At CUIT, this is generally done with Puppet. For simplicity, I'll just show some sample files: `/etc/httpd/conf.d/wsgi.conf`: ```console # The WSGI Apache module configuration file is being # managed by Puppet an changes will be overwritten. WSGISocketPrefix /var/run/wsgi WSGIPythonHome "/var/www/django-jsonapi-training/env" WSGIPythonPath "/var/www/django-jsonapi-training/env/lib/python3.6/site-packages" ``` `/etc/httpd/conf.d/wsgi.load`: ```console LoadModule wsgi_module modules/mod_wsgi_python3.6.so ``` `/etc/httpd/conf.d/10-myserver.cc.columbia.edu`: ```console # ************************************ # Vhost template in module puppetlabs-apache # Managed by Puppet # ************************************ ServerName myserver.cc.columbia.edu ## Vhost docroot DocumentRoot "/var/www/django-jsonapi-training" ## Directories, there should at least be a declaration for /var/www/django-jsonapi-training Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny Allow from all ## Logging ErrorLog "/var/log/httpd/myserver.cc.columbia.edu_error_ssl.log" ServerSignature Off CustomLog "/var/log/httpd/myserver.cc.columbia.edu_access_ssl.log" "virtualhost_snat" ## SSL directives SSLEngine on SSLCertificateFile "/etc/pki/tls/certs/localhost.crt" SSLCertificateKeyFile "/etc/pki/tls/private/localhost.key" SSLCertificateChainFile "/etc/pki/tls/certs/localhost.csr" SSLCACertificatePath "/etc/pki/tls/certs" SSLCACertificateFile "/etc/pki/tls/certs/intermediateCAbundle.crt" WSGIDaemonProcess django-jsonapi-training WSGIProcessGroup django-jsonapi-training WSGIScriptAlias / "/var/www/django-jsonapi-training/wsgi.py" WSGIPassAuthorization On WSGIChunkedRequest On ``` and `/var/www/django-jsonapi-training/wsgi.py`: ```python """ Generated by Puppet. DO NOT EDIT. WSGI config for django-jsonapi-training project. It exposes the WSGI callable as a module-level variable named ``application``. https://modwsgi.readthedocs.io/en/develop/user-guides/virtual-environments.html """ import sys import site import os # Calculate path to site-packages directory. python_home = "/var/www/django-jsonapi-training/env" python_version = ".".join(map(str, sys.version_info[:2])) site_packages = python_home + "/lib/python%s/site-packages" % python_version # Add the site-packages directory. site.addsitedir(site_packages) from django.core.wsgi import get_wsgi_application os.environ["DJANGO_SETTINGS_MODULE"] = "training.settings" os.environ["DJANGO_SECRET_KEY"] = "123456789012345687890" os.environ["DJANGO_DEBUG"] = "false" os.environ["DJANGO_SQLSERVER"] = "true" os.environ["DJANGO_SQLSERVER_DB"] = "mydb" os.environ["DJANGO_SQLSERVER_USER"] = "myuser" os.environ["DJANGO_SQLSERVER_PASS"] = "mypass" os.environ["DJANGO_SQLSERVER_HOST"] = "mydbhost" os.environ["OAUTH2_SERVER"] = "https://oauth-test.cc.columbia.edu" os.environ["RESOURCE_SERVER_ID"] = "demo_resource_server" os.environ["RESOURCE_SERVER_SECRET"] = "wL0pgS5RcNOgdOSSmejzZNA605d3MtkoXMVSDaJxmaTU70XnYQPOabBAYtfkWXay" application = get_wsgi_application() ``` Make careful note to have **`WSGIPassAuthorization On`** or the `Authorization` header will not be passed through to the Django app. Alternatively, look into [`mod_auth_openidc`](https://github.com/zmartzone/mod_auth_openidc) and use the `REMOTE_USER`. I have not tested this approach. It depends on whether your backend server needs to introspect the Bearer token.