Skip to content

Commit a8fbfa7

Browse files
authored
Merge pull request #1385 from makeabilitylab/1034-gunicorn
Run Gunicorn on test/prod instead of Django's dev runserver (#1034)
2 parents 6d6cb2e + fe7c99a commit a8fbfa7

2 files changed

Lines changed: 52 additions & 4 deletions

File tree

docker-entrypoint.sh

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,39 @@ python manage.py setup_admin_groups
164164
# python manage.py rename_talk_files
165165

166166
# Start server
167-
echo "Starting server"
167+
#
168+
# Production-grade environments (TEST, PROD) run Gunicorn, the recommended WSGI
169+
# server. Local development (DJANGO_ENV=DEBUG) keeps Django's `runserver` for
170+
# its auto-reload on code edits, friendlier tracebacks, debug toolbar, and
171+
# static-file serving under DEBUG=True. See issue #1034.
172+
#
173+
# This swap is entirely inside the container -- UW CSE's Apache still reverse-
174+
# proxies dynamic requests to 127.0.0.1:8571 (-> container :8000) and serves
175+
# /static/ and /media/ directly, exactly as before -- so it ships via the
176+
# normal push-to-deploy path with no Apache/IT changes.
177+
#
178+
# Gunicorn tuning (overridable via env vars in the compose file):
179+
# GUNICORN_WORKERS number of worker processes. The (2*cores)+1 rule of thumb
180+
# would be ~49 on the 24-core host, but that box is SHARED
181+
# with all Project Sidewalk instances (see #959), so we
182+
# default to a modest 3.
183+
# GUNICORN_TIMEOUT per-request worker timeout in seconds. Gunicorn's default
184+
# of 30s can kill slow admin operations (ImageMagick/PDF
185+
# thumbnail generation), so we default to 120.
168186
echo "****************** STEP 5/5: docker-entrypoint.sh ************************"
169-
echo "5. Starting server with 'python manage.py runserver 0.0.0.0:8000'"
170-
echo "******************************************"
171-
python manage.py runserver 0.0.0.0:8000
187+
if [ "$DJANGO_ENV" = "TEST" ] || [ "$DJANGO_ENV" = "PROD" ]; then
188+
GUNICORN_WORKERS="${GUNICORN_WORKERS:-3}"
189+
GUNICORN_TIMEOUT="${GUNICORN_TIMEOUT:-120}"
190+
echo "5. Starting Gunicorn (DJANGO_ENV=$DJANGO_ENV, workers=$GUNICORN_WORKERS, timeout=${GUNICORN_TIMEOUT}s)"
191+
echo "******************************************"
192+
exec gunicorn makeabilitylab.wsgi:application \
193+
--bind 0.0.0.0:8000 \
194+
--workers "$GUNICORN_WORKERS" \
195+
--timeout "$GUNICORN_TIMEOUT" \
196+
--access-logfile - \
197+
--error-logfile -
198+
else
199+
echo "5. Starting dev server with 'python manage.py runserver 0.0.0.0:8000' (DJANGO_ENV=$DJANGO_ENV)"
200+
echo "******************************************"
201+
exec python manage.py runserver 0.0.0.0:8000
202+
fi

requirements.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,23 @@ django-sortedm2m==4.0.0
116116
django-prose-editor[sanitize]==0.26.0
117117

118118

119+
# -----------------------------------------------------------------------------
120+
# WSGI Server (production)
121+
# -----------------------------------------------------------------------------
122+
# Gunicorn is the production WSGI server. We previously ran Django's dev
123+
# `runserver` on test AND prod, which the Django docs explicitly warn against
124+
# ("DO NOT USE THIS SERVER IN A PRODUCTION SETTING ... has not gone through
125+
# security audits or performance tests"). See issue #1034.
126+
#
127+
# Gunicorn runs inside the same container behind UW CSE's Apache reverse proxy
128+
# (Apache still serves /static/ and /media/ directly and proxies dynamic
129+
# requests to 127.0.0.1:8571 -> container :8000), so this swap is contained to
130+
# the container and ships via the normal push-to-deploy path -- no Apache or
131+
# UW CSE IT changes required. Worker count and request timeout are tunable via
132+
# the GUNICORN_WORKERS / GUNICORN_TIMEOUT env vars in docker-entrypoint.sh.
133+
# See: https://docs.djangoproject.com/en/5.2/howto/deployment/wsgi/gunicorn/
134+
gunicorn==23.0.0
135+
119136
# -----------------------------------------------------------------------------
120137
# Security & Networking
121138
# -----------------------------------------------------------------------------

0 commit comments

Comments
 (0)