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: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ uv sync
uv run poe check
```

On Linux, install the Docker Compose plugin before using any of the `docker compose` commands; see [Linux prerequisites](docs/getting-started/installation.md#linux-prerequisites).

Frontend dependencies live in `ezrules/frontend/`.

```bash
Expand All @@ -163,7 +165,7 @@ npm install
npm start
```

See [docs/contributing.md](docs/contributing.md) for contribution guidance.
See [docs/contributing.md](docs/contributing.md) for contribution guidance, including local Playwright setup.

## License

Expand Down
60 changes: 59 additions & 1 deletion docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ If you already know the project, use this checklist:

1. Fork and clone
2. `uv sync`
3. Initialize test DB
3. Start infrastructure and initialize the DB
4. Create branch
5. Implement change + tests
6. Run checks:
Expand All @@ -29,12 +29,18 @@ git remote add upstream https://github.com/sofeikov/ezrules.git

## 2) Set Up Development Environment

On Linux, install the Docker Compose plugin first; see [Installation: Linux prerequisites](getting-started/installation.md#linux-prerequisites).

```bash
uv sync
docker compose up -d postgres redis mailpit
uv run ezrules init-db --auto-delete
uv run ezrules bootstrap-org --name test_org --admin-email admin@test_org.com --admin-password 12345678
docker compose up -d worker beat
```

Start the `worker` and `beat` containers only after `init-db` has created the database; otherwise they exit with `database "ezrules" does not exist`. See [Installation: Path 3](getting-started/installation.md#path-3-development-contributing-to-the-project) for the `EZRULES_APP_SECRET` difference between `settings.env` and `docker-compose.yml`.

When validating migrations directly (without re-initializing the full DB), apply the current head:

```bash
Expand Down Expand Up @@ -88,6 +94,58 @@ uv run pytest tests/test_api_v2_rules.py -v
uv run pytest tests/test_api_v2_rules.py::test_create_rule_success -v
```

### Run a disposable local stack

`scripts/start-agent-stack.sh` starts the API and the Angular dev server on random high ports against a private database (`ezrules_e2e_<suffix>`), and writes the matching URLs and env vars to `.env.agent-stack`:

The script needs the frontend dependencies, so install them once first:

```bash
cd ezrules/frontend && npm install && cd ../..
docker compose up -d postgres redis mailpit
./scripts/start-agent-stack.sh && source .env.agent-stack && ./scripts/verify-stack.sh
Comment thread
sofeikov marked this conversation as resolved.
```

Open `${FRONTEND_URL}/login` in a browser. The script's help text uses the macOS `open` command; on Linux use `xdg-open`:

```bash
xdg-open "${FRONTEND_URL}/login"
```

Stop the stack with `./scripts/stop-agent-stack.sh`.

### Run Playwright E2E tests locally

CI installs the Playwright browser on its own, but a local checkout has none. After `npm install` in `ezrules/frontend`, download Chromium:

```bash
cd ezrules/frontend
npx playwright install chromium
```

On Linux, the browser also needs system libraries. Install them once; the command runs `apt-get` through `sudo` and asks for your password:

```bash
npx playwright install-deps chromium
```

On macOS and Windows this step is not needed.

!!! note "Unsupported Linux distributions"
`install-deps` only knows the distributions that the installed Playwright version supports. Playwright 1.58 does not support Ubuntu 26.04, so `install-deps` stops with `Cannot install dependencies for ubuntu26.04-x64`. On such systems, either install the missing libraries with your package manager (Playwright lists them in a `Host system is missing dependencies to run browsers` error when it cannot launch Chromium), or run the tests on a supported distribution or in a container such as the official `mcr.microsoft.com/playwright` image.

Then run the tests against a running stack. With the disposable stack above, `source .env.agent-stack` sets `E2E_BASE_URL` and `E2E_API_BASE_URL`:

The disposable stack starts the API with `EZRULES_TESTING=true`, which skips SMTP sends, so the invite and password-reset specs in `auth-email-flows.spec.ts` would time out waiting for Mailpit. Exclude them when running against this stack:

```bash
source .env.agent-stack
Comment thread
sofeikov marked this conversation as resolved.
cd ezrules/frontend
npm run test:e2e -- --grep-invert "Auth Email Flows"
```
Comment thread
sofeikov marked this conversation as resolved.

To run the full suite, including the email flows, start the API yourself with `EZRULES_TESTING=false` and Mailpit SMTP (`EZRULES_SMTP_HOST=localhost`, `EZRULES_SMTP_PORT=1025`, `EZRULES_FROM_EMAIL=...`), as described in [`ezrules/frontend/e2e/README.md`](https://github.com/sofeikov/ezrules/blob/main/ezrules/frontend/e2e/README.md).

---

## 5) Code and Test Expectations
Expand Down
89 changes: 82 additions & 7 deletions docs/getting-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,47 @@

Choose the path that fits your goal.

All three paths need Docker with the Compose plugin. On Linux, read [Linux prerequisites](#linux-prerequisites) first: most distributions do not install Compose together with Docker.

---

## Linux prerequisites

Docker Desktop (macOS, Windows) already includes Compose and Buildx. On Linux, the Docker engine and its plugins are separate packages.

**Docker Compose plugin.** Ubuntu's `docker.io` package does not include Compose, so `docker compose` fails with `unknown command`. Install the plugin:

```bash
# Ubuntu's own packages (docker.io)
sudo apt install docker-compose-v2

