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:

    $ cp .env.skel .env
    

    Edit the values. The minimum set is documented in Required environment variables.

  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:

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

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

    $ docker exec -it richy ./manage.py loaddata users
    

Required environment variables#

The minimum .env for the dev compose:

BASE_URL=https://richy.test
DOMAIN=richy.test
TZ=Europe/Prague

The full reference of supported environment variables and Django settings is in 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 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:

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

$ docker exec -it richy ./manage.py shell_plus

Open a database shell:

$ docker exec -it richy-db psql -U postgres richy

Recompile the frontend bundle (run after editing JS / SASS):

$ ./app/_scripts/webpack.sh

Tear everything down (containers + volumes):

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

$ docker exec -it richy ./manage.py shell_plus
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):

$ 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 Tasks.