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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,11 @@ and then editing the results to include your name, email, and various configurat

First, get Cookiecutter. Trust me, it's awesome:

pip install "cookiecutter>=1.7.0"
uv tool install "cookiecutter>=1.7.0"

Now run it against this repo:

cookiecutter https://github.com/cookiecutter/cookiecutter-django
uvx cookiecutter https://github.com/cookiecutter/cookiecutter-django

You'll be prompted for some values. Provide them, then a Django project will be created for you.

Expand Down
58 changes: 38 additions & 20 deletions docs/2-local-development/developing-locally-docker.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,32 @@ Build the Stack

This can take a while, especially the first time you run this particular command on your development system::

$ docker compose -f docker-compose.local.yml build
docker compose -f docker-compose.local.yml build

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!

After we have created our initial image we nee to generate a lockfile for our dependencies.
Docker cannot write to the host system during builds, so we have to run the command to generate the lockfile in the container.
This is important for reproducible builds and to ensure that the dependencies are installed correctly in the container.
Updating the lockfile manually is normally not necessary when you add packages through `uv add <package_name>`.

docker compose -f docker-compose.local.yml run --rm django uv lock

This is done by running the following command: ::

docker compose -f docker-compose.local.yml run --rm django uv lock

To be sure we are on the right track we need to build our image again: ::

docker compose -f docker-compose.local.yml build




Before doing any git commit, `pre-commit`_ should be installed globally on your local machine, and then::

$ git init
$ pre-commit install
git init
pre-commit install

Failing to do so will result with a bunch of CI and Linter errors that can be avoided with pre-commit.

Expand All @@ -50,27 +68,27 @@ 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 docker-compose.local.yml up
docker compose -f docker-compose.local.yml up

You can also set the environment variable ``COMPOSE_FILE`` pointing to ``docker-compose.local.yml`` like this::

$ export COMPOSE_FILE=docker-compose.local.yml
export COMPOSE_FILE=docker-compose.local.yml

And then run::

$ docker compose up
docker compose up

To run in a detached (background) mode, just::

$ docker compose up -d
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
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
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.

Expand All @@ -79,8 +97,8 @@ Execute Management Commands

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: ::

$ docker compose -f docker-compose.local.yml run --rm django python manage.py migrate
$ docker compose -f docker-compose.local.yml run --rm django python manage.py createsuperuser
docker compose -f docker-compose.local.yml run --rm django python manage.py migrate
docker compose -f docker-compose.local.yml run --rm django python manage.py createsuperuser

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.
Expand Down Expand Up @@ -136,7 +154,7 @@ The three envs we are presented with here are ``POSTGRES_DB``, ``POSTGRES_USER``