# Docker's apt repository (docker-ce)
sudo apt install docker-compose-plugin
```

Check it with `docker compose version`.

**Buildx (optional).** Without Buildx every build prints `Docker Compose is configured to build using Bake, but buildx isn't installed`. Builds still work. To remove the warning, install `docker-buildx` (Ubuntu packages) or `docker-buildx-plugin` (Docker's apt repository).

**Running Docker without `sudo`.** With the standard (rootful) daemon, add your user to the `docker` group, then log out and back in:

```bash
sudo usermod -aG docker "$USER"
```

Rootless Docker works as-is: the published ports (`4200`, `8888`, `5432`, `6379`, `8025`) are reachable on `localhost`. Rootless containers stop when you log out unless lingering is enabled for your user:

```bash
sudo loginctl enable-linger "$USER"
```

**Ports already in use.** The compose files publish PostgreSQL on `5432` and Redis on `6379`. If PostgreSQL or Redis is already installed from apt and running, the containers cannot start. See [Appendix B](#appendix-b-manual-postgresql-setup-without-docker) and [Troubleshooting](../troubleshooting.md#port-5432-or-6379-is-already-in-use).

---

## Path 1 — Demo (exploring the product)

**Prerequisites:** Docker + Docker Compose, Git.
**Prerequisites:** Docker + Docker Compose, Git. On Linux, see [Linux prerequisites](#linux-prerequisites).

```bash
git clone https://github.com/sofeikov/ezrules.git
Expand Down Expand Up @@ -36,7 +72,7 @@ docker compose -f docker-compose.demo.yml up --build

## Path 2 — Single-Host Production Validation

**Prerequisites:** Docker + Docker Compose, Git.
**Prerequisites:** Docker + Docker Compose, Git. On Linux, see [Linux prerequisites](#linux-prerequisites).

```bash
git clone https://github.com/sofeikov/ezrules.git
Expand Down Expand Up @@ -76,7 +112,7 @@ docker compose -f docker-compose.prod.yml down

## Path 3 — Development (contributing to the project)

**Prerequisites:** Python 3.12+, `uv`, Docker + Docker Compose, Git, Node 20+ (for frontend work).
**Prerequisites:** Python 3.12+, `uv`, Docker + Docker Compose, Git, Node 20+ (for frontend work). On Linux, see [Linux prerequisites](#linux-prerequisites).

### 1) Clone and install

Expand All @@ -89,11 +125,14 @@ uv sync
### 2) Start infrastructure

```bash
docker compose up -d
docker compose up -d postgres redis mailpit
```

This starts PostgreSQL, Redis, the Celery worker, and Celery beat. The API and frontend run as local processes.
It also starts Mailpit for local email capture on `http://localhost:8025`.
This starts PostgreSQL, Redis, and Mailpit (local email capture on `http://localhost:8025`). The API and frontend run as local processes.
The Celery worker and Celery beat are started in step 4, after the database exists.

!!! warning "Do not start the worker and beat yet"
A bare `docker compose up -d` also starts the `worker` and `beat` containers. They connect to the `ezrules` database, which does not exist until `ezrules init-db` runs, so both exit with `database "ezrules" does not exist`. They have no restart policy and stay down. If this already happened, run `docker compose up -d` again after step 4.

### 3) Configure `settings.env`

Expand All @@ -109,13 +148,28 @@ EZRULES_AI_AUTHORING_MODEL=gpt-4.1-mini
EZRULES_AI_AUTHORING_API_KEY=provider-api-key
```

The `worker` and `beat` containers do not read `settings.env`. `docker-compose.yml` sets their environment directly:

- `EZRULES_DB_ENDPOINT=postgresql://postgres:root@postgres:5432/ezrules` (the database name `ezrules` is fixed)
- `EZRULES_APP_SECRET=put_your_own_secret_here`

The `settings.env` in the repository uses `EZRULES_APP_SECRET=dev_secret`, so by default the local API and the Celery containers use different secrets. Stored notification channel settings and organisation-specific AI provider credentials are encrypted with `EZRULES_APP_SECRET`. Values that the API encrypts with one secret cannot be decrypted by worker tasks that use the other (for example, alert notification delivery). If you use those features locally, set the same value in both places, and keep the database name `ezrules` unless you also change `docker-compose.yml`.

### 4) Initialize database and bootstrap the first organisation

```bash
uv run ezrules init-db
uv run ezrules bootstrap-org --name your-org --admin-email admin@example.com --admin-password admin
```

Now that the database exists, start the Celery worker and beat:

```bash
docker compose up -d worker beat
```

Check that they are running with `docker compose ps`. If either shows `Exited`, read its log with `docker compose logs worker`.

`init-db` creates the target database (if missing), applies Alembic migrations, and initializes the global permission action catalogue.
`bootstrap-org` creates the organisation, seeds default roles and user lists, and creates the first admin user.
It does not create any outcomes or labels; add those through the UI or API for each environment.
Expand All @@ -140,6 +194,7 @@ npm start
```

Open [http://localhost:4200](http://localhost:4200).
On Linux, if `npm start` fails with `ENOSPC: System limit for number of file watchers reached`, see [Troubleshooting](../troubleshooting.md#angular-dev-server-fails-with-enospc-linux).
For invitation/password-reset email testing, open [http://localhost:8025](http://localhost:8025).

---
Expand Down Expand Up @@ -184,27 +239,47 @@ If `uv` is missing:

## Appendix B: Manual PostgreSQL Setup (Without Docker)

The rest of this guide assumes the endpoint `postgresql://postgres:root@localhost:5432/ezrules`. Either give the `postgres` user the password `root`, as shown below, or change `EZRULES_DB_ENDPOINT` in `settings.env` to match your server.
Comment thread
sofeikov marked this conversation as resolved.

!!! warning "Do not run both a system PostgreSQL and the compose PostgreSQL"
A PostgreSQL server installed with Homebrew or apt listens on `5432`, the same port that `docker-compose.yml` publishes. If both are present, `docker compose up` fails with a port conflict, or the API connects to the server you did not mean to use. Use one or the other. The same applies to a Redis server (for example apt's `redis-server`) on `6379`. To switch back to the compose services on Ubuntu/Debian, stop the system services first:

```bash
sudo systemctl disable --now postgresql redis-server
```

=== "macOS"

```bash
brew install postgresql@16
brew services start postgresql@16
"$(brew --prefix postgresql@16)/bin/psql" postgres \
-c "CREATE ROLE postgres WITH LOGIN SUPERUSER PASSWORD 'root';"
```

Homebrew's cluster has no `postgres` role; its superuser is your macOS user, without a password. The last command creates the `postgres` role the default endpoint expects. `postgresql@16` is keg-only, so `psql` is called by its full path.

=== "Ubuntu/Debian"

```bash
sudo apt update
sudo apt install postgresql postgresql-contrib
sudo systemctl start postgresql
sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'root';"
```

For backtesting and other Celery work, also install Redis:

```bash
sudo apt install redis-server
```

=== "Docker single container"

```bash
docker run -d \
--name ezrules-postgres \
-e POSTGRES_PASSWORD=yourpassword \
-e POSTGRES_PASSWORD=root \
-e POSTGRES_USER=postgres \
-p 5432:5432 \
postgres:16
Expand Down
Loading
Loading