# Local Development

## Prerequisites

- Docker and Docker Compose
- Rust 1.91+
- [mise](https://mise.jdx.dev/) - Task runner and tool version manager
- [direnv](https://direnv.net/) (optional) - Auto-loads `.envrc`

## Development Stack

### Docker Compose Services

| Service | Port | Purpose |
|---------|------|---------|
| **postgres** | 5432 | PostgreSQL database |
| **dex** | 5556 | OAuth2/OIDC provider |
| **registry** | 5000 | Docker registry |
| **registry-ui** | 5001 | Registry web UI |

### Rise Backend

Single process running HTTP API server + controllers (deployment, project, ECR) as concurrent tokio tasks. Controllers enabled automatically based on config.

### Networking Setup

For comprehensive networking setup including Docker registry configuration, BuildKit network connectivity, Minikube configuration, and troubleshooting, see the **[Local Development Networking Guide](local-development.md)**.

Key topics covered:
- Name resolution (/etc/hosts configuration)
- Docker registry insecure access
- BuildKit network connectivity (`RISE_MANAGED_BUILDKIT_NETWORK_NAME`)
- Minikube host aliases and registry access
- Common networking issues and solutions

### Mise Tasks

- `mise docs:serve` - Serve docs (port 3001)
- `mise db:migrate` - Run migrations
- `mise backend:deps` - Start docker-compose services
- `mise backend:run` (alias: `mise br`) - Run backend
- `mise setup:hosts` - Configure `/etc/hosts` entries (idempotent)
- `mise setup:docker` - Configure Docker insecure registries (idempotent, skips if `/etc/docker` is unavailable)
- `mise minikube:up` - Start Minikube with local registry
- `mise minikube:down` - Stop and delete Minikube

## Quick Start

```bash
mise install
mise backend:run  # Starts services + backend
```

Services: http://localhost:3000 (API, Web UI), localhost:5432 (PostgreSQL), http://localhost:5000 (Registry)

### Registry Configuration for Local Development

When using Docker Compose with Minikube, you may need different registry URLs for:
- **Deployment controllers** (running in Minikube): `rise-registry:5000` (Docker internal network)
- **CLI** (running on host): `localhost:5000` (host network)

Configure this in `config/development.yaml`:

```yaml
registry:
  type: "oci-client-auth"
  registry_url: "rise-registry:5000"      # Internal URL for deployment controllers
  namespace: "rise-apps/"
  client_registry_url: "localhost:5000"   # Client-facing URL for CLI push operations
```

The `client_registry_url` is optional and defaults to `registry_url` if not specified. The API returns `client_registry_url` to CLI clients for push operations, while deployment controllers use `registry_url` for image references.

### Build CLI

```bash
cargo build --bin rise
```

## Environment Variables

`.envrc` (loaded by direnv): `DATABASE_URL`, `RISE_CONFIG_RUN_MODE`, `PATH`

Server config in `config/development.yaml` (or `config/production.yaml` with `RISE_CONFIG_RUN_MODE=production`).

## Development Workflow

### Making Changes

**Backend:**
```bash
# Edit code
mise backend:reload  # or: mise br
```

**Frontend (React + Vite):**
```bash
# Terminal 1
mise backend:run

# Terminal 2
mise frontend:dev
```

Open the app at `http://rise.local:3000` during development. The backend proxies frontend routes to Vite (`http://localhost:5173`) when `server.frontend_dev_proxy_url` is configured.
Run `mise setup:hosts` to add `rise.local` to `/etc/hosts` if needed.

**CLI:**
```bash
cargo build --bin rise
rise <command>
```

**Schema:**
```bash
sqlx migrate add <migration_name>
# Edit migration in migrations/
sqlx migrate run
cargo sqlx prepare  # Update query cache
```

## Local Kubernetes Development

For testing the Kubernetes controller locally, use Minikube:

```bash
mise minikube:up
```

This starts a local Kubernetes cluster with an embedded container registry. The backend will automatically deploy applications to Minikube when configured for Kubernetes.

For installation and advanced usage, see the [Minikube documentation](https://minikube.sigs.k8s.io/docs/start/).

### Accessing Database

```bash
# Using psql
docker-compose exec postgres psql -U rise -d rise

# Or connection string
psql postgres://rise:rise123@localhost:5432/rise
```

### Default Credentials

**PostgreSQL:** `postgres://rise:rise123@localhost:5432/rise`

**Dex:** `admin@example.com` / `dev@example.com` / `user@example.com` and `password`

## Code Style

- Avoid over-engineering; add abstractions only when needed
- Use `anyhow::Result` for application code, typed errors only when callers need specific handling
- Document non-obvious behavior and rationale
- Update docs when adding features

## Testing

```bash
cargo test
```

## Commit Messages

Use conventional commits: `feat:`, `fix:`, `docs:`, `refactor:`

## Deprecated API Endpoints

Endpoints listed here are kept for backward compatibility with older CLI versions. They should be removed in a future major release once all clients have migrated.

| Endpoint | Replacement | Deprecated in | Reason |
|----------|-------------|---------------|--------|
| `PATCH /api/v1/deployments/{deployment_id}/status` | `PATCH /api/v1/projects/{project_name}/deployments/{deployment_id}/status` | v0.18.0 | `deployment_id` is not globally unique — two projects can share the same timestamp-based ID, causing status updates to hit the wrong deployment |

## Troubleshooting

See [Troubleshooting](user-guide/troubleshooting.md) for common issues.

**Reset everything:**
```bash
docker-compose down -v
cargo clean
mise install
mise backend:run
```