One final touch: should you ever need to merge ``.envs/.production/*`` in a single ``.env`` run the ``merge_production_dotenvs_in_dotenv.py``: ::

$ python merge_production_dotenvs_in_dotenv.py
python merge_production_dotenvs_in_dotenv.py

The ``.env`` file will then be created, with all your production envs residing beside each other.

Expand All @@ -149,15 +167,15 @@ Activate a Docker Machine

This tells our computer that all future commands are specifically for the dev1 machine. Using the ``eval`` command we can switch machines as needed.::

$ eval "$(docker-machine env dev1)"
eval "$(docker-machine env dev1)"

Add 3rd party python packages
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To install a new 3rd party python package, you cannot use ``pip install <package_name>``, that would only add the package to the container. The container is ephemeral, so that new library won't be persisted if you run another container. Instead, you should modify the Docker image:
You have to modify the relevant requirement file: base, local or production by adding: ::
To install a new 3rd party python package, you cannot use ``uv add <package_name>``, that would only add the package to the container. The container is ephemeral, so that new library won't be persisted if you run another container. Instead, you should modify the Docker image:
You have to modify pyproject.toml and either add it to project.dependencies or to tool.uv.dev-dependencies by adding: ::

<package_name>==<package_version>
"<package_name>==<package_version>"

To get this change picked up, you'll need to rebuild the image(s) and restart the running container: ::

Expand All @@ -176,7 +194,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 docker-compose.local.yml run --rm --service-ports django
docker compose -f docker-compose.local.yml run --rm --service-ports django


django-debug-toolbar
Expand All @@ -190,8 +208,8 @@ docker

The ``container_name`` from the yml file can be used to check on containers with docker commands, for example: ::

$ docker logs <project_slug>_local_celeryworker
$ docker top <project_slug>_local_celeryworker
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

Expand Down Expand Up @@ -331,7 +349,7 @@ Assuming that you registered your local hostname as ``my-dev-env.local``, the ce

Rebuild your ``docker`` application. ::

$ docker compose -f docker-compose.local.yml up -d --build
docker compose -f docker-compose.local.yml up -d --build

Go to your browser and type in your URL bar ``https://my-dev-env.local``.

Expand Down
48 changes: 19 additions & 29 deletions docs/2-local-development/developing-locally.rst
Original file line number Diff line number Diff line change
@@ -1,37 +1,27 @@
Getting Up and Running Locally
==============================

.. index:: pip, virtualenv, PostgreSQL
.. index:: PostgreSQL


Setting Up Development Environment
----------------------------------

Make sure to have the following on your host:

* Python 3.12
* uv https://docs.astral.sh/uv/getting-started/installation/
* PostgreSQL_.
* Redis_, if using Celery
* Cookiecutter_

First things first.

#. Create a virtualenv: ::

$ python3.12 -m venv <virtual env path>

#. Activate the virtualenv you have just created: ::

$ source <virtual env path>/bin/activate

#. .. include:: generate-project-block.rst

#. Install development requirements: ::

$ cd <what you have entered as the project_slug at setup stage>
$ pip install -r requirements/local.txt
$ git init # A git repo is required for pre-commit to install
$ pre-commit install
cd <what you have entered as the project_slug at setup stage>
uv sync
git init # A git repo is required for pre-commit to install
uv run pre-commit install

.. note::

Expand All @@ -40,7 +30,7 @@ First things first.

#. Create a new PostgreSQL database using createdb_: ::

$ createdb --username=postgres <project_slug>
createdb --username=postgres <project_slug>

``project_slug`` is what you have entered as the project_slug at the setup stage.

Expand All @@ -54,7 +44,7 @@ First things first.

#. Set the environment variables for your database(s): ::

$ export DATABASE_URL=postgres://postgres:<password>@127.0.0.1:5432/<DB name given to createdb>
export DATABASE_URL=postgres://postgres:<password>@127.0.0.1:5432/<DB name given to createdb>

.. note::

Expand All @@ -71,15 +61,15 @@ First things first.

#. Apply migrations: ::

$ python manage.py migrate
uv run python manage.py migrate

#. If you're running synchronously, see the application being served through Django development server: ::

$ python manage.py runserver 0.0.0.0:8000
uv run python manage.py runserver 0.0.0.0:8000

or if you're running asynchronously: ::

$ uvicorn config.asgi:application --host 0.0.0.0 --reload --reload-include '*.html'
uv run uvicorn config.asgi:application --host 0.0.0.0 --reload --reload-include '*.html'

If you've opted for Webpack or Gulp as frontend pipeline, please see the :ref:`dedicated section <bare-metal-webpack-gulp>` below.

Expand Down Expand Up @@ -136,11 +126,11 @@ 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>
uv run 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>/
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>'``.

Expand All @@ -166,7 +156,7 @@ For instance, one of the packages we depend upon, ``django-allauth`` sends verif

#. Make it executable: ::

$ chmod +x mailpit
chmod +x mailpit

#. Spin up another terminal window and start it there: ::

Expand Down Expand Up @@ -199,18 +189,18 @@ If the project is configured to use Celery as a task scheduler then, by default,

Next, make sure `redis-server` is installed (per the `Getting started with Redis`_ guide) and run the server in one terminal::

$ redis-server
redis-server

Start the Celery worker by running the following command in another terminal::

$ celery -A config.celery_app worker --loglevel=info
uv run celery -A config.celery_app worker --loglevel=info

That Celery worker should be running whenever your app is running, typically as a background process,
so that it can pick up any tasks that get queued. Learn more from the `Celery Workers Guide`_.

The project comes with a simple task for manual testing purposes, inside `<project_slug>/users/tasks.py`. To queue that task locally, start the Django shell, import the task, and call `delay()` on it::

$ python manage.py shell
uv run python manage.py shell
>> from <project_slug>.users.tasks import get_users_count
>> get_users_count.delay()

Expand All @@ -231,11 +221,11 @@ If you've opted for Gulp or Webpack as front-end pipeline, the project comes con
#. Make sure that `Node.js`_ v18 is installed on your machine.
#. In the project root, install the JS dependencies with::

$ npm install
npm install

#. Now - with your virtualenv activated - start the application by running::

$ npm run dev
npm run dev

This will start 2 processes in parallel: the static assets build loop on one side, and the Django server on the other.

Expand Down
2 changes: 1 addition & 1 deletion docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXBUILD = uv run sphinx-build
SOURCEDIR = .
BUILDDIR = _build

Expand Down
Loading
Loading