* Pin Python version to 3.12
* Add back actions/setup-python to bare metal tests
* Revert "Add back actions/setup-python to bare metal tests"
This reverts commit cdee7e2da7.
* Update test_bare.sh to run commands via uv
* Skip uv lock on PRs from forks
* Revert "Update test_bare.sh to run commands via uv"
This reverts commit 56f839e2b4.
* Add back actions/setup-python to bare metal tests
* Only run uv lock workflow on dependabot PRs
* Add workflow to keep uv.lock up to date
Should do the job for dependabot updates
* Only run uv lock workflow when GH_PAT is set
* Make a change to pyproject.toml
* Attempt to fix workflow syntax
* Attempt to fix workflow syntax
* Regenerate uv.lock
This option is now longer valid
```
$ heroku addons:create heroku-postgresql:mini
› Warning: heroku update available from 8.11.5 to 9.2.1.
Creating heroku-postgresql:mini on ⬢ location-tracker... !
▸ We tried to create heroku-postgresql:mini, but received an error from the add-on provider. Try the request again, or log a support ticket and include
▸ this message: The mini plan has reached end-of-life. You can try again with a valid plan. See the available plans with: heroku addons:plans
▸ heroku-postgresql.
```
The next cheapest heroku option is "essentials-0"
```
$ heroku addons:create heroku-postgresql:essential-0
› Warning: heroku update available from 8.11.5 to 9.2.1.
Creating heroku-postgresql:essential-0 on ⬢ location-tracker... ~$0.007/hour (max $5/month)
Database should be available soon
postgresql-silhouetted-14783 is being created in the background. The app will restart when complete...
Use heroku addons:info postgresql-silhouetted-14783 to check creation progress
Use heroku addons:docs heroku-postgresql to view documentation
```
documentation: https://elements.heroku.com/addons/heroku-postgresql
* change email subject prefix variable name in settings
* Update {{cookiecutter.project_slug}}/config/settings/production.py
Co-authored-by: Bruno Alla <browniebroke@users.noreply.github.com>
---------
Co-authored-by: Alex Kanavos <alexkanv@gmail.com>
Co-authored-by: Bruno Alla <browniebroke@users.noreply.github.com>
Watchdog 5.0.0 was recently released. This update causes Werkzeug to reload the Django server much more frequently than desired (causing the local docker development build to barely load).
* Update ruff from 0.6.0 to 0.6.1
* Update ruff from 0.6.0 to 0.6.1
* Auto-update pre-commit hooks
---------
Co-authored-by: browniebroke <861044+browniebroke@users.noreply.github.com>
Co-authored-by: Bruno Alla <browniebroke@users.noreply.github.com>
* Update ruff from 0.5.7 to 0.6.0
* Update ruff from 0.5.7 to 0.6.0
* Update Ruff pre-commit hook
* Update pytest style to match update Ruff rules
* Switch Ruff setting from exclude to extend-exclude
* Omit default Ruff settings
---------
Co-authored-by: Bruno Alla <alla.brunoo@gmail.com>
* Fix: clear ENTRYPOINT in derived image to allow script execution
* Added explanation regarding clearing ENTRYPOINT from the base image
Co-authored-by: Bruno Alla <browniebroke@users.noreply.github.com>
---------
Co-authored-by: Bruno Alla <browniebroke@users.noreply.github.com>
* Update ruff from 0.5.0 to 0.5.1
* Update ruff from 0.5.0 to 0.5.1
* Auto-update ruff pre-commit hook (#5194)
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Bruno Alla <browniebroke@users.noreply.github.com>
Recently noticed the following warning in my Docker builds:
> WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match
I don't think it's causing any harm, apart perhaps some small noise in the logs.
* chore: Replace deprecated uvicorn.workers with uvicorn-worker
* Add package and fix worker class name
---------
Co-authored-by: Bruno Alla <alla.brunoo@gmail.com>
The book link for "Two Scoops of Django 3.x" was a 404; updated to the current page in `README` and `faq.rst`. `README.md`: pointed to a current cover image. Changed the HTML `<img>` tags to use markdown instead, removed `<p>` center tags
* Renamed local.yml to docker-compose.local.yml
* Renamed production.yml to docker-compose.production.yml
* Rename docs.yml to docker-compose.docs.yml
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Bruno Alla <alla.brunoo@gmail.com>
* feat(docs): add instruction for adding a django app
Following the the steps outlined in:
https://github.com/cookiecutter/cookiecutter-django/discussions/4339#discussioncomment-5922166
this PR adds a "Creating Your First Django App" section to the docs
breifly expalins the file structure and outlines the steps to add a new
app.
* Update docs/developing-locally.rst
Co-authored-by: Bruno Alla <browniebroke@users.noreply.github.com>
* Update docs/developing-locally.rst
Co-authored-by: Bruno Alla <browniebroke@users.noreply.github.com>
---------
Co-authored-by: Bruno Alla <browniebroke@users.noreply.github.com>
* Fix Python (docker) Docker image version not being recognized after adding registry to image names
* Fix Python (docs) Docker image version not being recognized after adding registry to image names
* Fix Python (django) Docker image version not being recognized after adding registry to image names
In order to run pytest we can constrain the build command to only build the images related to the django service.
This mainly prevents the docs image from being built unnecessarily.
This cuts run time of the Github Actions workflow from approx. 4min 30s to below 3min.
* Update testing.rst - coverage config file is now pyproject.toml
* Update docs/testing.rst
---------
Co-authored-by: Bruno Alla <browniebroke@users.noreply.github.com>
* Update black from 23.12.1 to 24.1.0
* Update black from 23.12.1 to 24.1.0
* Update black pre-commit hooks
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Fix a few styling issues for black v24
---------
Co-authored-by: Bruno Alla <alla.brunoo@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
The custom cloud storages module has been deleted, and the settings have been updated to use the storage backend settings directly from each cloud provider's storage backend libraries. These changes have simplified the cloud storage configuration for each cloud provider in the production settings file.
Parsing doesn't work for classifiers that only
include the Django major version, e.g.:
``'Framework :: Django :: 3'`
We need a '.' in the 4th part of the classifier
to be able to parse it:
``'Framework :: Django :: 3.2'`
* Update mypy from 1.6.1 to 1.7.1
* Update djangorestframework-stubs from 3.14.4 to 3.14.5
* Update django-stubs from 4.2.6 to 4.2.7
---------
Co-authored-by: Bruno Alla <alla.brunoo@gmail.com>
@ -18,39 +18,26 @@ This last step is very important, don't start developing from master, it'll caus
## Testing
You'll need to run the tests using Python 3.11. We recommend using [tox](https://tox.readthedocs.io/en/latest/) to run the tests. It will automatically create a fresh virtual environment and install our test dependencies, such as [pytest-cookies](https://pypi.python.org/pypi/pytest-cookies/) and [flake8](https://pypi.python.org/pypi/flake8/).
You'll need to run the tests using Python 3.12. We recommend using [tox](https://tox.readthedocs.io/en/latest/) to run the tests. It will automatically create a fresh virtual environment and install our test dependencies, such as [pytest-cookies](https://pypi.python.org/pypi/pytest-cookies/) and [flake8](https://pypi.python.org/pypi/flake8/).
We'll also run the tests on GitHub actions when you send your pull request, but it's a good idea to run them locally before you send it.
### Installation
First, make sure that your version of Python is 3.11:
```bash
$ python --version
Python 3.11.3
```
Any version that starts with 3.11 will do. If you need to install it, you can get it from [python.org](https://www.python.org/downloads/).
Then install `tox`, if not already installed:
```bash
$ python -m pip install tox
```
We use uv to manage our environment and manage our Python installation. You can install it following the instructions at https://docs.astral.sh/uv/getting-started/installation/
### Run the template's test suite
To run the tests of the template using the current Python version:
```bash
$ tox -e py
$ uv run tox run -e py
```
This uses `pytest `under the hood, and you can pass options to it after a `--`. So to run a particular test:
```bash
$ tox -e py -- -k test_default_configuration
$ uv run tox run -e py -- -k test_default_configuration
```
For further information, please consult the [pytest usage docs](https://pytest.org/en/latest/how-to/usage.html#specifying-which-tests-to-run).
@ -66,13 +53,13 @@ $ source venv/bin/activate
These tests are slower and can be run with or without Docker:
- Without Docker: `scripts/test_bare.sh` (for bare metal)
- With Docker: `scripts/test_docker.sh`
- Without Docker: `tests/test_bare.sh` (for bare metal)
- With Docker: `tests/test_docker.sh`
All arguments to these scripts will be passed to the `cookiecutter` CLI, letting you set options, for example:
[](https://www.feldroy.com/two-scoops-press#two-scoops-of-django)
Two Scoops of Django 3.x is the best ice cream-themed Django reference in the universe!
PyUp brings you automated security and dependency updates used by Google and other organizations. Free for open source projects!
@ -98,7 +94,7 @@ You'll be prompted for some values. Provide them, then a Django project will be
**Warning**: After this point, change 'Daniel Greenfeld', 'pydanny', etc to your own information.
Answer the prompts with your own desired [options](http://cookiecutter-django.readthedocs.io/en/latest/project-generation-options.html). For example:
Answer the prompts with your own desired [options](http://cookiecutter-django.readthedocs.io/en/latest/1-getting-started/project-generation-options.html). For example:
Cloning into 'cookiecutter-django'...
remote: Counting objects: 550, done.
@ -133,13 +129,11 @@ Answer the prompts with your own desired [options](http://cookiecutter-django.re
Choose from 1, 2, 3 [1]: 1
use_docker [n]: n
Select postgresql_version:
1 - 15
2 - 14
3 - 13
4 - 12
5 - 11
6 - 10
Choose from 1, 2, 3, 4, 5 [1]: 1
1 - 16
2 - 15
3 - 14
4 - 13
Choose from 1, 2, 3, 4 [1]: 1
Select cloud_provider:
1 - AWS
2 - GCP
@ -152,7 +146,7 @@ Answer the prompts with your own desired [options](http://cookiecutter-django.re
4 - Mandrill
5 - Postmark
6 - Sendgrid
7 - SendinBlue
7 - Brevo (formerly SendinBlue)
8 - SparkPost
9 - Other SMTP
Choose from 1, 2, 3, 4, 5, 6, 7, 8, 9 [1]: 1
@ -195,8 +189,8 @@ Now take a look at your repo. Don't forget to carefully look at the generated RE
- [Developing locally using docker](https://cookiecutter-django.readthedocs.io/en/latest/2-local-development/developing-locally-docker.html)
## Community
@ -249,6 +243,7 @@ experience better.
## Articles
- [Why cookiecutter-django is Essential for Your Next Django Project](https://medium.com/@millsks/why-cookiecutter-django-is-essential-for-your-next-django-project-7d3c00cdce51) - Aug. 4, 2024
- [How to Make Your Own Django Cookiecutter Template!](https://medium.com/@FatemeFouladkar/how-to-make-your-own-django-cookiecutter-template-a753d4cbb8c2) - Aug. 10, 2023
- [Cookiecutter Django With Amazon RDS](https://haseeburrehman.com/posts/cookiecutter-django-with-amazon-rds/) - Apr, 2, 2021
- [Complete Walkthrough: Blue/Green Deployment to AWS ECS using GitHub actions](https://github.com/Andrew-Chen-Wang/cookiecutter-django-ecs-github) - June 10, 2020
Generally, if you want to emulate production environment use ``production.yml`` instead. And this is true for any other actions you might need to perform: whenever a switch is required, just do it!
Generally, if you want to emulate production environment use ``docker-compose.production.yml`` instead. And this is true for any other actions you might need to perform: whenever a switch is required, just do it!
Before doing any git commit, `pre-commit`_ should be installed globally on your local machine, and then::
@ -43,7 +43,6 @@ Before doing any git commit, `pre-commit`_ should be installed globally on your
Failing to do so will result with a bunch of CI and Linter errors that can be avoided with pre-commit.
Run the Stack
-------------
@ -51,11 +50,11 @@ This brings up both Django and PostgreSQL. The first time it is run it might tak
Open a terminal at the project root and run the following for local development::
$ docker compose -f local.yml up
$ docker compose -f docker-compose.local.yml up
You can also set the environment variable ``COMPOSE_FILE`` pointing to ``local.yml`` like this::
You can also set the environment variable ``COMPOSE_FILE`` pointing to ``docker-compose.local.yml`` like this::
$ export COMPOSE_FILE=local.yml
$ export COMPOSE_FILE=docker-compose.local.yml
And then run::
@ -65,16 +64,23 @@ To run in a detached (background) mode, just::
$ docker compose up -d
These commands don't run the docs service. In order to run docs service you can run::
$ docker compose -f docker-compose.docs.yml up
To run the docs with local services just use::
$ docker compose -f docker-compose.local.yml -f docker-compose.docs.yml up
The site should start and be accessible at http://localhost:3000 if you selected Webpack or Gulp as frontend pipeline and http://localhost:8000 otherwise.
Execute Management Commands
---------------------------
As with any shell command that we wish to run in our container, this is done using the ``docker compose -f local.yml run --rm`` command: ::
As with any shell command that we wish to run in our container, this is done using the ``docker compose -f docker-compose.local.yml run --rm`` command: ::
Here, ``django`` is the target service we are executing the commands against.
Also, please note that the ``docker exec`` does not work for running management commands.
@ -84,13 +90,12 @@ Also, please note that the ``docker exec`` does not work for running management
When ``DEBUG`` is set to ``True``, the host is validated against ``['localhost', '127.0.0.1', '[::1]']``. This is adequate when running a ``virtualenv``. For Docker, in the ``config.settings.local``, add your host development server IP to ``INTERNAL_IPS`` or ``ALLOWED_HOSTS`` if the variable exists.
.._envs:
Configuring the Environment
---------------------------
This is the excerpt from your project's ``local.yml``: ::
This is the excerpt from your project's ``docker-compose.local.yml``: ::
# ...
@ -110,8 +115,8 @@ The most important thing for us here now is ``env_file`` section enlisting ``./.
.envs
├── .local
│ ├── .django
│ └── .postgres
│ ├── .django
│ └── .postgres
└── .production
├── .django
└── .postgres
@ -156,8 +161,8 @@ You have to modify the relevant requirement file: base, local or production by a
To get this change picked up, you'll need to rebuild the image(s) and restart the running container: ::
docker compose -f local.yml build
docker compose -f local.yml up
docker compose -f docker-compose.local.yml build
docker compose -f docker-compose.local.yml up
Debugging
~~~~~~~~~
@ -171,7 +176,7 @@ If you are using the following within your code to debug: ::
Then you may need to run the following for it to work as desired: ::
$ docker compose -f local.yml run --rm --service-ports django
$ docker compose -f docker-compose.local.yml run --rm --service-ports django
django-debug-toolbar
@ -188,7 +193,6 @@ The ``container_name`` from the yml file can be used to check on containers with
$ docker logs <project_slug>_local_celeryworker
$ docker top <project_slug>_local_celeryworker
Notice that the ``container_name`` is generated dynamically using your project slug as a prefix
Mailpit
@ -224,7 +228,7 @@ Prerequisites:
* ``use_docker`` was set to ``y`` on project initialization;
* ``use_celery`` was set to ``y`` on project initialization.
By default, it's enabled both in local and production environments (``local.yml`` and ``production.yml`` Docker Compose configs, respectively) through a ``flower`` service. For added security, ``flower`` requires its clients to provide authentication credentials specified as the corresponding environments' ``.envs/.local/.django`` and ``.envs/.production/.django````CELERY_FLOWER_USER`` and ``CELERY_FLOWER_PASSWORD`` environment variables. Check out ``localhost:5555`` and see for yourself.
By default, it's enabled both in local and production environments (``docker-compose.local.yml`` and ``docker-compose.production.yml`` Docker Compose configs, respectively) through a ``flower`` service. For added security, ``flower`` requires its clients to provide authentication credentials specified as the corresponding environments' ``.envs/.local/.django`` and ``.envs/.production/.django````CELERY_FLOWER_USER`` and ``CELERY_FLOWER_PASSWORD`` environment variables. Check out ``localhost:5555`` and see for yourself.
.._`Flower`: https://github.com/mher/flower
@ -238,46 +242,65 @@ The stack comes with a dedicated node service to build the static assets, watch
.._Sass: https://sass-lang.com/
.._live reloading: https://browsersync.io
Developing locally with HTTPS
-----------------------------
Increasingly it is becoming necessary to develop software in a secure environment in order that there are very few changes when deploying to production. Recently Facebook changed their policies for apps/sites that use Facebook login which requires the use of an HTTPS URL for the OAuth redirect URL. So if you want to use the ``users`` application with a OAuth provider such as Facebook, securing your communication to the local development environment will be necessary.
Using Just for Docker Commands
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In order to create a secure environment, we need to have a trusted SSL certificate installed in our Docker application.
We have included a ``justfile`` to simplify the use of frequent Docker commands for local development.
#. **Let's Encrypt**
..warning::
Currently, "Just" does not reliably handle signals or forward them to its subprocesses. As a result,
pressing CTRL+C (or sending other signals like SIGTERM, SIGINT, or SIGHUP) may only interrupt
"Just" itself rather than its subprocesses.
For more information, see `this GitHub issue <https://github.com/casey/just/issues/2473>`_.
The official line from Let’s Encrypt is:
First, install Just using one of the methods described in the `official documentation <https://just.systems/man/en/packages.html>`_.
[For local development section] ... The best option: Generate your own certificate, either self-signed or signed by a local root, and trust it in your operating system’s trust store. Then use that certificate in your local web server. See below for details.
Here are the available commands:
See `letsencrypt.org - certificates-for-localhost`_
- ``just build``
Builds the Python image using the local Docker Compose file.
Starts the containers in detached mode and removes orphaned containers.
#. **mkcert: Valid Https Certificates For Localhost**
- ``just down``
Stops the running containers.
`mkcert`_ is a simple by design tool that hides all the arcane knowledge required to generate valid TLS certificates. It works for any hostname or IP, including localhost. It supports macOS, Linux, and Windows, and Firefox, Chrome and Java. It even works on mobile devices with a couple manual steps.
- ``just prune``
Stops and removes containers along with their volumes. You can optionally pass an argument with the service name to prune a single container.
See https://blog.filippo.io/mkcert-valid-https-certificates-for-localhost/
- ``just logs``
Shows container logs. You can optionally pass an argument with the service name to view logs for a specific service.
Runs Django management commands within the container. Replace ``<command>`` with any valid Django management command, such as ``migrate``, ``createsuperuser``, or ``shell``.
After installing a trusted TLS certificate, configure your docker installation. We are going to configure an ``nginx`` reverse-proxy server. This makes sure that it does not interfere with our ``traefik`` configuration that is reserved for production environments.
These are the places that you should configure to secure your local environment.
(Optionally) Developing locally with HTTPS
------------------------------------------
certs
Nginx
~~~~~
Take the certificates that you generated and place them in a folder called ``certs`` in the project's root folder. Assuming that you registered your local hostname as ``my-dev-env.local``, the certificates you will put in the folder should have the names ``my-dev-env.local.crt`` and ``my-dev-env.local.key``.
If you want to add some sort of social authentication with a OAuth provider such as Facebook, securing your communication to the local development environment will be necessary. These providers usually require that you use an HTTPS URL for the OAuth redirect URL for the Facebook login to work appropriately.
local.yml
~~~~~~~~~
Here is a link to an article on `how to add HTTPS using Nginx`_ to your local docker installation. This also includes how to serve files from the ``media`` location, in the event that you are want to serve user-uploaded content.
#. Add the ``nginx-proxy`` service. ::
.._`how to add HTTPS using Nginx`: https://afroshok.com/cookiecutter-https
...
Webpack
~~~~~~~
If you are using Webpack, first install `mkcert`_. It is a simple by design tool that hides all the arcane knowledge required to generate valid TLS certificates. It works for any hostname or IP, including localhost. It supports macOS, Linux, and Windows, and Firefox, Chrome and Java. It even works on mobile devices with a couple manual steps. See https://blog.filippo.io/mkcert-valid-https-certificates-for-localhost/
These are the places that you should configure to secure your local environment. Take the certificates that you generated and place them in a folder called ``certs`` in the project's root folder. Configure an ``nginx`` reverse-proxy server as a ``service`` in the ``docker-compose.local.yml``. This makes sure that it does not interfere with our ``traefik`` configuration that is reserved for production environments.
Assuming that you registered your local hostname as ``my-dev-env.local``, the certificates you will put in the folder should have the names ``my-dev-env.local.crt`` and ``my-dev-env.local.key``.
1. Add the ``nginx-proxy`` service to the ``docker-compose.local.yml``. ::
nginx-proxy:
image: jwilder/nginx-proxy:alpine
@ -290,66 +313,28 @@ local.yml
- ./certs:/etc/nginx/certs
restart: always
depends_on:
- django
- node
environment:
- VIRTUAL_HOST=my-dev-env.local
- VIRTUAL_PORT=3000
...
2. Add the local secure domain to the ``config/settings/local.py``. You should allow the new hostname ::
#. Link the ``nginx-proxy`` to ``django`` through environment variables.
``django`` already has an ``.env`` file connected to it. Add the following variables. You should do this especially if you are working with a team and you want to keep your local environment details to yourself.
3. Add the following configuration to the ``devServer`` section of ``webpack/dev.config.js`` ::
::
client: {
webSocketURL: 'auto://0.0.0.0:0/ws', // note the `:0` after `0.0.0.0`
After setting up your environment, you're ready to add your first app. This project uses the setup from "Two Scoops of Django" with a two-tier layout:
- **Top Level Repository Root** has config files, documentation, `manage.py`, and more.
- **Second Level Django Project Root** is where your Django apps live.
- **Second Level Configuration Root** holds settings and URL configurations.
The project layout looks something like this: ::
<repository_root>/
├── config/
│ ├── settings/
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── local.py
│ │ └── production.py
│ ├── urls.py
│ └── wsgi.py
├── <django_project_root>/
│ ├── <name_of_the_app>/
│ │ ├── migrations/
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── models.py
│ │ ├── tests.py
│ │ └── views.py
│ ├── __init__.py
│ └── ...
├── requirements/
│ ├── base.txt
│ ├── local.txt
│ └── production.txt
├── manage.py
├── README.md
└── ...
Following this structured approach, here's how to add a new app:
#. **Create the app** using Django's ``startapp`` command, replacing ``<name-of-the-app>`` with your desired app name: ::
$ python manage.py startapp <name-of-the-app>
#. **Move the app** to the Django Project Root, maintaining the project's two-tier structure: ::
$ mv <name-of-the-app> <django_project_root>/
#. **Edit the app's apps.py** change ``name = '<name-of-the-app>'`` to ``name = '<django_project_root>.<name-of-the-app>'``.
#. **Register the new app** by adding it to the ``LOCAL_APPS`` list in ``config/settings/base.py``, integrating it as an official component of your project.
Setup Email Backend
-------------------
@ -164,7 +216,7 @@ The project comes with a simple task for manual testing purposes, inside `<proje
You can also use Django admin to queue up tasks, thanks to the `django-celerybeat`_ package.
.._Getting started with Redis guide: https://redis.io/docs/getting-started/
.._Getting started with Redis: https://redis.io/docs/getting-started/
pip install -r requirements/production.txt # may take a few minutes
..note:: We're creating the virtualenv using Python 3.10 (``--python=/usr/bin/python3.10```), although Cookiecutter Django generates a project for Python 3.11. This is because, at time of writing, PythonAnywhere only supports Python 3.10. It shouldn't be a problem, but if is, you may try changing the Python version to 3.11 and see if it works. If it does, please let us know, or even better, submit a pull request to update this section.
..note:: We're creating the virtualenv using Python 3.10 (``--python=/usr/bin/python3.10```), although Cookiecutter Django generates a project for Python 3.12. This is because, at time of writing, PythonAnywhere only supports Python 3.10. It shouldn't be a problem, but if is, you may try changing the Python version to 3.12 and see if it works. If it does, please let us know, or even better, submit a pull request to update this section.
Before you begin, check out the ``production.yml`` file in the root of this project. Keep note of how it provides configuration for the following services:
Before you begin, check out the ``docker-compose.production.yml`` file in the root of this project. Keep note of how it provides configuration for the following services:
* ``django``: your application running behind ``Gunicorn``;
* ``postgres``: PostgreSQL database with the application's relational data;
@ -55,7 +55,7 @@ You will probably also need to setup the Mail backend, for example by adding a `
..warning::
..include:: mailgun.rst
..include::../includes/mailgun.rst
Optional: Use AWS IAM Role for EC2 instance
@ -107,7 +107,7 @@ To solve this, you can either:
2. create a ``.env`` file in the root of the project with just variables you need. You'll need to also define them in ``.envs/.production/.django`` (hence duplicating them).
3. set these variables when running the build command::
..note:: For brevity it is assumed that you will be running the below commands against local environment, however, this is by no means mandatory so feel free to switch to ``production.yml`` when needed.
..note:: For brevity it is assumed that you will be running the below commands against local environment, however, this is by no means mandatory so feel free to switch to ``docker-compose.production.yml`` when needed.
Prerequisites
-------------
#. the project was generated with ``use_docker`` set to ``y``;
#. the stack is up and running: ``docker compose -f local.yml up -d postgres``.
#. the stack is up and running: ``docker compose -f docker-compose.local.yml up -d postgres``.
You can also get the container ID using ``docker compose -f local.yml ps -q postgres`` so if you want to automate your backups, you don't have to check the container ID manually every time. Here is the full command ::
You can also get the container ID using ``docker compose -f docker-compose.local.yml ps -q postgres`` so if you want to automate your backups, you don't have to check the container ID manually every time. Here is the full command ::
For uploading your backups to Amazon S3 you can use the aws cli container. There is an upload command for uploading the postgres /backups directory recursively and there is a download command for downloading a specific backup. The default S3 environment variables are used. ::
$ docker compose -f production.yml run --rm awscli upload
$ docker compose -f production.yml run --rm awscli download backup_2018_03_13T09_05_07.sql.gz
$ docker compose -f docker-compose.production.yml run --rm awscli upload
$ docker compose -f docker-compose.production.yml run --rm awscli download backup_2018_03_13T09_05_07.sql.gz
Remove Backup
----------------------------------
To remove backup you can use the ``rmbackup`` command. This will remove the backup from the ``/backups`` directory. ::
Upgrading PostgreSQL in your project requires a series of carefully executed steps. Start by halting all containers, excluding the postgres container. Following this, create a backup and proceed to remove the outdated data volume. ::
$ docker compose -f docker-compose.local.yml down
$ docker compose -f docker-compose.local.yml up -d postgres
$ docker compose -f docker-compose.local.yml run --rm postgres backup
$ docker compose -f docker-compose.local.yml down
$ docker volume rm my_project_postgres_data
..note:: Neglecting to remove the old data volume may lead to issues, such as the new postgres container failing to start with errors like ``FATAL: database files are incompatible with server``, and ``could not translate host name "postgres" to address: Name or service not known``.
To complete the upgrade, update the PostgreSQL version in the corresponding Dockerfile (e.g. ``compose/production/postgres/Dockerfile``) and build a new version of PostgreSQL. ::
You may notice that some elements of this project do not exactly match what we describe in chapter 3 of `Two Scoops of Django 1.11`_. The reason for that is this project, amongst other things, serves as a test bed for trying out new ideas and concepts. Sometimes they work, sometimes they don't, but the end result is that it won't necessarily match precisely what is described in the book I co-authored.
You may notice that some elements of this project do not exactly match what we describe in chapter 3 of `Two Scoops of Django 3.x`_. The reason for that is this project, amongst other things, serves as a test bed for trying out new ideas and concepts. Sometimes they work, sometimes they don't, but the end result is that it won't necessarily match precisely what is described in the book I co-authored.
.._Two Scoops of Django 1.11: https://www.feldroy.com/collections/django/products/two-scoops-of-django-1-11
.._Two Scoops of Django 3.x: https://www.feldroy.com/two-scoops-press#two-scoops-of-django
This document is intended for maintainers of the template.
## Automated updates
We use 2 separate services to keep our dependencies up-to-date:
- Dependabot, which manages updates of Python deps of the template, GitHub actions, npm packages and Docker images.
- PyUp, which manages the Python deps for the generated project.
We don't use Dependabot for the generated project deps because our requirements files are templated, and Dependabot fails to parse them. PyUp is -AFAIK- the only service out there that supports having Jinja tags in the requirements file.
Updates for the template should be labelled as `project infrastructure` while the ones about the generated project should be labelled as `update`. This is use to work in conjunction with our changelog script (see later).
## Automation scripts
We have a few workflows which have been automated over time. They usually run using GitHub actions and might need a few small manual actions to work nicely. Some have a few limitations which we should document here.
### CI
`ci.yml`
The CI workflow tries to cover 2 main aspects of the template:
- Check all combinations to make sure that valid files are generated with no major linting issues. Issues which are fixed by an auto-formatter after generation aren't considered major, and only aim for best effort. This is under the `test` job.
- Run more in-depth tests on a few combinations, by installing dependencies, running type checker and the test suite of the generated project. We try to cover docker (`docker` job) and non-docker (`bare` job) setups.
We also run the deployment checks, but we don't do much more beyond that for testing the production setup.
### Django issue checker
`django-issue-checker.yml`
This workflow runs daily, on schedule, and checks if there is a new major version of Django (not in the pure SemVer sense) released that we are not running, and list our dependencies compatibility.
For example, at time of writing, we use Django 4.2, but the latest version of Django is 5.0, so the workflow created a ["Django 5.0" issue](https://github.com/cookiecutter/cookiecutter-django/issues/4724) in GitHub, with a compatibility table and keeps it up to date every day.
#### Limitations
Here are a few current and past limitations of the script
- When a new dependency is added to the template, the script fails to update an existing issue
- Not sure what happens when a deps is removed
- ~~Unable to parse classifiers without minor version~~
- ~~Creates an issue even if we are on the latest version~~
### Issue manager
`issue-manager.yml`
A workflow that uses [Sebastian Ramirez' issue-manager](https://github.com/tiangolo/issue-manager) to help us automate issue management. The tag line from the repo explains it well:
> Automatically close issues or Pull Requests that have a label, after a custom delay, if no one replies back.
It runs on a schedule as well as when some actions are taken on issues and pull requests.
We wait 10 days before closing issues, and we have a few customised reasons, which are configured in the workflow itself. The config should be fairly self-explanatory.
### Pre-commit auto-update
`pre-commit-autoupdate.yml`
Run daily, to do `pre-commit autoupdate` on the template as well as the generated project, and opens a pull request with the changes.
#### Limitations
- The PR is open as GitHub action which means that CI does NOT run. The documentation for create-pull-request action [explains why](https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#triggering-further-workflow-runs).
- Some hooks are also installed as local dependencies (via `requirements/local.txt`), but these are updated separately via PyUP.
### Update changelog
`update-changelog.yml`
Run daily at 2AM to update our changelog and create a GitHub release. This runs a custom script which:
- List all pull requests merged the day before
- The release name is calendar based, so `YYYY.MM.DD`
- For each PR:
- Get the PR title to summarize the change
- Look at the PR labels to classify it in a section of the release notes:
- anything labelled `project infrastructure` is excluded
- label `update` goes in section "Updated"
- label `bug` goes in section "Fixed"
- label `docs` goes in section "Documentation"
- Default to section "Changed"
With that in mind, when merging changes, it's a good idea to set the labels and rename the PR title to give a good summary of the change, in the context of the changelog.
#### Limitations
- Dependabot updates for npm & Docker have a verbose title, try to rename them to be more readable: `Bump webpack-dev-server from 4.15.1 to 5.0.2 in /{{cookiecutter.project_slug}}` -> `Bump webpack-dev-server to 5.0.2`
- ~~Dependencies updates for the template repo (tox, cookiecutter, etc...) don't need to appear in changelog, and need to be labelled as `project infrastructure` manually. By default, they come from PyUp labelled as `update`.~~
### Update contributors
`update-contributors.yml`
Runs on each push to master branch. List the 5 most recently merged pull requests and extract their author. If any of the authors is a new one, updates the `.github/contributors.json`, regenerate the `CONTRIBUTORS.md` from it, and push back the changes to master.
#### Limitations
- If you merge a pull request from a new contributor, and merge another one right after, the push to master will fail as the remote will be out of date.
- If you merge more than 5 pull requests in a row like this, the new contributor might fail to be added.
uv run cookiecutter ../../ --no-input --overwrite-if-exists use_docker=y "$@"
cd my_awesome_project
# make sure all images build
docker compose -f local.yml build
docker compose -f docker-compose.local.yml build
# run the project's type checks
docker compose -f local.yml run django mypy my_awesome_project
docker compose -f docker-compose.local.yml run --rm django mypy my_awesome_project
# run the project's tests
docker compose -f local.yml run django pytest
docker compose -f docker-compose.local.yml run --rm django pytest
# return non-zero status code if there are migrations that have not been created
docker compose -f local.yml run django python manage.py makemigrations --dry-run --check ||{echo"ERROR: there were changes in the models, but migration listed above have not been created and are not saved in version control";exit 1;}
docker compose -f docker-compose.local.yml run --rm django python manage.py makemigrations --check ||{echo"ERROR: there were changes in the models, but migration listed above have not been created and are not saved in version control";exit 1;}
# Test support for translations
docker compose -f local.yml run django python manage.py makemessages --all
[](https://github.com/cookiecutter/cookiecutter-django/)
Moved to [settings](http://cookiecutter-django.readthedocs.io/en/latest/settings.html).
Moved to [settings](https://cookiecutter-django.readthedocs.io/en/latest/1-getting-started/settings.html).
## Basic Commands
@ -46,7 +46,7 @@ To run the tests, check your test coverage, and generate an HTML coverage report
### Live reloading and Sass CSS compilation
Moved to [Live reloading and SASS compilation](https://cookiecutter-django.readthedocs.io/en/latest/developing-locally.html#sass-compilation-live-reloading).
Moved to [Live reloading and SASS compilation](https://cookiecutter-django.readthedocs.io/en/latest/2-local-development/developing-locally.html#using-webpack-or-gulp).
{%- if cookiecutter.use_celery == "y" %}
@ -87,7 +87,7 @@ celery -A config.celery_app worker -B -l info
In development, it is often nice to be able to see emails that are being sent from your application. For that reason local SMTP server [Mailpit](https://github.com/axllent/mailpit) with a web interface is available as docker container.
Container mailpit will start automatically when you will run all docker containers.
Please check [cookiecutter-django Docker documentation](http://cookiecutter-django.readthedocs.io/en/latest/deployment-with-docker.html) for more details how to start all containers.
Please check [cookiecutter-django Docker documentation](https://cookiecutter-django.readthedocs.io/en/latest/2-local-development/developing-locally-docker.html) for more details how to start all containers.
With Mailpit running, to view messages that are sent by your application, open your browser and go to `http://127.0.0.1:8025`
{%- else %}
@ -130,14 +130,14 @@ The following details how to deploy this application.
### Heroku
See detailed [cookiecutter-django Heroku documentation](http://cookiecutter-django.readthedocs.io/en/latest/deployment-on-heroku.html).
See detailed [cookiecutter-django Heroku documentation](https://cookiecutter-django.readthedocs.io/en/latest/3-deployment/deployment-on-heroku.html).
{%- endif %}
{%- if cookiecutter.use_docker.lower() == "y" %}
### Docker
See detailed [cookiecutter-django Docker documentation](http://cookiecutter-django.readthedocs.io/en/latest/deployment-with-docker.html).
See detailed [cookiecutter-django Docker documentation](https://cookiecutter-django.readthedocs.io/en/latest/3-deployment/deployment-with-docker.html).
{%- endif %}
{%- if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] %}
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.