{"id":20313089,"url":"https://github.com/edoburu/docker-django-base-images","last_synced_at":"2025-04-11T16:51:45.382Z","repository":{"id":142735089,"uuid":"116681753","full_name":"edoburu/docker-django-base-images","owner":"edoburu","description":"Docker base images for Django projects","archived":false,"fork":false,"pushed_at":"2024-02-05T10:20:17.000Z","size":70,"stargazers_count":16,"open_issues_count":1,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-05T01:32:55.159Z","etag":null,"topics":["docker-image","python36"],"latest_commit_sha":null,"homepage":"https://hub.docker.com/r/edoburu/django-base-images/","language":"Dockerfile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/edoburu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2018-01-08T13:43:22.000Z","updated_at":"2025-03-30T02:03:44.000Z","dependencies_parsed_at":"2023-10-16T19:56:37.091Z","dependency_job_id":null,"html_url":"https://github.com/edoburu/docker-django-base-images","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edoburu%2Fdocker-django-base-images","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edoburu%2Fdocker-django-base-images/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edoburu%2Fdocker-django-base-images/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edoburu%2Fdocker-django-base-images/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/edoburu","download_url":"https://codeload.github.com/edoburu/docker-django-base-images/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248443071,"owners_count":21104331,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker-image","python36"],"created_at":"2024-11-14T18:09:14.404Z","updated_at":"2025-04-11T16:51:45.358Z","avatar_url":"https://github.com/edoburu.png","language":"Dockerfile","funding_links":[],"categories":[],"sub_categories":[],"readme":"Base docker images for Django\n=============================\n\nThese images are suitable as base for running Django inside a Docker Swarm or Kubernetes environment.\n\nFeatures:\n\n* Nessesairy base libraries to install Django.\n* Multi-stage builds for smaller runtime images (below 300MB).\n* No separate Nginx container is needed thanks to `uwsgi --http-socket`.\n* [MozJPEG](https://github.com/mozilla/mozjpeg) installed.\n* Pillow generated JPEG images pass [Google PageSpeed](https://developers.google.com/speed/pagespeed/insights/).\n* Run `manage.py check --deploy` on startup.\n\nThe default ports are 8080 (HTTP) and 1717 (uWSGI stats). These higher ports allow the container to run as unprivileged user.\n\nStatic files are efficiently served from uWSGI using offload threads. You may use [WhiteNoise](http://whitenoise.evans.io/) to generate cache-busting file names, given that you have an edge-node that caches these files (e.g. AWS CloudFront). Delegating static file serving to a separate Nginx container is pretty pointless, given that everything likely runs behind an HTTP proxy already to route virtual hosts (e.g. Kubernetes Nginx ingress).\n\nThe standard libjpeg and libjpeg-turbo are optimized to quickly encode JPEG files. MozJPEG is a drop-in replacement which is slower for encoding, but faster for downloading and decoding. The resuling images are much slower and pass [Google PageSpeed](https://developers.google.com/speed/pagespeed/insights/). All images generated by Pillow, including those by [sorl-thumbnail](https://github.com/jazzband/sorl-thumbnail), use MozJPEG for rendering.\n\nLinking Pillow against MozJPEG does require require Pillow to be installed from the source tarball using `pip install --no-binary=Pillow ...`. Otherwise, the Pillow wheel package is installed, which bundles it's own copy of libjpeg. The build image contains a caching layer for the latest Pillow image to avoid recompiling Pillow in most use-cases.\n\n**Tips:** When using `sorl-thumbnail`, add the setting `THUMBNAIL_QUALITY = 75` to match the behavior of the default `cjpeg` tool. A quality of 80 is also sufficient. The default value for `THUMBNAIL_QUALITY` is 95, which generates overly large thumbnail files.\n\n**NOTE:** uwsgi doesn't build yet on Python 3.12, hence it's not provided in the py312-* images.\n\nAvailable tags\n--------------\n\nBase images:\n\n- `py312-bookworm-build` ([Dockerfile](https://github.com/edoburu/docker-django-base-image/blob/master/py312-bookworm-build/Dockerfile)) - Build-time container with [mozjpeg](https://github.com/mozilla/mozjpeg), and [Pillow](https://python-pillow.org/) 9.2.0 linked to it.\n- `py312-bookworm-runtime` ([Dockerfile](https://github.com/edoburu/docker-django-base-image/blob/master/py312-bookworm-runtime/Dockerfile)) - Run-time container with [mozjpeg](https://github.com/mozilla/mozjpeg), and default run-time libraries.\n- `py310-bullseye-build` ([Dockerfile](https://github.com/edoburu/docker-django-base-image/blob/master/py310-bullseye-build/Dockerfile)) - Build-time container with [mozjpeg](https://github.com/mozilla/mozjpeg), and [Pillow](https://python-pillow.org/) 9.2.0 linked to it.\n- `py310-bullseye-runtime` ([Dockerfile](https://github.com/edoburu/docker-django-base-image/blob/master/py310-bullseye-runtime/Dockerfile)) - Run-time container with [mozjpeg](https://github.com/mozilla/mozjpeg), and default run-time libraries.\n\nOnbuild images:\n\n- `py312-bookworm-build-onbuild` ([Dockerfile](https://github.com/edoburu/docker-django-base-image/blob/master/py312-bookworm-build/onbuild/Dockerfile)) - Pre-scripted build container that assumes `src/requirements/docker.txt` is available. Supports `PIP_REQUIREMENTS` build arg.\n- `py312-bookworm-runtime-onbuild` ([Dockerfile](https://github.com/edoburu/docker-django-base-image/blob/master/py312-bookworm-runtime/onbuild/Dockerfile)) - Pre-scripted runtime container that assumes `src/`, `web/media` and `web/static` are available. Supports `GIT_VERSION` build arg.\n- `py310-bullseye-build-onbuild` ([Dockerfile](https://github.com/edoburu/docker-django-base-image/blob/master/py310-bullseye-build/onbuild/Dockerfile)) - Pre-scripted build container that assumes `src/requirements/docker.txt` is available. Supports `PIP_REQUIREMENTS` build arg.\n- `py310-bullseye-runtime-onbuild` ([Dockerfile](https://github.com/edoburu/docker-django-base-image/blob/master/py310-bullseye-runtime/onbuild/Dockerfile)) - Pre-scripted runtime container that assumes `src/`, `web/media` and `web/static` are available. Supports `GIT_VERSION` build arg.\n\n\nOnbuild Usage\n-------------\n\nThe \"onbuild\" images contain pre-scripted and opinionated assumptions about the application layout.\nUsing these images result in a very small ``Dockerfile``:\n\n```dockerfile\nFROM edoburu/django-base-images:py312-bookworm-build-onbuild AS build-image\n\n# Remove more unneeded locale files\nRUN find /usr/local/lib/python3.12/site-packages/babel/locale-data/ -not -name 'en*' -not -name 'nl*' -name '*.dat' -delete \u0026\u0026 \\\n    find /usr/local/lib/python3.12/site-packages/tinymce/ -regextype posix-egrep -not -regex '.*/langs/(en|nl).*\\.js' -wholename '*/langs/*.js' -delete\n\n# Start runtime container\nFROM edoburu/django-base-images:py312-bookworm-runtime-onbuild\nENV DJANGO_SETTINGS_MODULE=mysite.settings.docker \\\n    UWSGI_MODULE=mysite.wsgi.docker:application\n\n# Collect static files as root, with gzipped files for uwsgi to serve\nRUN manage.py compilemessages \u0026\u0026 \\\n    manage.py collectstatic --settings=$DJANGO_SETTINGS_MODULE --noinput \u0026\u0026 \\\n    gzip --keep --best --force --recursive /app/web/static/\n\n# Add extra uwsgi settings\nCOPY deployment/docker/uwsgi-local.ini /usr/local/etc/uwsgi-local.ini\n\n# Reduce default permissions\nUSER app\n```\n\nYou may add `SILENCED_SYSTEM_CHECKS = ['security.W001']` since the `SecurityMiddleware` headers are sent by uWSGI already.\n\n\nBase image usage\n----------------\n\nWhile the \"onbuild\" images are opinionated, the base images only contain what is absolutely needed. By using these images, your custom `Dockerfile` can break with all assumptions that the onbuild images make. This example is equivalent to the onbuild example above:\n\n```dockerfile\n# Build environment has gcc and develop header files.\n# The installed files are copied to the smaller runtime container.\nFROM edoburu/django-base-images:py312-bookworm-build AS build-image\n\n# Install (and compile) all dependencies\nRUN mkdir -p /app/src/requirements\nCOPY src/requirements/*.txt /app/src/requirements/\nARG PIP_REQUIREMENTS=/app/src/requirements/docker.txt\nRUN pip install --no-binary=Pillow -r $PIP_REQUIREMENTS\n\n# Remove unneeded locale files\nRUN find /usr/local/lib/python3.12/site-packages/ -name '*.po' -delete \u0026\u0026 \\\n    find /usr/local/lib/python3.12/site-packages/babel/locale-data/ -not -name 'en*' -not -name 'nl*' -name '*.dat' -delete \u0026\u0026 \\\n    find /usr/local/lib/python3.12/site-packages/tinymce/ -regextype posix-egrep -not -regex '.*/langs/(en|nl).*\\.js' -wholename '*/langs/*.js' -delete\n\n# Start runtime container\n# Default DATABASE_URL is useful for local testing, and avoids connect timeouts for `manage.py`.\nFROM edoburu/django-base-images:py312-bookworm-runtime\nENV UWSGI_PROCESSES=1 \\\n    UWSGI_THREADS=20 \\\n    UWSGI_OFFLOAD_THREADS=%k \\\n    UWSGI_MODULE=mysite.wsgi.docker:application \\\n    DJANGO_SETTINGS_MODULE=mysite.settings.docker \\\n    DATABASE_URL=sqlite:////tmp/demo.db\n\n# System config (done early, avoid running on every code change)\nEXPOSE 8080 1717\nCMD [\"/usr/local/bin/uwsgi\", \"--ini\", \"/usr/local/etc/uwsgi.ini\"]\nWORKDIR /app/src\nVOLUME /app/web/media\n\n# Install dependencies\nCOPY --from=build-image /usr/local/bin/ /usr/local/bin/\nCOPY --from=build-image /usr/local/lib/python3.12/site-packages/ /usr/local/lib/python3.12/site-packages/\nCOPY deployment/docker/manage.py /usr/local/bin/\nCOPY deployment/docker/uwsgi.ini /usr/local/etc/uwsgi.ini\n\n# Insert application code.\n# - Set a default database URL for accidental DB requests\n# - Prepare gzipped versions of static files for uWSGI to use\n# - Create a default database inside the container (as demo),\n#   when caller doesn't define DATABASE_URL\n# - Give full permissions, so Kubernetes can run the image as different user\nCOPY web /app/web\nCOPY src /app/src\nRUN rm /app/src/*/settings/local.py* \u0026\u0026 \\\n    find . -name '*.pyc' -delete \u0026\u0026 \\\n    python -mcompileall -q */ \u0026\u0026 \\\n    manage.py compilemessages \u0026\u0026 \\\n    manage.py collectstatic --noinput \u0026\u0026 \\\n    gzip --keep --best --force --recursive /app/web/static/ \u0026\u0026 \\\n    chown -R app:app /app/web/media/ /app/web/static/CACHE \u0026\u0026 \\\n    chmod -R go+rw /app/web/media/ /app/web/static/CACHE\n\n# Reduce default permissions\nUSER app\n```\n\nA `.dockerignore` with at least the following exclusions is recommended:\n\n```\n*.pyc\n*.mo\n*.db\n*.css.map\n.cache\n.sass-cache\n.idea\n.vagrant\n.git\n.DS_Store\n__pycache__\nsrc/myproject/settings/local.py\nsrc/node_modules\nweb/media\nweb/static/CACHE\n```\n\nOverriding UWSGI config\n-----------------------\n\nThe onbuild image contains a default [uwsgi.ini](https://github.com/edoburu/docker-django-base-images/blob/master/py37-stretch-runtime/onbuild/uwsgi.ini) that is fully functional, but is slightly opinionated about static file paths. It can be easily extended by adding a different version:\n\n```\nCOPY uwsgi-local.ini /usr/local/etc/uwsgi-local.ini\n```\n\nOr overwritten all together:\n\n```\nCOPY uwsgi.ini /usr/local/etc/uwsgi.ini\n```\n\nThe default [uwsgi.ini](https://github.com/edoburu/docker-django-base-images/blob/master/py37-stretch-runtime/onbuild/uwsgi.ini) serves static files entirely from uWSGI, with HTTP cache headers set. [WhiteNoise](http://whitenoise.evans.io/) can still be used to generate cache-busing file names, but serving files performs better using `uwsgi --static-map` since it can cache ``stat()`` calls and use offload threads.\n\n\nOther recommendations\n---------------------\n\nDon't forget to include a `HEALTHCHECK` in your docker file:\n\n```dockerfile\nHEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost:8080/api/healthcheck/ || exit 1\n```\n\nConsider adding `localhost` to `ALLOWED_HOSTS`, to make healthhecks easy to implement.\n\nConsider including the latest git version:\n\n```dockerfile\nARG GIT_VERSION\nLABEL git-version=$GIT_VERSION\nRUN echo $GIT_VERSION \u003e .docker-git-version\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedoburu%2Fdocker-django-base-images","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fedoburu%2Fdocker-django-base-images","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedoburu%2Fdocker-django-base-images/lists"}