This repository has been archived by the owner on Nov 17, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #17 from praekeltfoundation/feature/docker-setup
Feature/docker setup
- Loading branch information
Showing
4 changed files
with
261 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
# Docker-specific things: | ||
# Docker files | ||
Dockerfile | ||
*.dockerfile | ||
.dockerignore | ||
|
||
# Git files | ||
.git/ | ||
**/.gitignore | ||
|
||
# Adapted from the standard Python .gitignore | ||
# https://github.com/github/gitignore/blob/master/Python.gitignore | ||
# 455a69dd48ce041f6ac2aa7aeeb9560957311e2f | ||
|
||
# Byte-compiled / optimized / DLL files | ||
**/__pycache__/ | ||
**/*.py[cod] | ||
**/*$py.class | ||
|
||
# C extensions | ||
*.so | ||
|
||
# Distribution / packaging | ||
.Python | ||
env/ | ||
build/ | ||
develop-eggs/ | ||
dist/ | ||
downloads/ | ||
eggs/ | ||
.eggs/ | ||
lib/ | ||
lib64/ | ||
parts/ | ||
sdist/ | ||
var/ | ||
*.egg-info/ | ||
.installed.cfg | ||
*.egg | ||
|
||
# PyInstaller | ||
# Usually these files are written by a python script from a template | ||
# before PyInstaller builds the exe, so as to inject date/other infos into it. | ||
*.manifest | ||
*.spec | ||
|
||
# Installer logs | ||
pip-log.txt | ||
pip-delete-this-directory.txt | ||
|
||
# Unit test / coverage reports | ||
htmlcov/ | ||
.tox/ | ||
.coverage | ||
.coverage.* | ||
.cache | ||
nosetests.xml | ||
coverage.xml | ||
*,cover | ||
.hypothesis/ | ||
|
||
# Translations | ||
**/*.mo | ||
**/*.pot | ||
|
||
# Django stuff: | ||
*.log | ||
local_settings.py | ||
|
||
# Flask stuff: | ||
instance/ | ||
.webassets-cache | ||
|
||
# Scrapy stuff: | ||
.scrapy | ||
|
||
# Sphinx documentation | ||
docs/_build/ | ||
|
||
# PyBuilder | ||
target/ | ||
|
||
# IPython Notebook | ||
.ipynb_checkpoints | ||
|
||
# pyenv | ||
.python-version | ||
|
||
# celery beat schedule file | ||
celerybeat-schedule | ||
|
||
# dotenv | ||
.env | ||
|
||
# virtualenv | ||
venv/ | ||
ENV/ | ||
|
||
# Spyder project settings | ||
.spyderproject | ||
|
||
# Rope project settings | ||
.ropeproject |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
FROM praekeltfoundation/django-bootstrap:py3.6 | ||
|
||
COPY . /app | ||
COPY entrypoint.sh /scripts/django-entrypoint.sh | ||
COPY nginx.conf /etc/nginx/conf.d/django.conf | ||
RUN pip install -e . | ||
|
||
ENV DJANGO_SETTINGS_MODULE "momkhulu.settings.production" | ||
RUN ./manage.py collectstatic --noinput | ||
CMD ["momkhulu.wsgi:application"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#!/usr/bin/env sh | ||
set -e | ||
|
||
# No args or looks like options or the APP_MODULE for Gunicorn | ||
if [ "$#" = 0 ] || \ | ||
[ "${1#-}" != "$1" ] || \ | ||
echo "$1" | grep -Eq '^([_A-Za-z]\w*\.)*[_A-Za-z]\w*:[_A-Za-z]\w*$'; then | ||
set -- gunicorn "$@" | ||
fi | ||
|
||
# Looks like a Celery command, let's run that with Celery's entrypoint script | ||
if [ "$1" = 'celery' ]; then | ||
set -- celery-entrypoint.sh "$@" | ||
fi | ||
|
||
if [ "$1" = 'gunicorn' ] || [ "$1" = 'daphne' ]; then | ||
# Do an extra chown of the /app directory at runtime in addition to the one in | ||
# the build process in case any directories are mounted as root-owned volumes | ||
# at runtime. | ||
chown -R django:django /app | ||
|
||
# Run the migration as the django user so that if it creates a local DB | ||
# (e.g. when using sqlite in development), that DB is still writable. | ||
# Ultimately, the user shouldn't really be using a local DB and it's difficult | ||
# to offer support for all the cases in which a local DB might be created -- | ||
# but here we do the minimum. | ||
if [ -z "$SKIP_MIGRATIONS" ]; then | ||
su-exec django django-admin migrate --noinput | ||
fi | ||
|
||
if [ -n "$SUPERUSER_PASSWORD" ]; then | ||
echo "from django.contrib.auth.models import User | ||
if not User.objects.filter(username='admin').exists(): | ||
User.objects.create_superuser('admin', 'admin@example.com', '$SUPERUSER_PASSWORD') | ||
" | su-exec django django-admin shell | ||
echo "Created superuser with username 'admin' and password '$SUPERUSER_PASSWORD'" | ||
fi | ||
|
||
nginx -g 'daemon off;' & | ||
|
||
# Celery | ||
ensure_celery_app() { | ||
[ -n "$CELERY_APP" ] || \ | ||
{ echo 'If $CELERY_WORKER or $CELERY_BEAT are set then $CELERY_APP must be provided'; exit 1; } | ||
} | ||
|
||
if [ -n "$CELERY_WORKER" ]; then | ||
ensure_celery_app | ||
celery-entrypoint.sh worker --pool=solo --pidfile worker.pid & | ||
fi | ||
|
||
if [ -n "$CELERY_BEAT" ]; then | ||
ensure_celery_app | ||
celery-entrypoint.sh beat --pidfile beat.pid & | ||
fi | ||
|
||
# Set some sensible Gunicorn and daphne options, needed for things to work with Nginx | ||
|
||
# umask working files (worker tmp files & unix socket) as 0o117 (i.e. chmod as | ||
# 0o660) so that they are only read/writable by django and nginx users. | ||
if [ "$1" = 'gunicorn' ]; then | ||
set -- su-exec django "$@" \ | ||
--pid /var/run/gunicorn/gunicorn.pid \ | ||
--bind unix:/var/run/gunicorn/gunicorn.sock \ | ||
--umask 0117 \ | ||
${GUNICORN_ACCESS_LOGS:+--access-logfile -} | ||
fi | ||
if [ "$1" = 'daphne' ]; then | ||
set -- su-exec django "$@" \ | ||
-u /var/run/gunicorn/gunicorn.sock | ||
fi | ||
fi | ||
|
||
exec "$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
upstream gunicorn { | ||
# Proxy to Gunicorn socket and always retry, as recommended by deployment | ||
# guide: http://docs.gunicorn.org/en/stable/deploy.html | ||
server unix:/var/run/gunicorn/gunicorn.sock max_fails=0; | ||
} | ||
|
||
# Detect filenames for static files that look like they contain MD5 hashes as | ||
# these can be cached indefinitely. | ||
|
||
# Nginx's 'expires max' directive sets the Cache-Control header to have a max- | ||
# age of 10 years. It also sets the Expires header to a certain date in 2037: | ||
# http://nginx.org/en/docs/http/ngx_http_headers_module.html#expires | ||
|
||
# We also want to add the 'public' and 'immutable' values to the Cache-Control | ||
# header to prevent clients from revalidating files that we know are immutable: | ||
# https://bitsup.blogspot.co.za/2016/05/cache-control-immutable.html | ||
|
||
# Using 'expires max' makes adding other Cache-Control values tricky and the | ||
# The Expires header should be ignored when a max-age is set for Cache-Control: | ||
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires | ||
|
||
# So, avoid 'expires max' & just add the header manually with a 10-year max-age. | ||
map $uri $static_cache_control { | ||
# ManifestStaticFilesStorage files have a hash in the middle of the filename | ||
"~^/static/.*/[^/\.]+\.[a-f0-9]{12}\.\w+$" "max-age=315360000, public, immutable"; | ||
|
||
# django-compressor cached files are js/css with a hash filename | ||
"~^/static/CACHE/(js|css)/[a-f0-9]{12}\.(js|css)$" "max-age=315360000, public, immutable"; | ||
|
||
# For the default, copy what WhiteNoise does and set a short max-age | ||
default "max-age=60, public"; | ||
} | ||
|
||
server { | ||
listen 8000; | ||
|
||
root /app; | ||
|
||
location ~ ^/static/?(.*)$ { | ||
# Fallback for projects still using STATIC_ROOT = BASE_DIR/staticfiles | ||
# as recommended by WhiteNoise | ||
try_files /static/$1 /staticfiles/$1 =404; | ||
add_header Cache-Control $static_cache_control; | ||
} | ||
|
||
location ~ ^/media/?(.*)$ { | ||
# Fallback for projects still using MEDIA_ROOT = BASE_DIR/mediafiles | ||
try_files /media/$1 /mediafiles/$1 =404; | ||
} | ||
|
||
location / { | ||
client_max_body_size 20m; | ||
proxy_pass http://gunicorn; | ||
|
||
proxy_set_header Host $http_host; | ||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||
|
||
# For websockets, from https://www.nginx.com/blog/websocket-nginx/ | ||
proxy_http_version 1.1; | ||
proxy_set_header Upgrade $http_upgrade; | ||
proxy_set_header Connection "Upgrade"; | ||
|
||
# We only use the 'X-Forwarded-Proto' header from our load-balancer to | ||
# indicate the original connection used HTTPS, but Gunicorn by default | ||
# accepts more headers than that: | ||
# http://docs.gunicorn.org/en/19.7.1/settings.html#secure-scheme-headers | ||
# Overriding that config in Gunicorn is a bit complicated, and could | ||
# easily be overriden by accident by the user, so just delete those | ||
# other headers here so that a client can't set them | ||
# incorrectly/maliciously. | ||
proxy_set_header X-Forwarded-Protocol ""; | ||
proxy_set_header X-Forwarded-Ssl ""; | ||
} | ||
} |