diff --git a/{{ cookiecutter.name }}/Dockerfile b/{{ cookiecutter.name }}/Dockerfile index 091c98eb..53e2fdb8 100644 --- a/{{ cookiecutter.name }}/Dockerfile +++ b/{{ cookiecutter.name }}/Dockerfile @@ -38,21 +38,27 @@ LABEL maintainer="{{ cookiecutter.email }}" ENV DEBIAN_FRONTEND=noninteractive ENV PYTHONUNBUFFERED=1 ENV STATIC_ROOT=/var/lib/django-static +# Define user ids to ensure consistent permissions, e.g., for mounted volumes +ENV UID=999 GID=999 RUN apt-get update \ && apt-get --no-install-recommends install -y gettext locales-all tzdata git wait-for-it wget \ && rm -rf /var/lib/apt/lists/* +RUN groupadd --system --gid=${GID} "web" \ + && useradd --system --uid=${UID} --gid=${GID} --create-home --home-dir "/code" "web" + COPY --from=uwsgi-compile /uwsgi /usr/local/bin/ -COPY --from=deps-compile /code/.venv /code/.venv -COPY src /code/src +COPY --from=deps-compile --chown=web:web /code/.venv /code/.venv +COPY --chown=web:web src /code/src ENV PATH="/code/.venv/bin:$PATH" WORKDIR /code/src -RUN chmod +x ./manage.py -RUN ./manage.py compilemessages -RUN ./manage.py collectstatic --noinput +RUN python manage.py compilemessages +RUN python manage.py collectstatic --noinput + +USER web # Also to mark that when CMD is used in shell form, it is a conscious decision SHELL ["/bin/bash", "-c"] @@ -62,8 +68,17 @@ FROM base AS web HEALTHCHECK --interval=15s --timeout=15s --start-period=15s --retries=3 \ CMD wget --quiet --tries=1 --spider http://localhost:8000/api/v1/healthchecks/ -CMD ./manage.py migrate && uwsgi --master --http :8000 --venv /code/.venv/ --wsgi app.wsgi --workers 2 --threads 2 --harakiri 25 --max-requests 1000 --log-x-forwarded-for - +CMD python manage.py migrate \ + && uwsgi \ + --master \ + --http=:8000 \ + --venv=/code/.venv/ \ + --wsgi=app.wsgi \ + --workers=2 \ + --threads=2 \ + --harakiri=25 \ + --max-requests=1000 \ + --log-x-forwarded-for FROM base AS worker @@ -71,17 +86,28 @@ ENV _CELERY_APP=app.celery HEALTHCHECK --interval=15s --timeout=15s --start-period=5s --retries=3 \ CMD celery --app=${_CELERY_APP} inspect ping --destination=celery@$HOSTNAME -CMD celery --app=${_CELERY_APP} worker --concurrency=${CONCURENCY:-2} --hostname="celery@%h" --max-tasks-per-child=${MAX_REQUESTS_PER_CHILD:-50} --time-limit=${TIME_LIMIT:-900} --soft-time-limit=${SOFT_TIME_LIMIT:-45} +CMD celery \ + --app=${_CELERY_APP} \ + worker \ + --concurrency=${CONCURENCY:-2} \ + --hostname="celery@%h" \ + --max-tasks-per-child=${MAX_REQUESTS_PER_CHILD:-50} \ + --time-limit=${TIME_LIMIT:-900} \ + --soft-time-limit=${SOFT_TIME_LIMIT:-45} FROM base AS scheduler ENV _SCHEDULER_DB_PATH=/var/db/scheduler USER root -RUN mkdir -p ${_SCHEDULER_DB_PATH} && chown nobody ${_SCHEDULER_DB_PATH} +RUN mkdir --parent ${_SCHEDULER_DB_PATH} && chown web:web ${_SCHEDULER_DB_PATH} +USER web VOLUME ${_SCHEDULER_DB_PATH} -USER nobody ENV _CELERY_APP=app.celery HEALTHCHECK NONE -CMD celery --app=${_CELERY_APP} beat --pidfile=/tmp/celerybeat.pid --schedule=${_SCHEDULER_DB_PATH}/celerybeat-schedule.db +CMD celery \ + --app=${_CELERY_APP} \ + beat \ + --pidfile=/tmp/celerybeat.pid \ + --schedule=${_SCHEDULER_DB_PATH}/celerybeat-schedule.db