# Dev Webapp

> Runs and troubleshoots local development for dotnet-vite-webapp-template apps using Docker Compose, including logs, restarts, migrations, ports, and env fixes. Use when the user invokes /dev-webapp, asks to start/stop the dev stack, debug compose issues, or fix CORS/JWT/DB connection problems.

- Skill: `manifold-works/dev-webapp` (Agent Skill)
- Install (CLI): `npx skillmds@latest add manifold-works/dev-webapp`
- Raw SKILL.md: https://api.skillmd.com/api/skills/manifold-works/dev-webapp/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: Manifold-Works (https://skillmd.com/u/manifold-works)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/manifold-works/dev-webapp

---


# Dev Webapp

Day-2 local development: Compose up/down, logs, env, common fixes.

**Read first:** [`~/.cursor/skills/webapp-shared/reference.md`](../webapp-shared/reference.md)

## Quick reference

| Service | Host URL | Internal |
|---------|----------|----------|
| Web (Vite) | http://localhost:5173 | `web:5173` |
| API | http://localhost:8080 | `api:8080` |
| Health | http://localhost:8080/api/health | — |
| Postgres | localhost:5432 | `db:5432` |

Env file: `.env` (from `.env.example`). Never commit `.env`.

## Checklist: start dev stack

```
Dev-webapp start:
- [ ] 1. .env exists with valid Jwt__SigningKey
- [ ] 2. docker compose up --build -d
- [ ] 3. docker compose ps (all healthy)
- [ ] 4. curl health + optional login
- [ ] 5. Open http://localhost:5173
```

```bash
cd <app-root>
cp -n .env.example .env    # if missing
# Ensure Jwt__SigningKey set via ./scripts/generate-jwt-key.sh
docker compose up --build -d
docker compose ps
curl -sf http://localhost:8080/api/health
```

First boot: API auto-applies EF migrations in Development.

## Checklist: stop / reset

```bash
# Stop containers (keep volumes)
docker compose down

# Stop + remove volumes (fresh DB)
docker compose down -v

# Rebuild single service after Dockerfile change
docker compose up -d --build api
docker compose up -d --build web
```

## Logs

```bash
docker compose logs -f              # all services
docker compose logs -f api          # API only
docker compose logs -f web          # Vite
docker compose logs -f db           # Postgres
docker compose logs api --tail 100  # recent API lines
```

Look for: migration applied, JWT config error, DB connection refused, CORS errors.

## Restart single service

```bash
docker compose restart api
docker compose restart web
docker compose restart db
```

After backend code changes, `api` with `dotnet watch` should hot-reload. If stuck, restart `api`.

## Host-side development (optional)

When not using Compose for app processes:

```bash
# Backend
cd backend && dotnet watch run --project src/{App}.Api

# Frontend
cd frontend && npm run dev
```

Ensure `.env` or user secrets match host connection string (`Host=localhost` not `Host=db`).

## Run tests locally

```bash
cd backend && dotnet test
cd frontend && npm ci && npm test -- --run && npm run build
```

Testcontainers needs Docker available to test runner.

## Common fixes

### JWT signing key error

```
Jwt:SigningKey must be set to a strong secret
```

```bash
./scripts/generate-jwt-key.sh
# Paste into .env → Jwt__SigningKey=...
docker compose up -d --force-recreate api
```

### CORS blocked in browser

- `Cors__Origins` in `.env` must include exact browser origin: `http://localhost:5173`
- No trailing slash mismatch
- Recreate api after env change: `docker compose up -d --force-recreate api`

### DB connection refused

```bash
docker compose ps db
docker compose logs db
# Wait for "database system is ready"
docker compose restart api
```

Check `ConnectionStrings__Default` uses `Host=db` inside Compose.

### Port already in use

```bash
# Find process on 5173 or 8080
ss -tlnp | grep -E '5173|8080'
# Stop conflicting process or adjust ports in docker-compose.override.yml
```

### Migrations out of sync

See `add-migration` skill:

```bash
cd backend
dotnet ef migrations add FixSchema ...
docker compose restart api
```

### Frontend cannot reach API

- Dev: Vite proxy in `vite.config.ts` should target `http://api:8080` in Docker or `http://localhost:8080` on host
- Browser calls go to Vite origin; proxy forwards `/api/*`

### Stale node_modules / dist

```bash
docker compose exec web npm ci
# or on host:
cd frontend && rm -rf node_modules dist && npm ci
```

## Verify auth flow manually

```bash
curl -sf http://localhost:8080/api/health
curl -X POST http://localhost:8080/api/auth/register \
  -H 'Content-Type: application/json' \
  -d '{"email":"dev@test.local","password":"Password1!"}'
```

Then test login/refresh in browser at `http://localhost:5173`.

## Do not

- Commit `.env`
- Set `ASPNETCORE_ENVIRONMENT=Production` for local dev unless testing prod behavior
- Expect prod Caddy in dev compose — Caddy is prod-only

## Related skills

- First-time scaffold → `create-webapp`
- Schema changes → `add-migration`
- Production → `deploy-webapp`

