cookiecutter-django/{{cookiecutter.project_slug}}/Dockerfile

137 lines
3.6 KiB
Docker

##############################################
# Build virtualenv
##############################################
FROM python:{{cookiecutter.python_version}}-bullseye AS venv
# Prepare poetry
##############################################
# https://python-poetry.org/docs/#installation
ENV POETRY_VERSION={{cookiecutter.poetry_version}}
RUN curl -sSL https://install.python-poetry.org | python3 -
ENV PATH /root/.local/bin:$PATH
RUN python -m pip install --user poetry-lock-check==0.1.0 \
cleo==0.8.1 # poetry-lock-check depends on cleo
WORKDIR /app
COPY pyproject.toml poetry.lock ./
RUN python -m poetry_lock_check check-lock
# Install python dependencies
##############################################
RUN python -m venv --copies /app/venv
# Will install dev deps as well, so that we can run tests in this image
RUN . /app/venv/bin/activate \
&& poetry install --no-interaction
ENV PATH /app/venv/bin:$PATH
# Collect static files & build assets
##############################################
COPY ./src /app/src
COPY ./envs/local-envs.env /app/.env
WORKDIR /app/src
# Required for manage.py to startup
ARG ENV_FILE=/app/.env
ARG DEBUG=true
ENV STATIC_ROOT=/app/static
RUN mkdir -p $STATIC_ROOT
# Build assets so that we don't need the build tools later
RUN python manage.py collectstatic --noinput --clear
##############################################
# write git info
##############################################
FROM alpine/git:v2.26.2 AS git
WORKDIR /app
COPY .git /app/.git/
RUN git describe --tags --always > /git-describe
RUN git rev-parse HEAD > /git-commit
RUN date +'%Y-%m-%d %H:%M %Z' > /build-date
##############################################
# Main image
##############################################
FROM python:{{cookiecutter.python_version}}-slim-bullseye AS final
ARG DEBIAN_FRONTEND=noninteractive
# Setup user & group
##############################################
RUN groupadd -g 1000 django
RUN useradd -M -d /app -u 1000 -g 1000 -s /bin/bash django
# Setup system
##############################################
RUN apt-get update -y \
&& apt-get install -y --no-install-recommends \
libxml2 \
media-types \
postgresql-client
# Fetch project requirements
##############################################
COPY --chown=django:django --from=venv /app/venv /app/venv/
COPY --chown=django:django --from=git /git-describe /git-commit /build-date /app/git/
ENV PATH /app/venv/bin:$PATH
# Fetch built assets & static files
##############################################
ENV STATIC_ROOT=/app/static
COPY --chown=django:django --from=venv $STATIC_ROOT $STATIC_ROOT
# uWSGI env vars
##############################################
ENV UWSGI_HTTP=:8000
ENV UWSGI_CHDIR="/app/src"
ENV UWSGI_WSGI_FILE="/app/src/{{cookiecutter.project_slug}}/wsgi.py"
ENV UWSGI_MASTER=1
ENV UWSGI_HTTP_AUTO_CHUNKED=1
ENV UWSGI_HTTP_KEEPALIVE=1
ENV UWSGI_UID=1000
ENV UWSGI_GID=1000
ENV UWSGI_WSGI_ENV_BEHAVIOR=holy
ENV UWSGI_DIE_ON_TERM=true
ENV UWSGI_STRICT=true
ENV UWSGI_NEED_APP=true
# Tweak for perf
ENV UWSGI_SINGLE_INTERPRETER=true
ENV UWSGI_AUTO_PROCNAME=true
ENV UWSGI_MAX_REQUESTS=5000
ENV UWSGI_MAX_WORKER_LIFETIME=3600
ENV UWSGI_RELOAD_ON_RSS=500
ENV UWSGI_WORKER_RELOAD_MERCY=10
ENV UWSGI_WORKERS=2 UWSGI_THREADS=4
# Create directory structure
##############################################
WORKDIR /app
COPY pyproject.toml poetry.lock ./
ADD --chown=django:django ./src ./src
COPY --chown=django:django tasks.py ./tasks.py
COPY --chown=django:django docker/uwsgi.ini ./uwsgi.ini
RUN mkdir -p /app/data
RUN chown django:django /app /app/data
EXPOSE 8000
WORKDIR /app/src
USER django
CMD ["uwsgi", "--show-config", "--ini", "/app/uwsgi.ini"]