Local setup
===========
The project ships with a Docker Compose configuration for development
(``compose.dev.yaml``). All services run in containers; no Python or
Node tooling is required on the host.
Prerequisites
-------------
* `Docker `_ with the Compose
plugin (``docker compose ...``).
* A POSIX shell (the helper scripts under ``app/_scripts/`` are
``sh`` / ``bash``).
If you also want to run the app outside Docker:
* Python ``>= 3.13``
* `uv `_
First-time setup
----------------
1. Clone the repository and step inside it.
2. Copy the environment skeleton:
.. code-block:: bash
$ cp .env.skel .env
Edit the values. The minimum set is documented in :ref:`required-env`.
3. (Optional) Drop a database dump named ``dump.sql`` into the project
root. The dev compose file mounts it as a Postgres bootstrap script,
so the schema and data are imported on the first ``db`` start.
4. Build images and start the stack:
.. code-block:: bash
$ docker compose -f compose.dev.yaml up --build
The first build pulls images and installs ``requirements_dev``;
subsequent runs reuse the cached image.
5. Wait for the ``richy`` container to become *healthy*. Tail its logs
to follow startup:
.. code-block:: bash
$ docker logs -f richy
6. Open the app at https://richy.test (or the ``BASE_URL`` you set).
Login with ``admin@test.com`` / ``test`` once the users fixture is
loaded:
.. code-block:: bash
$ docker exec -it richy ./manage.py loaddata users
.. _required-env:
Required environment variables
------------------------------
The minimum ``.env`` for the dev compose:
.. code-block:: ini
BASE_URL=https://richy.test
DOMAIN=richy.test
TZ=Europe/Prague
The full reference of supported environment variables and Django
settings is in :doc:`/architecture/settings`.
Services
--------
``compose.dev.yaml`` brings up:
* ``richy`` -- the Django app under Gunicorn (with reload).
* ``worker``, ``worker_slow``, ``worker_fast`` -- one Celery worker
per queue. See :doc:`/architecture/tasks` for the queue model.
* ``redis`` -- broker + cache.
* ``db`` -- PostgreSQL 16.
* ``nginx`` -- reverse proxy + TLS termination on
``localhost:80`` / ``localhost:443``.
* ``flower`` -- Celery monitor at http://localhost:5555.
* ``webpack`` -- frontend bundler (run on demand, see below).
Common tasks
------------
Apply migrations:
.. code-block:: bash
$ docker exec -it richy ./manage.py migrate
Open a Django shell. ``shell_plus`` (from
`django-extensions `_)
is preferred over the stock ``shell`` -- it auto-imports every
project model and uses IPython when available:
.. code-block:: bash
$ docker exec -it richy ./manage.py shell_plus
Open a database shell:
.. code-block:: bash
$ docker exec -it richy-db psql -U postgres richy
Recompile the frontend bundle (run after editing JS / SASS):
.. code-block:: bash
$ ./app/_scripts/webpack.sh
Tear everything down (containers + volumes):
.. code-block:: bash
$ docker compose -f compose.dev.yaml down -v
Triggering Celery tasks
-----------------------
The dev compose file starts the three workers automatically, but it
**does not** start ``beat`` -- so periodic tasks do not auto-fire in
dev. This is intentional: most local work doesn't need the schedule,
and keeping beat off avoids hammering external APIs.
Fire a single task on demand from a shell:
.. code-block:: bash
$ docker exec -it richy ./manage.py shell_plus
.. code-block:: python
from richy.shares import tasks
tasks.fetch_current_price.delay()
Run beat manually as a one-off (when you actually need the
periodic schedule to fire):
.. code-block:: bash
$ docker compose -f compose.dev.yaml run --rm worker \
celery -A richy beat -l info -S django --pidfile=
The full schedule, queue routing, and worker invocation flags are
documented in :doc:`/architecture/tasks`.