diff --git a/.github/contributors.json b/.github/contributors.json
index 7920e8caf..e84337123 100644
--- a/.github/contributors.json
+++ b/.github/contributors.json
@@ -1362,5 +1362,25 @@
"name": "duffn",
"github_login": "duffn",
"twitter_username": ""
+ },
+ {
+ "name": "Delphine LEMIRE",
+ "github_login": "DelphineLemire",
+ "twitter_username": ""
+ },
+ {
+ "name": "Hoai-Thu Vuong",
+ "github_login": "thuvh",
+ "twitter_username": ""
+ },
+ {
+ "name": "Arkadiusz Michał Ryś",
+ "github_login": "arrys",
+ "twitter_username": ""
+ },
+ {
+ "name": "mpsantos",
+ "github_login": "mpsantos",
+ "twitter_username": ""
}
]
\ No newline at end of file
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index d95192f33..d308ff96a 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -27,6 +27,9 @@ updates:
directory: "{{cookiecutter.project_slug}}/compose/local/django/"
schedule:
interval: "daily"
+ ignore:
+ - dependency-name: "*"
+ update-types: ["version-update:semver-major", "version-update:semver-minor"]
labels:
- "update"
@@ -34,6 +37,9 @@ updates:
directory: "{{cookiecutter.project_slug}}/compose/local/docs/"
schedule:
interval: "daily"
+ ignore:
+ - dependency-name: "*"
+ update-types: ["version-update:semver-major", "version-update:semver-minor"]
labels:
- "update"
@@ -55,6 +61,9 @@ updates:
directory: "{{cookiecutter.project_slug}}/compose/production/django/"
schedule:
interval: "daily"
+ ignore:
+ - dependency-name: "*"
+ update-types: ["version-update:semver-major", "version-update:semver-minor"]
labels:
- "update"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2b88bc869..8457fa646 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,88 @@ All enhancements and patches to Cookiecutter Django will be documented in this f
+## 2023.03.14
+
+### Updated
+- Update django-celery-beat to 2.5.0 ([#4208](https://github.com/cookiecutter/cookiecutter-django/pull/4208))
+
+## 2023.03.13
+
+### Updated
+- Update uvicorn to 0.21.0 ([#4203](https://github.com/cookiecutter/cookiecutter-django/pull/4203))
+- Update django-anymail to 9.1 ([#4206](https://github.com/cookiecutter/cookiecutter-django/pull/4206))
+- Update tox to 4.4.7 ([#4207](https://github.com/cookiecutter/cookiecutter-django/pull/4207))
+
+## 2023.03.09
+
+### Fixed
+- Fix the omit configuration for coverage ([#4201](https://github.com/cookiecutter/cookiecutter-django/pull/4201))
+### Updated
+- Update ipdb to 0.13.13 ([#4202](https://github.com/cookiecutter/cookiecutter-django/pull/4202))
+
+## 2023.03.07
+
+### Updated
+- Update mypy to 1.1.1 ([#4196](https://github.com/cookiecutter/cookiecutter-django/pull/4196))
+- Update django-environ to 0.10.0 ([#4195](https://github.com/cookiecutter/cookiecutter-django/pull/4195))
+
+## 2023.03.04
+
+### Changed
+- Add option to serve media files locally using nginx ([#2457](https://github.com/cookiecutter/cookiecutter-django/pull/2457))
+### Documentation
+- Include contributing page to the docs ([#4144](https://github.com/cookiecutter/cookiecutter-django/pull/4144))
+### Updated
+- Update myst-parser to 0.19.1 ([#4193](https://github.com/cookiecutter/cookiecutter-django/pull/4193))
+- Update pytest to 7.2.2 ([#4191](https://github.com/cookiecutter/cookiecutter-django/pull/4191))
+- Update drf-spectacular to 0.26.0 ([#4192](https://github.com/cookiecutter/cookiecutter-django/pull/4192))
+
+## 2023.02.28
+
+### Updated
+- Update pre-commit to 3.1.1 ([#4188](https://github.com/cookiecutter/cookiecutter-django/pull/4188))
+
+## 2023.02.27
+
+### Updated
+- Update sentry-sdk to 1.16.0 ([#4187](https://github.com/cookiecutter/cookiecutter-django/pull/4187))
+
+## 2023.02.26
+
+### Changed
+- Fix readthedocs config file for generated project ([#4172](https://github.com/cookiecutter/cookiecutter-django/pull/4172))
+### Updated
+- Bump traefik from v2.2.11 to 2.9.8 ([#4164](https://github.com/cookiecutter/cookiecutter-django/pull/4164))
+- Update coverage to 7.2.1 ([#4186](https://github.com/cookiecutter/cookiecutter-django/pull/4186))
+
+## 2023.02.25
+
+### Changed
+- Run linting with pre-commit on GitLab ([#4150](https://github.com/cookiecutter/cookiecutter-django/pull/4150))
+### Fixed
+- Disable caching for linter job on GitHub actions ([#4166](https://github.com/cookiecutter/cookiecutter-django/pull/4166))
+### Documentation
+- Add instuction to run celery beat ([#4162](https://github.com/cookiecutter/cookiecutter-django/pull/4162))
+### Updated
+- Bump garland/aws-cli-docker from 1.15.47 to 1.16.140 ([#4136](https://github.com/cookiecutter/cookiecutter-django/pull/4136))
+- Update djangorestframework-stubs to 1.9.1 ([#4184](https://github.com/cookiecutter/cookiecutter-django/pull/4184))
+- Update whitenoise to 6.4.0 ([#4180](https://github.com/cookiecutter/cookiecutter-django/pull/4180))
+- Update django-stubs to 1.15.0 ([#4183](https://github.com/cookiecutter/cookiecutter-django/pull/4183))
+- Update django-crispy-forms to 2.0 ([#4158](https://github.com/cookiecutter/cookiecutter-django/pull/4158))
+- Update django-cors-headers to 3.14.0 ([#4181](https://github.com/cookiecutter/cookiecutter-django/pull/4181))
+- Update python-slugify to 8.0.1 ([#4178](https://github.com/cookiecutter/cookiecutter-django/pull/4178))
+- Update pre-commit to 3.1.0 ([#4176](https://github.com/cookiecutter/cookiecutter-django/pull/4176))
+- Update mypy to 1.0.1 ([#4168](https://github.com/cookiecutter/cookiecutter-django/pull/4168))
+- Update werkzeug to 2.2.3 ([#4160](https://github.com/cookiecutter/cookiecutter-django/pull/4160))
+- Update coverage to 7.2.0 ([#4177](https://github.com/cookiecutter/cookiecutter-django/pull/4177))
+- Update django to 4.0.10 ([#4159](https://github.com/cookiecutter/cookiecutter-django/pull/4159))
+- Update hiredis to 2.2.2 ([#4156](https://github.com/cookiecutter/cookiecutter-django/pull/4156))
+
+## 2023.02.17
+
+### Changed
+- Update version of github actions on the template project ([#4167](https://github.com/cookiecutter/cookiecutter-django/pull/4167))
+
## 2023.02.09
### Changed
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 85b1ae88f..f78278e34 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -292,6 +292,13 @@ Listed in alphabetical order.
Naveen |
diff --git a/README.md b/README.md
index 7ab0b7e15..aaeb25828 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ production-ready Django projects quickly.
- Optional basic ASGI setup for Websockets
- Optional custom static build using Gulp or Webpack
- Send emails via [Anymail](https://github.com/anymail/django-anymail) (using [Mailgun](http://www.mailgun.com/) by default or Amazon SES if AWS is selected cloud provider, but switchable)
-- Media storage using Amazon S3, Google Cloud Storage or Azure Storage
+- Media storage using Amazon S3, Google Cloud Storage, Azure Storage or nginx
- Docker support using [docker-compose](https://github.com/docker/compose) for development and production (using [Traefik](https://traefik.io/) with [LetsEncrypt](https://letsencrypt.org/) support)
- [Procfile](https://devcenter.heroku.com/articles/procfile) for deploying to Heroku
- Instructions for deploying to [PythonAnywhere](https://www.pythonanywhere.com/)
diff --git a/docs/conf.py b/docs/conf.py
index b53e6a7e7..b1a97750a 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -23,13 +23,13 @@ now = datetime.now()
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = []
+extensions = ["myst_parser"]
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
# The suffix of source filenames.
-source_suffix = ".rst"
+source_suffix = [".rst", ".md"]
# The encoding of source files.
# source_encoding = 'utf-8-sig'
diff --git a/docs/contributing.md b/docs/contributing.md
new file mode 100644
index 000000000..66c1f98d3
--- /dev/null
+++ b/docs/contributing.md
@@ -0,0 +1,3 @@
+```{include} ../CONTRIBUTING.md
+
+```
diff --git a/docs/deployment-with-docker.rst b/docs/deployment-with-docker.rst
index a431679bf..c1b8c6d7b 100644
--- a/docs/deployment-with-docker.rst
+++ b/docs/deployment-with-docker.rst
@@ -187,3 +187,7 @@ For status check, run::
supervisorctl status
+Media files without cloud provider
+----------------------------------
+
+If you chose no cloud provider and Docker, the media files will be served by an nginx service, from a ``production_django_media`` volume. Make sure to keep this around to avoid losing any media files.
diff --git a/docs/index.rst b/docs/index.rst
index dae641d10..da5186487 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -27,6 +27,7 @@ Contents
websocket
faq
troubleshooting
+ contributing
Indices and tables
------------------
diff --git a/docs/project-generation-options.rst b/docs/project-generation-options.rst
index d4ad8a9aa..9b379f12c 100644
--- a/docs/project-generation-options.rst
+++ b/docs/project-generation-options.rst
@@ -69,7 +69,7 @@ cloud_provider:
3. Azure_
4. None
- Note that if you choose no cloud provider, media files won't work.
+ If you choose no cloud provider and docker, the production stack will serve the media files via an nginx Docker service. Without Docker, the media files won't work.
mail_service:
Select an email service that Django-Anymail provides
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 0982f3d25..c16401c84 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,2 +1,3 @@
sphinx==6.1.3
sphinx-rtd-theme==1.2.0
+myst-parser==1.0.0
diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py
index b64bbbafd..dbc367175 100644
--- a/hooks/post_gen_project.py
+++ b/hooks/post_gen_project.py
@@ -491,9 +491,12 @@ def main():
use_async=("{{ cookiecutter.use_async }}".lower() == "y"),
)
- if "{{ cookiecutter.cloud_provider }}" == "None":
+ if (
+ "{{ cookiecutter.cloud_provider }}" == "None"
+ and "{{ cookiecutter.use_docker }}".lower() == "n"
+ ):
print(
- WARNING + "You chose not to use a cloud provider, "
+ WARNING + "You chose to not use any cloud providers nor Docker, "
"media files won't be served in production." + TERMINATOR
)
remove_storages_module()
diff --git a/requirements.txt b/requirements.txt
index 15c7c8c0a..b2e7cedb4 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,5 @@
cookiecutter==2.1.1
-sh==1.14.3; sys_platform != "win32"
+sh==2.0.2; sys_platform != "win32"
binaryornot==0.4.4
# Code quality
@@ -8,19 +8,19 @@ black==23.1.0
isort==5.12.0
flake8==6.0.0
flake8-isort==6.0.0
-pre-commit==3.0.4
+pre-commit==3.1.1
# Testing
# ------------------------------------------------------------------------------
-tox==4.4.5
-pytest==7.2.1
+tox==4.4.7
+pytest==7.2.2
pytest-cookies==0.6.1
pytest-instafail==0.4.2
pyyaml==6.0
# Scripting
# ------------------------------------------------------------------------------
-PyGithub==1.57
-gitpython==3.1.30
+PyGithub==1.58.0
+gitpython==3.1.31
jinja2==3.1.2
requests==2.28.2
diff --git a/setup.py b/setup.py
index 858d20691..762673d9a 100644
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@ except ImportError:
from distutils.core import setup
# We use calendar versioning
-version = "2023.02.09"
+version = "2023.03.14"
with open("README.rst") as readme_file:
long_description = readme_file.read()
diff --git a/tests/test_cookiecutter_generation.py b/tests/test_cookiecutter_generation.py
index 5608bf884..7628e5e1d 100755
--- a/tests/test_cookiecutter_generation.py
+++ b/tests/test_cookiecutter_generation.py
@@ -232,7 +232,7 @@ def test_travis_invokes_pytest(cookies, context, use_docker, expected_test_scrip
("y", "docker-compose -f local.yml run django pytest"),
],
)
-def test_gitlab_invokes_flake8_and_pytest(
+def test_gitlab_invokes_precommit_and_pytest(
cookies, context, use_docker, expected_test_script
):
context.update({"ci_tool": "Gitlab", "use_docker": use_docker})
@@ -246,7 +246,9 @@ def test_gitlab_invokes_flake8_and_pytest(
with open(f"{result.project_path}/.gitlab-ci.yml") as gitlab_yml:
try:
gitlab_config = yaml.safe_load(gitlab_yml)
- assert gitlab_config["flake8"]["script"] == ["flake8"]
+ assert gitlab_config["precommit"]["script"] == [
+ "pre-commit run --show-diff-on-failure --color=always --all-files"
+ ]
assert gitlab_config["pytest"]["script"] == [expected_test_script]
except yaml.YAMLError as e:
pytest.fail(e)
diff --git a/{{cookiecutter.project_slug}}/.github/dependabot.yml b/{{cookiecutter.project_slug}}/.github/dependabot.yml
index 420a63cdc..3f4eefe94 100644
--- a/{{cookiecutter.project_slug}}/.github/dependabot.yml
+++ b/{{cookiecutter.project_slug}}/.github/dependabot.yml
@@ -6,7 +6,7 @@ updates:
# Update GitHub actions in workflows
- package-ecosystem: "github-actions"
directory: "/"
- # Check for updates to GitHub Actions every weekday
+ # Every weekday
schedule:
interval: "daily"
@@ -19,55 +19,61 @@ updates:
- package-ecosystem: "docker"
# Look for a `Dockerfile` in the `compose/local/django` directory
directory: "compose/local/django/"
- # Check for updates to GitHub Actions every weekday
+ # Every weekday
schedule:
interval: "daily"
+ # Ignore minor version updates (3.10 -> 3.11) but update patch versions
+ ignore:
+ - dependency-name: "*"
+ update-types: ["version-update:semver-major", "version-update:semver-minor"]
- # Enable version updates for Docker
- package-ecosystem: "docker"
# Look for a `Dockerfile` in the `compose/local/docs` directory
directory: "compose/local/docs/"
- # Check for updates to GitHub Actions every weekday
+ # Every weekday
schedule:
interval: "daily"
+ # Ignore minor version updates (3.10 -> 3.11) but update patch versions
+ ignore:
+ - dependency-name: "*"
+ update-types: ["version-update:semver-major", "version-update:semver-minor"]
- # Enable version updates for Docker
- package-ecosystem: "docker"
# Look for a `Dockerfile` in the `compose/local/node` directory
directory: "compose/local/node/"
- # Check for updates to GitHub Actions every weekday
+ # Every weekday
schedule:
interval: "daily"
- # Enable version updates for Docker
- package-ecosystem: "docker"
# Look for a `Dockerfile` in the `compose/production/aws` directory
directory: "compose/production/aws/"
- # Check for updates to GitHub Actions every weekday
+ # Every weekday
schedule:
interval: "daily"
- # Enable version updates for Docker
- package-ecosystem: "docker"
# Look for a `Dockerfile` in the `compose/production/django` directory
directory: "compose/production/django/"
- # Check for updates to GitHub Actions every weekday
+ # Every weekday
schedule:
interval: "daily"
+ # Ignore minor version updates (3.10 -> 3.11) but update patch versions
+ ignore:
+ - dependency-name: "*"
+ update-types: ["version-update:semver-major", "version-update:semver-minor"]
- # Enable version updates for Docker
- package-ecosystem: "docker"
# Look for a `Dockerfile` in the `compose/production/postgres` directory
directory: "compose/production/postgres/"
- # Check for updates to GitHub Actions every weekday
+ # Every weekday
schedule:
interval: "daily"
- # Enable version updates for Docker
- package-ecosystem: "docker"
# Look for a `Dockerfile` in the `compose/production/traefik` directory
directory: "compose/production/traefik/"
- # Check for updates to GitHub Actions every weekday
+ # Every weekday
schedule:
interval: "daily"
@@ -78,7 +84,7 @@ updates:
# Look for a `requirements.txt` in the `root` directory
# also 'setup.cfg', 'runtime.txt' and 'requirements/*.txt'
directory: "/"
- # Check for updates to GitHub Actions every weekday
+ # Every weekday
schedule:
interval: "daily"
@@ -86,9 +92,9 @@ updates:
# Enable version updates for javascript/npm
- package-ecosystem: "npm"
- # Look for a `packages.json' in the `root` directory
+ # Look for a `packages.json` in the `root` directory
directory: "/"
- # Check for updates to GitHub Actions every weekday
+ # Every weekday
schedule:
interval: "daily"
diff --git a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml
index 3c8ea8780..89d83f257 100644
--- a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml
+++ b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml
@@ -27,16 +27,15 @@ jobs:
uses: actions/checkout@v3
- name: Set up Python
- uses: actions/setup-python@v3
+ uses: actions/setup-python@v4
with:
python-version: "3.10"
- cache: pip
{%- if cookiecutter.open_source_license != 'Not open source' %}
# Consider using pre-commit.ci for open source project
{%- endif %}
- name: Run pre-commit
- uses: pre-commit/action@v2.0.3
+ uses: pre-commit/action@v3.0.0
# With no caching at all the entire ci process takes 4m 30s to complete!
pytest:
@@ -85,7 +84,7 @@ jobs:
{%- else %}
- name: Set up Python
- uses: actions/setup-python@v3
+ uses: actions/setup-python@v4
with:
python-version: "3.10"
cache: pip
diff --git a/{{cookiecutter.project_slug}}/.gitlab-ci.yml b/{{cookiecutter.project_slug}}/.gitlab-ci.yml
index dbb65fb73..7892ad63a 100644
--- a/{{cookiecutter.project_slug}}/.gitlab-ci.yml
+++ b/{{cookiecutter.project_slug}}/.gitlab-ci.yml
@@ -7,21 +7,26 @@ variables:
POSTGRES_PASSWORD: ''
POSTGRES_DB: 'test_{{ cookiecutter.project_slug }}'
POSTGRES_HOST_AUTH_METHOD: trust
- {% if cookiecutter.use_celery == 'y' -%}
+ {%- if cookiecutter.use_celery == 'y' %}
CELERY_BROKER_URL: 'redis://redis:6379/0'
{%- endif %}
-flake8:
+precommit:
stage: lint
- image: python:3.10-alpine
+ image: python:3.10
+ variables:
+ PRE_COMMIT_HOME: ${CI_PROJECT_DIR}/.cache/pre-commit
+ cache:
+ paths:
+ - ${PRE_COMMIT_HOME}
before_script:
- - pip install -q flake8
+ - pip install -q pre-commit
script:
- - flake8
+ - pre-commit run --show-diff-on-failure --color=always --all-files
pytest:
stage: test
- {% if cookiecutter.use_docker == 'y' -%}
+ {%- if cookiecutter.use_docker == 'y' %}
image: docker/compose:1.29.2
tags:
- docker
@@ -34,7 +39,7 @@ pytest:
- docker-compose -f local.yml up -d
script:
- docker-compose -f local.yml run django pytest
- {%- else -%}
+ {%- else %}
image: python:3.10
tags:
- python
@@ -42,11 +47,8 @@ pytest:
- postgres:{{ cookiecutter.postgresql_version }}
variables:
DATABASE_URL: pgsql://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres/$POSTGRES_DB
-
before_script:
- pip install -r requirements/local.txt
-
script:
- pytest
{%- endif %}
-
diff --git a/{{cookiecutter.project_slug}}/.readthedocs.yml b/{{cookiecutter.project_slug}}/.readthedocs.yml
index e943a5fa9..08d7f9c24 100644
--- a/{{cookiecutter.project_slug}}/.readthedocs.yml
+++ b/{{cookiecutter.project_slug}}/.readthedocs.yml
@@ -1,12 +1,20 @@
+# Read the Docs configuration file
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
+
+# Required
version: 2
+# Set the version of Python and other tools you might need
+build:
+ os: ubuntu-22.04
+ tools:
+ python: "3.10"
+
+# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py
-build:
- image: testing
-
+# Python requirements required to build your docs
python:
- version: 3.10
install:
- requirements: requirements/local.txt
diff --git a/{{cookiecutter.project_slug}}/README.md b/{{cookiecutter.project_slug}}/README.md
index 16ee6d1fe..83f9a7e48 100644
--- a/{{cookiecutter.project_slug}}/README.md
+++ b/{{cookiecutter.project_slug}}/README.md
@@ -63,6 +63,20 @@ celery -A config.celery_app worker -l info
Please note: For Celery's import magic to work, it is important *where* the celery commands are run. If you are in the same folder with *manage.py*, you should be right.
+To run [periodic tasks](https://docs.celeryq.dev/en/stable/userguide/periodic-tasks.html), you'll need to start the celery beat scheduler service. You can start it as a standalone process:
+
+``` bash
+cd {{cookiecutter.project_slug}}
+celery -A config.celery_app beat
+```
+
+or you can embed the beat service inside a worker with the `-B` option (not recommended for production use):
+
+``` bash
+cd {{cookiecutter.project_slug}}
+celery -A config.celery_app worker -B -l info
+```
+
{%- endif %}
{%- if cookiecutter.use_mailhog == "y" %}
diff --git a/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile
index 3ea6b2d4c..36659d31d 100644
--- a/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile
+++ b/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile
@@ -1,7 +1,5 @@
-ARG PYTHON_VERSION=3.10-slim-bullseye
-
# define an alias for the specfic python version used in this file.
-FROM python:${PYTHON_VERSION} as python
+FROM python:3.10.9-slim-bullseye as python
# Python build stage
FROM python as python-build-stage
diff --git a/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile
index c45d18c95..f52e34d26 100644
--- a/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile
+++ b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile
@@ -1,7 +1,5 @@
-ARG PYTHON_VERSION=3.10-slim-bullseye
-
# define an alias for the specfic python version used in this file.
-FROM python:${PYTHON_VERSION} as python
+FROM python:3.10.9-slim-bullseye as python
# Python build stage
diff --git a/{{cookiecutter.project_slug}}/compose/production/aws/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/aws/Dockerfile
index 8282047b3..4d1ecbb20 100644
--- a/{{cookiecutter.project_slug}}/compose/production/aws/Dockerfile
+++ b/{{cookiecutter.project_slug}}/compose/production/aws/Dockerfile
@@ -1,4 +1,4 @@
-FROM garland/aws-cli-docker:1.15.47
+FROM garland/aws-cli-docker:1.16.140
COPY ./compose/production/aws/maintenance /usr/local/bin/maintenance
COPY ./compose/production/postgres/maintenance/_sourced /usr/local/bin/maintenance/_sourced
diff --git a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile
index ef80441ba..ac4ca7714 100644
--- a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile
+++ b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile
@@ -1,5 +1,3 @@
-ARG PYTHON_VERSION=3.10-slim-bullseye
-
{% if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] -%}
FROM node:16-bullseye-slim as client-builder
@@ -28,7 +26,7 @@ RUN npm run build
{%- endif %}
# define an alias for the specfic python version used in this file.
-FROM python:${PYTHON_VERSION} as python
+FROM python:3.10.9-slim-bullseye as python
# Python build stage
FROM python as python-build-stage
diff --git a/{{cookiecutter.project_slug}}/compose/production/nginx/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/nginx/Dockerfile
new file mode 100644
index 000000000..911b16f71
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/compose/production/nginx/Dockerfile
@@ -0,0 +1,2 @@
+FROM nginx:1.17.8-alpine
+COPY ./compose/production/nginx/default.conf /etc/nginx/conf.d/default.conf
diff --git a/{{cookiecutter.project_slug}}/compose/production/nginx/default.conf b/{{cookiecutter.project_slug}}/compose/production/nginx/default.conf
new file mode 100644
index 000000000..aafdd5bee
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/compose/production/nginx/default.conf
@@ -0,0 +1,7 @@
+server {
+ listen 80;
+ server_name localhost;
+ location /media/ {
+ alias /usr/share/nginx/media/;
+ }
+}
diff --git a/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile
index aa879052b..2365c4c49 100644
--- a/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile
+++ b/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile
@@ -1,4 +1,4 @@
-FROM traefik:v2.2.11
+FROM traefik:2.9.8
RUN mkdir -p /etc/traefik/acme \
&& touch /etc/traefik/acme/acme.json \
&& chmod 600 /etc/traefik/acme/acme.json
diff --git a/{{cookiecutter.project_slug}}/compose/production/traefik/traefik.yml b/{{cookiecutter.project_slug}}/compose/production/traefik/traefik.yml
index cc183cd6c..ea57f4a51 100644
--- a/{{cookiecutter.project_slug}}/compose/production/traefik/traefik.yml
+++ b/{{cookiecutter.project_slug}}/compose/production/traefik/traefik.yml
@@ -57,6 +57,18 @@ http:
# https://docs.traefik.io/master/routing/routers/#certresolver
certResolver: letsencrypt
{%- endif %}
+ {%- if cookiecutter.cloud_provider == 'None' %}
+
+ web-media-router:
+ rule: "Host(`{{ cookiecutter.domain_name }}`) && PathPrefix(`/media/`)"
+ entryPoints:
+ - web-secure
+ middlewares:
+ - csrf
+ service: django-media
+ tls:
+ certResolver: letsencrypt
+ {%- endif %}
middlewares:
csrf:
@@ -77,6 +89,13 @@ http:
servers:
- url: http://flower:5555
{%- endif %}
+ {%- if cookiecutter.cloud_provider == 'None' %}
+
+ django-media:
+ loadBalancer:
+ servers:
+ - url: http://nginx:80
+ {%- endif %}
providers:
# https://docs.traefik.io/master/providers/file/
diff --git a/{{cookiecutter.project_slug}}/production.yml b/{{cookiecutter.project_slug}}/production.yml
index 45c8b3c1d..4e9b9e048 100644
--- a/{{cookiecutter.project_slug}}/production.yml
+++ b/{{cookiecutter.project_slug}}/production.yml
@@ -4,6 +4,9 @@ volumes:
production_postgres_data: {}
production_postgres_data_backups: {}
production_traefik: {}
+ {%- if cookiecutter.cloud_provider == 'None' %}
+ production_django_media: {}
+ {%- endif %}
services:
django:{% if cookiecutter.use_celery == 'y' %} &django{% endif %}
@@ -24,6 +27,10 @@ services:
{%- endif %}
image: {{ cookiecutter.project_slug }}_production_django
+ {%- if cookiecutter.cloud_provider == 'None' %}
+ volumes:
+ - production_django_media:/app/{{ cookiecutter.project_slug }}/media
+ {%- endif %}
depends_on:
- postgres
- redis
@@ -89,3 +96,14 @@ services:
volumes:
- production_postgres_data_backups:/backups:z
{%- endif %}
+ {%- if cookiecutter.cloud_provider == 'None' %}
+ nginx:
+ build:
+ context: .
+ dockerfile: ./compose/production/nginx/Dockerfile
+ image: {{ cookiecutter.project_slug }}_local_nginx
+ depends_on:
+ - django
+ volumes:
+ - production_django_media:/usr/share/nginx/media:ro
+ {%- endif %}
diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt
index 9bcdf31bf..2fff9561f 100644
--- a/{{cookiecutter.project_slug}}/requirements/base.txt
+++ b/{{cookiecutter.project_slug}}/requirements/base.txt
@@ -1,5 +1,5 @@
pytz==2022.7.1 # https://github.com/stub42/pytz
-python-slugify==8.0.0 # https://github.com/un33k/python-slugify
+python-slugify==8.0.1 # https://github.com/un33k/python-slugify
Pillow==9.4.0 # https://github.com/python-pillow/Pillow
{%- if cookiecutter.frontend_pipeline == 'Django Compressor' %}
{%- if cookiecutter.windows == 'y' and cookiecutter.use_docker == 'n' %}
@@ -10,30 +10,30 @@ rcssmin==1.1.1 # https://github.com/ndparker/rcssmin
{%- endif %}
argon2-cffi==21.3.0 # https://github.com/hynek/argon2_cffi
{%- if cookiecutter.use_whitenoise == 'y' %}
-whitenoise==6.3.0 # https://github.com/evansd/whitenoise
+whitenoise==6.4.0 # https://github.com/evansd/whitenoise
{%- endif %}
redis==4.5.1 # https://github.com/redis/redis-py
{%- if cookiecutter.use_docker == "y" or cookiecutter.windows == "n" %}
-hiredis==2.2.1 # https://github.com/redis/hiredis-py
+hiredis==2.2.2 # https://github.com/redis/hiredis-py
{%- endif %}
{%- if cookiecutter.use_celery == "y" %}
celery==5.2.7 # pyup: < 6.0 # https://github.com/celery/celery
-django-celery-beat==2.4.0 # https://github.com/celery/django-celery-beat
+django-celery-beat==2.5.0 # https://github.com/celery/django-celery-beat
{%- if cookiecutter.use_docker == 'y' %}
flower==1.2.0 # https://github.com/mher/flower
{%- endif %}
{%- endif %}
{%- if cookiecutter.use_async == 'y' %}
-uvicorn[standard]==0.20.0 # https://github.com/encode/uvicorn
+uvicorn[standard]==0.21.1 # https://github.com/encode/uvicorn
{%- endif %}
# Django
# ------------------------------------------------------------------------------
-django==4.0.9 # pyup: < 4.1 # https://www.djangoproject.com/
-django-environ==0.9.0 # https://github.com/joke2k/django-environ
+django==4.0.10 # pyup: < 4.1 # https://www.djangoproject.com/
+django-environ==0.10.0 # https://github.com/joke2k/django-environ
django-model-utils==4.3.1 # https://github.com/jazzband/django-model-utils
-django-allauth==0.52.0 # https://github.com/pennersr/django-allauth
-django-crispy-forms==1.14.0 # https://github.com/django-crispy-forms/django-crispy-forms
+django-allauth==0.53.0 # https://github.com/pennersr/django-allauth
+django-crispy-forms==2.0 # https://github.com/django-crispy-forms/django-crispy-forms
crispy-bootstrap5==0.7 # https://github.com/django-crispy-forms/crispy-bootstrap5
{%- if cookiecutter.frontend_pipeline == 'Django Compressor' %}
django-compressor==4.3.1 # https://github.com/django-compressor/django-compressor
@@ -42,9 +42,9 @@ django-redis==5.2.0 # https://github.com/jazzband/django-redis
{%- if cookiecutter.use_drf == 'y' %}
# Django REST Framework
djangorestframework==3.14.0 # https://github.com/encode/django-rest-framework
-django-cors-headers==3.13.0 # https://github.com/adamchainz/django-cors-headers
+django-cors-headers==3.14.0 # https://github.com/adamchainz/django-cors-headers
# DRF-spectacular for api documentation
-drf-spectacular==0.25.1 # https://github.com/tfranzel/drf-spectacular
+drf-spectacular==0.26.0 # https://github.com/tfranzel/drf-spectacular
{%- endif %}
{%- if cookiecutter.frontend_pipeline == 'Webpack' %}
django-webpack-loader==1.8.1 # https://github.com/django-webpack/django-webpack-loader
diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt
index 00c15d3cb..218cdcaad 100644
--- a/{{cookiecutter.project_slug}}/requirements/local.txt
+++ b/{{cookiecutter.project_slug}}/requirements/local.txt
@@ -1,7 +1,7 @@
-r base.txt
-Werkzeug[watchdog]==2.2.2 # https://github.com/pallets/werkzeug
-ipdb==0.13.11 # https://github.com/gotcha/ipdb
+Werkzeug[watchdog]==2.2.3 # https://github.com/pallets/werkzeug
+ipdb==0.13.13 # https://github.com/gotcha/ipdb
{%- if cookiecutter.use_docker == 'y' %}
psycopg2==2.9.5 # https://github.com/psycopg/psycopg2
{%- else %}
@@ -13,12 +13,12 @@ watchfiles==0.18.1 # https://github.com/samuelcolvin/watchfiles
# Testing
# ------------------------------------------------------------------------------
-mypy==0.991 # https://github.com/python/mypy
-django-stubs==1.14.0 # https://github.com/typeddjango/django-stubs
-pytest==7.2.1 # https://github.com/pytest-dev/pytest
+mypy==1.1.1 # https://github.com/python/mypy
+django-stubs==1.15.0 # https://github.com/typeddjango/django-stubs
+pytest==7.2.2 # https://github.com/pytest-dev/pytest
pytest-sugar==0.9.6 # https://github.com/Frozenball/pytest-sugar
{%- if cookiecutter.use_drf == "y" %}
-djangorestframework-stubs==1.8.0 # https://github.com/typeddjango/djangorestframework-stubs
+djangorestframework-stubs==1.9.1 # https://github.com/typeddjango/djangorestframework-stubs
{%- endif %}
# Documentation
@@ -30,13 +30,13 @@ sphinx-autobuild==2021.3.14 # https://github.com/GaretJax/sphinx-autobuild
# ------------------------------------------------------------------------------
flake8==6.0.0 # https://github.com/PyCQA/flake8
flake8-isort==6.0.0 # https://github.com/gforcada/flake8-isort
-coverage==7.1.0 # https://github.com/nedbat/coveragepy
+coverage==7.2.1 # https://github.com/nedbat/coveragepy
black==23.1.0 # https://github.com/psf/black
pylint-django==2.5.3 # https://github.com/PyCQA/pylint-django
{%- if cookiecutter.use_celery == 'y' %}
pylint-celery==0.3 # https://github.com/PyCQA/pylint-celery
{%- endif %}
-pre-commit==3.0.4 # https://github.com/pre-commit/pre-commit
+pre-commit==3.1.1 # https://github.com/pre-commit/pre-commit
# Django
# ------------------------------------------------------------------------------
diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt
index 06917d8dd..c79f98431 100644
--- a/{{cookiecutter.project_slug}}/requirements/production.txt
+++ b/{{cookiecutter.project_slug}}/requirements/production.txt
@@ -8,10 +8,10 @@ psycopg2==2.9.5 # https://github.com/psycopg/psycopg2
Collectfast==2.2.0 # https://github.com/antonagestam/collectfast
{%- endif %}
{%- if cookiecutter.use_sentry == "y" %}
-sentry-sdk==1.15.0 # https://github.com/getsentry/sentry-python
+sentry-sdk==1.16.0 # https://github.com/getsentry/sentry-python
{%- endif %}
{%- if cookiecutter.use_docker == "n" and cookiecutter.windows == "y" %}
-hiredis==2.2.1 # https://github.com/redis/hiredis-py
+hiredis==2.2.2 # https://github.com/redis/hiredis-py
{%- endif %}
# Django
@@ -24,21 +24,21 @@ django-storages[google]==1.13.2 # https://github.com/jschneier/django-storages
django-storages[azure]==1.13.2 # https://github.com/jschneier/django-storages
{%- endif %}
{%- if cookiecutter.mail_service == 'Mailgun' %}
-django-anymail[mailgun]==9.0 # https://github.com/anymail/django-anymail
+django-anymail[mailgun]==9.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Amazon SES' %}
-django-anymail[amazon_ses]==9.0 # https://github.com/anymail/django-anymail
+django-anymail[amazon_ses]==9.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Mailjet' %}
-django-anymail[mailjet]==9.0 # https://github.com/anymail/django-anymail
+django-anymail[mailjet]==9.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Mandrill' %}
-django-anymail[mandrill]==9.0 # https://github.com/anymail/django-anymail
+django-anymail[mandrill]==9.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Postmark' %}
-django-anymail[postmark]==9.0 # https://github.com/anymail/django-anymail
+django-anymail[postmark]==9.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Sendgrid' %}
-django-anymail[sendgrid]==9.0 # https://github.com/anymail/django-anymail
+django-anymail[sendgrid]==9.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'SendinBlue' %}
-django-anymail[sendinblue]==9.0 # https://github.com/anymail/django-anymail
+django-anymail[sendinblue]==9.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'SparkPost' %}
-django-anymail[sparkpost]==9.0 # https://github.com/anymail/django-anymail
+django-anymail[sparkpost]==9.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Other SMTP' %}
-django-anymail==9.0 # https://github.com/anymail/django-anymail
+django-anymail==9.1 # https://github.com/anymail/django-anymail
{%- endif %}
diff --git a/{{cookiecutter.project_slug}}/setup.cfg b/{{cookiecutter.project_slug}}/setup.cfg
index 7ee60215a..e282af36a 100644
--- a/{{cookiecutter.project_slug}}/setup.cfg
+++ b/{{cookiecutter.project_slug}}/setup.cfg
@@ -35,6 +35,6 @@ ignore_errors = True
[coverage:run]
include = {{cookiecutter.project_slug}}/**
-omit = *migrations*, *tests*
+omit = */migrations/*, */tests/*
plugins =
django_coverage_plugin
|