Skip to content

Commit 0bc9dca

Browse files
authored
Merge pull request #1311 from makeabilitylab/1252-document-apache-routing
docs: document Apache static-vs-Django routing (robots.txt & sitemap.xml)
2 parents 61014b5 + 2a61120 commit 0bc9dca

1 file changed

Lines changed: 10 additions & 0 deletions

File tree

docs/DEPLOYMENT.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ This document covers the Makeability Lab website's production infrastructure, de
1616
- [Server Configuration](#server-configuration)
1717
- [Configuration File](#configuration-file)
1818
- [Environment Variables](#environment-variables)
19+
- [Static Files vs. Dynamic Requests (Apache routing)](#static-files-vs-dynamic-requests-apache-routing)
1920
- [Debugging \& Logging](#debugging--logging)
2021
- [Log Files](#log-files)
2122
- [Accessing Logs via Web](#accessing-logs-via-web)
@@ -127,6 +128,15 @@ Django reads database credentials and secret keys from `config.ini`. This file:
127128

128129
Production-specific settings are configured in `settings.py` using values from `config.ini`. Local development uses different defaults specified in `docker-compose-local-dev.yml`.
129130

131+
### Static Files vs. Dynamic Requests (Apache routing)
132+
133+
On both servers, Apache sits in front of the Django container. It serves any URL that maps to a **real file** directly, and only **proxies to Django** (over plain HTTP) for paths that have no matching file. This has a few non-obvious consequences:
134+
135+
- **`/robots.txt` is a static file** — it is the top-level [`robots.txt`](../robots.txt) committed in the repo root, served by Apache from the project checkout. To change crawler rules or the advertised sitemap, edit that file and deploy. A Django view/route for `/robots.txt` would be dead code on the servers (it only runs under local `runserver`, which diverges from production).
136+
- **`/sitemap.xml` is dynamic** — no such file exists, so Apache proxies it to Django's `django.contrib.sitemaps` (see `website/sitemaps.py`), which builds the XML from the database on each request.
137+
- **Django sees requests as HTTP, not HTTPS.** Apache terminates TLS and proxies to Django over plain HTTP, so `request.scheme` is `http`. Any code that builds absolute URLs from the request (e.g. the sitemap) must force `https` explicitly — the sitemaps do this via `protocol = "https"`.
138+
- **The test server is never indexed.** Apache stamps `X-Robots-Tag: noindex, nofollow` on every response from the test host, so staging stays out of search engines regardless of its `robots.txt`.
139+
130140
## Debugging & Logging
131141

132142
### Log Files

0 commit comments

Comments
 (0)