Deployment¶
Database connections¶
Use persistent database connections. PostGIS prepares each reprojection once per connection, then keeps it: without them, every request for features in another CRS than the one they are stored in pays for it again, about 130 ms on the test stack, against well under a millisecond once it is prepared. CRS84, the default, is such a CRS for any collection stored in a projected one.
Under a WSGI server such as gunicorn, keep connections for a while with
CONN_MAX_AGE, and have Django
check one before reusing it with
CONN_HEALTH_CHECKS, in case
the database closed it meanwhile, after a restart for instance:
Keep the age finite, and under any idle timeout between Django and the database. Each worker thread keeps a
connection of its own, so the workers and threads of every instance have to fit within the
max_connections of PostgreSQL, or to go through a connection pooler such as pgbouncer.
Under ASGI, Django advises against persistent connections: use its
connection pool instead, which
needs psycopg 3 and psycopg[pool], with CONN_MAX_AGE left at 0. Each connection of the pool prepares a
reprojection once, then keeps it too.
Django's development server opens a new connection for every request, whatever the settings.
Behind a reverse proxy¶
The responses link to other resources with absolute URLs: the landing page to the collections, a page of
items to the next one, a created feature to itself in its Location header. Django builds them from the
request, so behind a reverse proxy that terminates HTTPS, it has to be told which requests came in over
HTTPS, or the links point to http://. If the proxy sets X-Forwarded-Proto, and overwrites any that the
client sent:
If the proxy does not pass the original Host on either, but sets X-Forwarded-Host, set
USE_X_FORWARDED_HOST too.
Read the warnings of the Django documentation on
SECURE_PROXY_SSL_HEADER
before setting it.