---
title: Local Setup
tags: [development]
---

# Local Setup

This guide walks you through running both repositories of the marketplace stack on your workstation. The platform is split into two services:

- **Backend** — Node.js 22+ / Express 5 / MongoDB 8 / Redis 8 / Socket.IO, served on port `5001`.
- **Frontend** — Next.js 16 / React 19 / MUI v7, served on port `8083` (or `3000` in Docker dev).

By the end of this page you will have the API running locally with MongoDB + Redis containers, a seeded set of test accounts, and the Next.js dashboard talking to it through your browser. For ongoing reference see [[Environment Variables]], [[Project Structure]], and [[Scripts]].

---

## 1. Prerequisites

Install the following before you start:

| Tool | Version | Why |
|------|---------|-----|
| Node.js | `>= 22` (backend), `>= 20` (frontend) | Runtime |
| Yarn | `1.22.22` (Classic) | Pinned via `packageManager` field |
| Docker Desktop | latest | Runs MongoDB + Redis + (optionally) backend/frontend |
| Git | `>= 2.40` | SSH-based clone from Gitea |
| OpenSSL | system default | For generating local secrets |
| `ngrok` (optional) | latest | For webhook testing — see [[Scripts#start-ngrok-sh]] |

> [!tip] Use a single Node version manager (`nvm`, `fnm`, or `volta`) and pin to `22`. Yarn Classic is required — do **not** upgrade to Berry, the lockfiles are incompatible.

You also need an SSH key registered with Gitea. The Git server runs on a non-standard port (`222`), so add an entry to `~/.ssh/config`:

```ssh
Host git.manko.yoga
  HostName git.manko.yoga
  Port 222
  User git
  IdentityFile ~/.ssh/id_ed25519
```

Verify connectivity:

```bash
ssh -T git@git.manko.yoga -p 222
```

You should see a Gitea welcome line. If you see "Permission denied (publickey)", upload your public key to your Gitea profile first.

---

## 2. Clone the repos

The two repos are siblings — keep them next to each other (the production compose file references `../frontend` from the backend folder):

```bash
mkdir -p ~/code && cd ~/code

git clone ssh://git@git.manko.yoga:222/nick/backend.git
git clone ssh://git@git.manko.yoga:222/nick/frontend.git
```

Switch each repo to the active integration branch for the stack you are testing. As of 2026-05-31, the dev stack work is on `integrate-main-into-development`:

```bash
cd ~/code/backend  && git checkout integrate-main-into-development
cd ~/code/frontend && git checkout integrate-main-into-development
```

> [!warning] `main`/`master` is the production branch and is consumed by the Watchtower auto-update flow. Never push WIP commits there. See [[Git Workflow]].

---

## 3. Install dependencies

Backend uses **npm** for scripts but `yarn install` for lockfile parity with Docker, while the frontend is pure Yarn:

```bash
# Backend
cd ~/code/backend
yarn install --frozen-lockfile

# Frontend
cd ~/code/frontend
yarn install --frozen-lockfile
```

Both installs take 2–5 minutes on a cold cache. If `node-gyp`/`sharp` fail on macOS, install Xcode CLT (`xcode-select --install`).

---

## 4. Configure `.env` files

Each repo ships example files. Copy them and fill in secrets — full reference is in [[Environment Variables]].

### Backend (`/Users/mojtabaheidari/code/backend/.env.local`)

`docker-compose.dev.yml` reads `.env.local`. The container expects at minimum:

```bash
NODE_ENV=development
PORT=5001
MONGODB_URI=mongodb://mongodb:27017
DB_NAME=marketplace
REDIS_URI=redis://redis:6379
JWT_SECRET=$(openssl rand -hex 32)
JWT_EXPIRES_IN=1h
REFRESH_TOKEN_EXPIRES_IN=30d
FRONTEND_URL=http://localhost:8083
MAX_FILE_SIZE=10485760
UPLOAD_PATH=/app/uploads
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100
```

For payments, OpenAI, SMTP, etc., refer to [[Environment Variables]].

### Frontend

Three env files already exist; pick the one that matches your scenario:

| File | When to use |
|------|-------------|
| `.env.local` | Local Next dev (`yarn dev`) — points at `http://localhost:5001` |
| `.env.development` | Docker compose dev — points at `dev.amn.gg` via Nginx |
| `.env.production` | Production build — points at `amn.gg` |

Next.js automatically picks `.env.local` for `next dev`. Do **not** check this file in if you change secrets.

---

## 5. Start the backend

You have two equivalent paths.

### Option A — All-in-Docker (recommended)

Builds the backend image, brings up MongoDB + Redis + backend on `nickapp-network`, and mounts `./src` for hot reload:

```bash
cd ~/code/backend
npm run docker:dev
```

Follow logs:

```bash
npm run docker:dev:logs
```

Stop:

```bash
npm run docker:dev:down
```

### Option B — Local Node + Docker datastores

Run only the datastores in Docker and the API on the host:

```bash
cd ~/code/backend
docker compose -f docker-compose.dev.yml up -d mongodb redis
npm run dev      # ts-node + nodemon on port 5001
```

Override `MONGODB_URI=mongodb://localhost:27017` in `.env` if you take this route, since `mongodb` only resolves inside the compose network.

> [!tip] If port `5001` is already in use, set `PORT=5002` in `.env.local` and update `NEXT_PUBLIC_API_URL` in the frontend env to match.

---

## 6. Seed test data

Once MongoDB is healthy, populate it with default users, categories, addresses, and templates:

```bash
cd ~/code/backend
npm run seed:all          # users + addresses (clears existing)
npm run seed:categories   # marketplace taxonomy
```

`seed:all` creates the canonical test accounts (password `Moji6364` for all):

| Role | Email |
|------|-------|
| Admin | `admin@marketplace.com` |
| Buyer | `buyer@marketplace.com` |
| Seller | `seller@marketplace.com` |
| Seller (alt) | `seller2@marketplace.com` |

You can also enable auto-seeding on container start by adding `AUTO_SEED_ON_START=true` to `.env.local`. Auto-seed runs only when the `users` collection has no non-admin entries — safe to leave on.

See [[Scripts#seed-scripts]] for the full list (`seed:users`, `seed:addresses`, `seed:categories`, `seed:all`, plus `createSupportUser.ts`, `createTestRequest.ts`, etc.).

---

## 7. Start the frontend

```bash
cd ~/code/frontend
yarn dev
```

Next.js starts on **port 8083** (`next dev -p 8083 --turbopack`). The dashboard is at:

- http://localhost:8083 — landing
- http://localhost:8083/auth/jwt/sign-in — login
- http://localhost:8083/dashboard — authenticated area

If you used the Docker compose dev workflow with the production-mode container, port `3000` may also be exposed; check the compose output.

---

## 8. Verify

Run these smoke checks before you start coding:

```bash
# Backend health (should return JSON with success: true)
curl -s http://localhost:5001/health | jq .

# API root
curl -s http://localhost:5001/ | jq .

# Login (returns JWT)
curl -s -X POST http://localhost:5001/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"admin@marketplace.com","password":"Moji6364"}' | jq .
```

In the browser, open http://localhost:8083, log in with `admin@marketplace.com / Moji6364`, and confirm the dashboard loads. If chat or notification badges show up, sockets connected too.

> [!tip] Tail backend logs in a separate terminal: `npm run docker:dev:logs`. Look for `✅ Connected to MongoDB`, `🔌 User connected`, and `🚀 Server running on port 5001`.

---

## 9. Common issues

| Symptom | Fix |
|---------|-----|
| `EADDRINUSE :::5001` | Another process owns the port — `lsof -i :5001` then `kill`, or change `PORT`. |
| `MongoServerError: Authentication failed` | The compose file does **not** set Mongo auth in dev; remove any `user:pass@` prefix from `MONGODB_URI`. |
| `ECONNREFUSED 127.0.0.1:6379` | Redis container is down — `docker compose -f docker-compose.dev.yml ps` to check. |
| CORS errors in the browser | `FRONTEND_URL` in backend `.env.local` must exactly match the origin you open in the browser (scheme + host + port). |
| `yarn install` hangs on `sharp` | Run `yarn config set network-timeout 600000` and retry. |
| `next dev` fails with module-not-found after a `git pull` | Run `yarn install` again — Next 16 is sensitive to drift in `react`/`react-dom`. |
| Sockets do not connect | Confirm `NEXT_PUBLIC_SOCKET_URL` matches the backend origin and that no browser extension blocks WebSockets. |

---

## 10. Quick reset

If your local state gets weird, the backend ships a one-shot reset script:

```bash
cd ~/code/backend
./scripts/reset-server.sh
```

This stops the dev compose stack, restarts it, runs health checks against MongoDB / Redis / `/health`, and probes the login endpoint with the seeded admin user. Output is colourised and ends with the canonical test credentials. See [[Scripts#reset-server-sh]] for details.

> [!warning] `reset-server.sh` does **not** drop volumes by default. To wipe the database, uncomment the `down -v` line in the script or run `docker compose -f docker-compose.dev.yml down -v` first.

---

## Next steps

- Walk the codebase via [[Project Structure]].
- Read [[Coding Standards]] before opening your first PR.
- Run the test suites — [[Testing]].
- Inspect what runs in each container — [[Docker Setup]] (Operations).
- For shipping changes through CI, see [[CI-CD Pipeline]] (Operations).
