Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion {{ cookiecutter.name }}/.github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ jobs:
- name: lint
run: make lint

- name: Lint the Dockerfile
uses: hadolint/hadolint-action@v3.1.0

test:
needs: lint
runs-on: ubuntu-latest

services:
postgres:
image: postgres:16.1-alpine
image: postgres:16.2-alpine
env:
POSTGRES_PASSWORD: secret
options: >-
Expand Down
4 changes: 4 additions & 0 deletions {{ cookiecutter.name }}/.hadolint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
ignored:
- DL3008
- SC2002
2 changes: 2 additions & 0 deletions {{ cookiecutter.name }}/.yamllint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
rules:
line-length: disable
33 changes: 6 additions & 27 deletions {{ cookiecutter.name }}/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ ARG PYTHON_VERSION=python-version-not-set
FROM python:${PYTHON_VERSION}-slim-bookworm AS uwsgi-compile
ENV _UWSGI_VERSION=2.0.29
RUN apt-get update && apt-get --no-install-recommends install -y build-essential wget && rm -rf /var/lib/apt/lists/*
RUN wget -O uwsgi-${_UWSGI_VERSION}.tar.gz https://github.com/unbit/uwsgi/archive/${_UWSGI_VERSION}.tar.gz \
RUN wget --progress=dot:giga -O uwsgi-${_UWSGI_VERSION}.tar.gz https://github.com/unbit/uwsgi/archive/${_UWSGI_VERSION}.tar.gz \
&& tar zxvf uwsgi-*.tar.gz \
&& UWSGI_BIN_NAME=/uwsgi make -C uwsgi-${_UWSGI_VERSION} \
&& rm -Rf uwsgi-*
Expand Down Expand Up @@ -56,8 +56,8 @@ ENV PATH="/code/.venv/bin:$PATH"
WORKDIR /code/src

USER web
RUN python manage.py compilemessages
RUN python manage.py collectstatic --noinput
RUN python manage.py compilemessages \
&& python manage.py collectstatic --noinput

# Also to mark that when CMD is used in shell form, it is a conscious decision
SHELL ["/bin/bash", "-c"]
Expand All @@ -67,32 +67,15 @@ 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 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
CMD ["sh", "-c", "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

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
Expand All @@ -105,8 +88,4 @@ VOLUME ${_SCHEDULER_DB_PATH}

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"]
28 changes: 23 additions & 5 deletions {{ cookiecutter.name }}/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,34 @@ fmt:
uv run ruff format src
uv run toml-sort pyproject.toml

lint:
lint: lint-sources lint-dockerfile lint-yaml
uv run toml-sort --check pyproject.toml
uv run pymarkdown scan README.md
uv run dotenv-linter src/app/.env.ci

lint-sources:
uv run python src/manage.py check
uv run python src/manage.py makemigrations --check --dry-run --no-input

uv run python src/manage.py spectacular --api-version v1 --fail-on-warn > /dev/null
uv run ruff check src
uv run ruff format --check src
uv run mypy src
uv run toml-sort --check pyproject.toml
uv run pymarkdown scan README.md
uv run dotenv-linter src/app/.env.ci

lint-dockerfile:
@if command -v hadolint >/dev/null 2>&1; then \
echo Running hadolint...; \
hadolint Dockerfile; \
else \
echo "hadolint not found, skipping Dockerfile linting"; \
fi

lint-yaml:
@if command -v yamllint >/dev/null 2>&1; then \
echo Running yamllint...; \
yamllint .; \
else \
echo "yamllint not found, skipping YAML files linting"; \
fi

test:
uv run pytest --dead-fixtures
Expand Down