When developing (settings.DEBUG = True), django serves up static content. If we are only running
our API service, there are no static files to serve as the only content is JSON, however, with the
addition of the openapi documentation and
Swagger-UI
we will need to collect and serve up the static files with a web server.
But there are a number of extra steps, so I've added them to the tox.ini. Just do a tox -e docker and the right
thing will happen. Here's what I've added which:
1. bundles openapi.json
2. builds a new wheel.
3. builds the docker image.
4. saves the image as a tar file so it can be docker image loaded elsewhere if needed.
1 2 3 4 5 6 7 8 91011121314151617
+[testenv:docker]+deps =+whitelist_externals =+ docker+ npm+ swagger-ui-watcher+setenv =+ DJANGO_SETTINGS_MODULE = training.settings+commands =+ npm install swagger-ui-watcher+ /bin/cp docs/schemas/openapi.json .+ /bin/rm -rf dist+ python setup.py bdist_wheel+ docker build -t myapp:latest .+ docker image save -o myapp-docker.tar myapp:latest+ /usr/bin/printf '\n\033[0;31m copy the tar to the docker host and do docker image load -i myapp-docker.tar\033[0m\n'+
We'll use docker-compose to combine an nginx web server and our django app (served by gunicorn)
using traefik
as the "edge router" to allow them to both listen on various paths below https://localhost/ (technically this could
be done with Apache httpd or nginx too, but traefik does some docker magic).
See docker-compose.yml for the gory details.
Just do a docker-compose up and away you go (I've used --no-start --force-recreate and start/stop):
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:
1234567
# The WSGI Apache module configuration file is being
# managed by Puppet. Any changes will be overwritten.
<IfModule mod_wsgi.c> WSGISocketPrefix /var/run/wsgi WSGIPythonHome "/var/www/django-jsonapi-training/env" WSGIPythonPath "/var/www/django-jsonapi-training/env/lib/python3.6/site-packages"</IfModule>
"""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"""importsysimportsiteimportos# 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)fromdjango.core.wsgiimportget_wsgi_applicationos.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 and use the REMOTE_USER. I have not
tested this approach. It depends on whether your backend server needs to introspect the Bearer token.