Add setup and deployment guide, env example files
- Rewrote README.md with full step-by-step setup guide covering Docker Compose deployment, environment configuration, port reference, local dev setup, and reset instructions - Added backend/.env.example and frontend/.env.local.example so new deployers know exactly what to configure without any secrets committed - Updated .gitignore to allow .env.example files through Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4b98219bf7
commit
4c6335d316
5 changed files with 275 additions and 66 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -18,6 +18,9 @@ __pycache__/
|
|||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
# But do commit example templates
|
||||
!.env.example
|
||||
!.env.local.example
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
|
|
|
|||
288
README.md
288
README.md
|
|
@ -1,89 +1,229 @@
|
|||
# DemoBMS
|
||||
# BMS — Data Centre Infrastructure Management
|
||||
|
||||
Intelligent Data Center Infrastructure Management platform.
|
||||
A full-stack DCIM platform with live sensor dashboards, alarm management, power/cooling monitoring, and simulated sensor bots.
|
||||
|
||||
## Stack
|
||||
|
||||
- **Frontend:** Next.js 16 + TypeScript + shadcn/ui + Recharts
|
||||
- **Backend:** Python FastAPI
|
||||
- **Database:** PostgreSQL + TimescaleDB
|
||||
- **Auth:** Clerk
|
||||
- **Runtime:** Docker Compose
|
||||
**Stack:** Next.js 16 · FastAPI · PostgreSQL + TimescaleDB · MQTT (Mosquitto) · Docker Compose
|
||||
|
||||
---
|
||||
|
||||
## Ports
|
||||
## Table of Contents
|
||||
|
||||
| Service | Port |
|
||||
|----------|------|
|
||||
| Frontend | 5646 |
|
||||
| Backend | 8000 (internal — not exposed publicly) |
|
||||
| Database | 5432 (internal) |
|
||||
|
||||
The frontend is the only service that needs to be reachable. Point your reverse proxy at port **5646**.
|
||||
1. [Prerequisites](#prerequisites)
|
||||
2. [Quick Start — Docker Compose](#quick-start--docker-compose)
|
||||
3. [Environment Variables](#environment-variables)
|
||||
4. [Verify Everything Is Running](#verify-everything-is-running)
|
||||
5. [Accessing the App](#accessing-the-app)
|
||||
6. [Ports Reference](#ports-reference)
|
||||
7. [Local Development (without Docker)](#local-development-without-docker)
|
||||
8. [Project Structure](#project-structure)
|
||||
9. [Stopping & Resetting](#stopping--resetting)
|
||||
|
||||
---
|
||||
|
||||
## API Calls & Reverse Proxy
|
||||
## Prerequisites
|
||||
|
||||
The frontend never hardcodes a backend hostname. All API calls use the relative path `/api/backend/*`, which Next.js rewrites to the backend on the internal Docker network (`BACKEND_INTERNAL_URL`). From the browser's perspective everything is same-origin — your reverse proxy only needs to forward to port 5646.
|
||||
| Requirement | Minimum version | Check |
|
||||
|---|---|---|
|
||||
| Docker | 24+ | `docker --version` |
|
||||
| Docker Compose | v2 (bundled with Docker Desktop / Engine) | `docker compose version` |
|
||||
| Git | any | `git --version` |
|
||||
|
||||
```
|
||||
Browser → Reverse Proxy → :5646 (Next.js)
|
||||
↓ server-side rewrite
|
||||
:8000 (FastAPI) — internal only
|
||||
```
|
||||
That's it for the Docker path — Node and Python are **not** needed on the host.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
## Quick Start — Docker Compose
|
||||
|
||||
### 1. Configure Clerk (required for auth)
|
||||
### 1. Clone the repo
|
||||
|
||||
Create a free account at https://clerk.com, create an application, then fill in the keys:
|
||||
|
||||
**`frontend/.env.local`**
|
||||
```
|
||||
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
|
||||
CLERK_SECRET_KEY=sk_test_...
|
||||
```bash
|
||||
git clone https://git.rdx4.com/youruser/bms.git
|
||||
cd bms
|
||||
```
|
||||
|
||||
**`backend/.env`**
|
||||
```
|
||||
CLERK_SECRET_KEY=sk_test_...
|
||||
CLERK_JWKS_URL=https://your-app.clerk.accounts.dev/.well-known/jwks.json
|
||||
### 2. Create the environment files
|
||||
|
||||
Copy the example files and fill in your values:
|
||||
|
||||
```bash
|
||||
cp backend/.env.example backend/.env
|
||||
cp frontend/.env.local.example frontend/.env.local
|
||||
```
|
||||
|
||||
### 2. Run with Docker Compose
|
||||
Open each file and follow the inline comments. At minimum you need to set the Clerk keys (see [Environment Variables](#environment-variables) below).
|
||||
|
||||
### 3. Start all services
|
||||
|
||||
```bash
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
- Frontend: http://your-server:5646
|
||||
- API Docs: http://your-server:5646/api/backend/docs
|
||||
The first run downloads base images and builds the containers — this takes a few minutes. On subsequent starts it is much faster:
|
||||
|
||||
### 3. Run locally (development)
|
||||
|
||||
**Frontend**
|
||||
```bash
|
||||
cd frontend
|
||||
pnpm install
|
||||
pnpm dev --port 5646
|
||||
docker compose up
|
||||
```
|
||||
|
||||
**Backend**
|
||||
### 4. Done
|
||||
|
||||
Open your browser at **http://your-server:5646**
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
### `backend/.env`
|
||||
|
||||
```env
|
||||
# Database — matches the db service in docker-compose.yml, no change needed
|
||||
DATABASE_URL=postgresql+asyncpg://dcim:dcim_pass@db:5432/dcim
|
||||
|
||||
# MQTT broker — matches the mqtt service, no change needed
|
||||
MQTT_HOST=mqtt
|
||||
MQTT_PORT=1883
|
||||
|
||||
# Clerk authentication
|
||||
# Get these from https://dashboard.clerk.com → Your App → API Keys
|
||||
CLERK_SECRET_KEY=sk_test_REPLACE_ME
|
||||
CLERK_JWKS_URL=https://YOUR_APP.clerk.accounts.dev/.well-known/jwks.json
|
||||
|
||||
# CORS — add your frontend origin if you expose the backend directly
|
||||
# Leave empty when using the built-in Next.js proxy (recommended)
|
||||
CORS_ORIGINS=[]
|
||||
|
||||
DEBUG=true
|
||||
```
|
||||
|
||||
### `frontend/.env.local`
|
||||
|
||||
```env
|
||||
# Clerk authentication (same app as above)
|
||||
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_REPLACE_ME
|
||||
CLERK_SECRET_KEY=sk_test_REPLACE_ME
|
||||
|
||||
# Clerk redirect paths — no need to change these
|
||||
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
|
||||
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
|
||||
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/dashboard
|
||||
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/dashboard
|
||||
|
||||
# API path — leave as-is, Next.js proxies /api/backend/* to the backend internally
|
||||
NEXT_PUBLIC_API_URL=/api/backend
|
||||
```
|
||||
|
||||
> **Where do I get Clerk keys?**
|
||||
> Sign up free at https://clerk.com → create an application → go to **API Keys**.
|
||||
> Copy the **Publishable key** and **Secret key** into both files above.
|
||||
|
||||
---
|
||||
|
||||
## Verify Everything Is Running
|
||||
|
||||
```bash
|
||||
docker compose ps
|
||||
```
|
||||
|
||||
All five services should show `healthy` or `running`:
|
||||
|
||||
```
|
||||
NAME STATUS
|
||||
dcim_mqtt running (healthy)
|
||||
dcim_db running (healthy)
|
||||
dcim_backend running (healthy)
|
||||
dcim_simulators running
|
||||
dcim_frontend running
|
||||
```
|
||||
|
||||
Check individual logs if something looks wrong:
|
||||
|
||||
```bash
|
||||
docker compose logs backend # FastAPI logs
|
||||
docker compose logs frontend # Next.js logs
|
||||
docker compose logs db # PostgreSQL logs
|
||||
docker compose logs simulators # Sensor bot logs
|
||||
```
|
||||
|
||||
Test the backend API directly:
|
||||
|
||||
```bash
|
||||
curl http://localhost:8000/api/health
|
||||
# Expected: {"status":"ok"}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Accessing the App
|
||||
|
||||
| What | URL |
|
||||
|---|---|
|
||||
| Dashboard | http://your-server:5646 |
|
||||
| API docs (Swagger) | http://your-server:5646/api/backend/docs |
|
||||
| API docs (ReDoc) | http://your-server:5646/api/backend/redoc |
|
||||
|
||||
> **Reverse proxy tip:** The frontend is the only service that needs to be publicly reachable. Point Nginx / Caddy / Traefik at port **5646**. The backend, database, and MQTT broker communicate only on the internal Docker network.
|
||||
|
||||
```
|
||||
Browser → Reverse Proxy → :5646 (Next.js)
|
||||
↓ server-side rewrite
|
||||
:8000 (FastAPI) — internal only
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Ports Reference
|
||||
|
||||
| Service | Host port | Container port | Notes |
|
||||
|---|---|---|---|
|
||||
| Frontend (Next.js) | 5646 | 5646 | Public-facing |
|
||||
| Backend (FastAPI) | 8000 | 8000 | Internal; exposed for dev/debugging |
|
||||
| Database (PostgreSQL) | 5433 | 5432 | Mapped to 5433 to avoid conflicts with any local Postgres |
|
||||
| MQTT (Mosquitto) | 1883 | 1883 | Internal |
|
||||
|
||||
---
|
||||
|
||||
## Local Development (without Docker)
|
||||
|
||||
Useful if you want hot-reload on the frontend or backend without rebuilding containers.
|
||||
|
||||
### Database only via Docker
|
||||
|
||||
```bash
|
||||
docker compose up db mqtt
|
||||
```
|
||||
|
||||
### Backend
|
||||
|
||||
Requires Python 3.12+.
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
||||
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
||||
pip install -r requirements.txt
|
||||
uvicorn main:app --reload
|
||||
uvicorn main:app --reload --port 8000
|
||||
```
|
||||
|
||||
**Database only (via Docker)**
|
||||
### Frontend
|
||||
|
||||
Requires Node 22+ and pnpm.
|
||||
|
||||
```bash
|
||||
docker compose up db
|
||||
# Install pnpm if you don't have it
|
||||
npm install -g pnpm
|
||||
|
||||
cd frontend
|
||||
pnpm install
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Frontend dev server runs on http://localhost:3000 by default.
|
||||
|
||||
### Simulators
|
||||
|
||||
```bash
|
||||
cd simulators
|
||||
pip install -r requirements.txt
|
||||
python main.py
|
||||
```
|
||||
|
||||
---
|
||||
|
|
@ -91,22 +231,38 @@ docker compose up db
|
|||
## Project Structure
|
||||
|
||||
```
|
||||
/bms
|
||||
/frontend Next.js app
|
||||
/backend FastAPI app
|
||||
/simulators Sensor bots (Phase 2)
|
||||
docker-compose.yml
|
||||
bms/
|
||||
├── frontend/ Next.js 16 app (TypeScript, Tailwind, shadcn/ui, Recharts)
|
||||
│ ├── app/ Pages (dashboard, cooling, power, alarms, floor-map, …)
|
||||
│ ├── components/ Shared UI components
|
||||
│ └── lib/ API client, contexts, utilities
|
||||
│
|
||||
├── backend/ FastAPI app
|
||||
│ ├── api/routes/ REST endpoints (alarms, cooling, power, env, …)
|
||||
│ ├── core/ DB connection, config
|
||||
│ ├── models/ SQLAlchemy models
|
||||
│ └── services/ MQTT subscriber, alarm engine, WebSocket manager
|
||||
│
|
||||
├── simulators/ Python sensor bots — publish fake DCIM telemetry over MQTT
|
||||
│ └── bots/ Per-device bots: CRAC, UPS, generator, PDU, env, …
|
||||
│
|
||||
├── infra/
|
||||
│ └── mosquitto/ Mosquitto broker config
|
||||
│
|
||||
└── docker-compose.yml Orchestrates all services
|
||||
```
|
||||
|
||||
## Phase Progress
|
||||
---
|
||||
|
||||
- [x] Phase 1 — Foundation (current)
|
||||
- [ ] Phase 2 — Data Pipeline & Simulator Bots
|
||||
- [ ] Phase 3 — Core Dashboard (live data)
|
||||
- [ ] Phase 4 — Environmental Monitoring
|
||||
- [ ] Phase 5 — Power Management
|
||||
- [ ] Phase 6 — Cooling & AI Panel
|
||||
- [ ] Phase 7 — Asset Management
|
||||
- [ ] Phase 8 — Alarms & Events
|
||||
- [ ] Phase 9 — Reports
|
||||
- [ ] Phase 10 — Polish & Hardening
|
||||
## Stopping & Resetting
|
||||
|
||||
```bash
|
||||
# Stop all containers (data is preserved)
|
||||
docker compose down
|
||||
|
||||
# Stop and delete the database volume (full reset — all data lost)
|
||||
docker compose down -v
|
||||
|
||||
# Rebuild images after code changes
|
||||
docker compose up --build
|
||||
```
|
||||
|
|
|
|||
24
backend/.env.example
Normal file
24
backend/.env.example
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# ─────────────────────────────────────────────────────────────────
|
||||
# BMS Backend — Environment Variables
|
||||
# Copy this file to .env and fill in your values.
|
||||
# Never commit .env to git.
|
||||
# ─────────────────────────────────────────────────────────────────
|
||||
|
||||
# Database — matches docker-compose.yml defaults, no change needed for Docker deploys
|
||||
DATABASE_URL=postgresql+asyncpg://dcim:dcim_pass@db:5432/dcim
|
||||
|
||||
# MQTT broker — matches the mqtt service name in docker-compose.yml
|
||||
MQTT_HOST=mqtt
|
||||
MQTT_PORT=1883
|
||||
|
||||
# Clerk authentication
|
||||
# Get these from https://dashboard.clerk.com → Your App → API Keys
|
||||
CLERK_SECRET_KEY=sk_test_REPLACE_ME
|
||||
CLERK_JWKS_URL=https://YOUR_APP.clerk.accounts.dev/.well-known/jwks.json
|
||||
|
||||
# CORS origins — only needed if the backend is accessed directly from a browser
|
||||
# Example: CORS_ORIGINS=["https://yourdomain.com"]
|
||||
# Leave empty when using the built-in Next.js proxy (recommended)
|
||||
CORS_ORIGINS=[]
|
||||
|
||||
DEBUG=true
|
||||
25
frontend/.env.local.example
Normal file
25
frontend/.env.local.example
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# ─────────────────────────────────────────────────────────────────
|
||||
# BMS Frontend — Environment Variables
|
||||
# Copy this file to .env.local and fill in your values.
|
||||
# Never commit .env.local to git.
|
||||
# ─────────────────────────────────────────────────────────────────
|
||||
|
||||
# Clerk authentication
|
||||
# Get these from https://dashboard.clerk.com → Your App → API Keys
|
||||
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_REPLACE_ME
|
||||
CLERK_SECRET_KEY=sk_test_REPLACE_ME
|
||||
|
||||
# Clerk redirect paths — no change needed
|
||||
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
|
||||
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
|
||||
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/dashboard
|
||||
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/dashboard
|
||||
|
||||
# API path — leave as-is
|
||||
# All /api/backend/* requests are proxied server-side to the FastAPI backend
|
||||
NEXT_PUBLIC_API_URL=/api/backend
|
||||
|
||||
# Backend internal URL (used by Next.js server-side proxy, not sent to browser)
|
||||
# In Docker: http://backend:8000
|
||||
# In local dev: http://localhost:8000
|
||||
BACKEND_INTERNAL_URL=http://backend:8000
|
||||
1
frontend/.gitignore
vendored
1
frontend/.gitignore
vendored
|
|
@ -32,6 +32,7 @@ yarn-error.log*
|
|||
|
||||
# env files (can opt-in for committing if needed)
|
||||
.env*
|
||||
!.env.local.example
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue