.. crate_anon/docs/source/website_config/apache.rst
.. Copyright (C) 2015, University of Cambridge, Department of Psychiatry.
Created by Rudolf Cardinal (rnc1001@cam.ac.uk).
.
This file is part of CRATE.
.
CRATE is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
.
CRATE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with CRATE. If not, see .
.. _config_apache:
Configuring for Apache
----------------------
Apache is a powerful but fairly complex web server. A suggested method of using
it with CRATE under Windows is as follows:
- Note that Windows configuration files for Apache are typically
``C:\Apache24\conf\httpd.conf`` (the master configuration file) and
``C:\Apache24\conf\extra\httpd-ssl.conf`` (included by the master file).
- Ensure you set up HTTPS correctly.
- Disable anything relating to CRATE on plain HTTP.
- Pick a URL stem such as `/crate` at which to serve CRATE.
- Route CRATE through an internal TCP port – let’s say 8999 – such that CRATE’s
CherryPy server talks to port 8999 (via plain HTTP), the main Apache server
talks to the world on the normal HTTPS port 443, and Apache talks to port
8999 behind the scenes and encrypts the external traffic.
- This is slightly tricky. CherryPy needs to think it’s mounted at /, because
Apache is going to strip off the prefix. It also needs to talk on the correct
path. To get CherryPy to do this for CRATE, set the environment variable
``CRATE_CHERRYPY_ARGS=--port 8999 --root_path /`` before you launch the CRATE
Windows service. The overview is like this:
.. code-block:: none
User visits https://mysite.mydomain/crate/XYZ
Apache: public (1) Receive request for https://mysite.mydomain/crate/XYZ
Apache: internal - decrypt from HTTPS (SSL)
- take path as ‘/crate/XYZ’
- notice that ‘/crate’ is being proxied
- ProxyPass: send path ‘/XYZ’ to internal address of http://127.0.0.1:8999
... request goes to internal (e.g. CherryPy) web server and results come back...
- ProxyPassReverse: rewrite URLs in headers going back to the user,
e.g. ‘/login’ -> ‘/crate/login’
- encrypt to HTTPS (SSL) when returning to user
CherryPy “I am based at /, so interpret path /XYZ as being one of mine.”
- The ‘/’ comes from the --root_path option to CherryPy.
Django “Do something with path /XYZ.”
“If I need to send an absolute URL to the user, I need to prepend
‘https://mysite.mydomain/crate’ to it.”
- This information comes from the DJANGO_SITE_ROOT_ABSOLUTE_URL
and FORCE_SCRIPT_NAME settings for CRATE.
And also, for static serving:
Apache: public (2) Receive request for https://mysite.mydomain/crate_static/PQR
Apache: internal - decrypt from HTTPS (SSL)
- take path as ‘/crate_static/PQR’
- notice that ‘/crate_static’ is being aliased to a directory full of static files
- serve ‘PQR’ from the configured static directory
- encrypt to HTTPS (SSL)
So...
- Ensure Apache has `mod_proxy` loaded. Under Windows, achieve this by
uncommenting these lines from `httpd.conf`:
.. code-block:: apacheconf
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
- Add to your Apache SSL config section (NB: ONLY in the SSL/HTTPS section!)
like this:
.. code-block:: apacheconf
# Definitions to make things clearer
Define CRATE_VISIBLE_PATH /crate
Define CRATE_INTERNAL_URL http://127.0.0.1:8999
Define CRATE_STATIC_PATH /crate_static
Define CRATE_STATIC_ROOT “C:/srv/src/crate/crate_anon/crateweb/static_collected”
# ... for UNIX sockets, you might use this instead of CRATE_INTERNAL_URL:
Define CRATE_UNIX_SOCKET unix:/tmp/.crate_gunicorn.sock
Define CRATE_DUMMY_HOST_URL http://cratedummy/
# Don’t ProxyPass the static files; serve them directly via Apache
ProxyPassMatch ^${CRATE_STATIC_PATH} !
# Set a timeout in seconds (default is the value of Timeout, whose default is 60)
# If your users can run slow queries, increase this:
ProxyTimeout 600
# Proxy through to CRATE
# (a) route the URLs
# ... “retry=0” prevents Apache disabling the connection for a while on failure
ProxyPass ${CRATE_VISIBLE_PATH} ${CRATE_INTERNAL_URL} retry=0
ProxyPassReverse ${CRATE_VISIBLE_PATH} ${CRATE_INTERNAL_URL}
# ... or to use UNIX sockets:
# ProxyPass ${CRATE_VISIBLE_PATH} ${CRATE_UNIX_SOCKET}|${CRATE_DUMMY_HOST_URL} retry=0
# ProxyPassReverse ${CRATE_VISIBLE_PATH} ${CRATE_UNIX_SOCKET}|${CRATE_DUMMY_HOST_URL}
# ... see the special methods for Unix Domain Sockets at
# https://httpd.apache.org/docs/trunk/mod/mod_proxy.html#proxypass
# (b) provide permission
Require all granted
# Serve static files directly from Apache
# (a) route the URL
Alias ${CRATE_STATIC_PATH} “${CRATE_STATIC_ROOT}”
# (b) provide permission
Require all granted
Require all granted
- Tell CRATE where it’s been mounted (so it can offer URLs to itself
correctly). In the Django :ref:`local settings ` (q.v.):
.. code-block:: python
DJANGO_SITE_ROOT_ABSOLUTE_URL = "https://myresearchdb.mysite.mydomain" # no “/crate” suffix here
FORCE_SCRIPT_NAME = "/crate"
- Restart Apache.
- For testing, run :ref:`crate_launch_cherrypy_server
` from the command line. You should see your
access requests here.
- Test static serving with e.g.
https://myresearchdb.mysite.mydomain/crate_static/yellow.png.