# IPCam Orange Pi Dashboard - INSTALL

Tài liệu này hướng dẫn triển khai toàn bộ hệ thống trên duy nhất một thiết bị `Orange Pi 5`. Thiết bị `Orange Pi 4 Pro` sẽ triển khai tương tự

Mục tiêu:

- `MediaMTX` chạy trên chính Orange Pi 5
- `FastAPI backend` chạy trên chính Orange Pi 5
- `Frontend React` build static và serve ngay trên chính Orange Pi 5
- File recordings lưu trên ổ cứng gắn trực tiếp vào Orange Pi 5

## 0) Cấu hình phần cứng khuyến nghị

Bắt buộc theo kịch bản này:

- Thiết bị: `Orange Pi 5`
- RAM: `4GB` hoặc `8GB`
- Ổ lưu trữ: `>= 256GB`

Khuyến nghị mạnh:

- Dùng `NVMe SSD` thay vì thẻ nhớ
- Nếu ghi nhiều camera hoặc lưu lâu ngày, nên dùng `512GB` hoặc `1TB`
- Không nên để recordings trên thẻ microSD

## 1) Mô hình triển khai

Tất cả dịch vụ chạy trên cùng một máy Orange Pi 5:

```text
Orange Pi 5
|- MediaMTX
|- FastAPI backend
|- Frontend React static
`- Thu muc recordings tren SSD/NVMe
```

Không cần thêm server riêng cho MediaMTX hay dashboard.

## 2) Yêu cầu hệ điều hành và phần mềm

- Orange Pi 5 chạy Debian/Ubuntu
- Python `3.9+` khuyến nghị `3.10+`
- Node.js `20+`
- Docker + Docker Compose plugin
- Nginx hoặc Apache nếu muốn serve frontend static production

## 3) Chuẩn bị ổ lưu trữ

Ví dụ SSD được mount tại `/mnt/ssd`.

Tạo thư mục dự án và thư mục recordings:

```bash
sudo mkdir -p /mnt/ssd/IPCam_OrangePi_Dashboard
sudo mkdir -p /mnt/ssd/IPCam_OrangePi_Dashboard/mediamtx/recordings
sudo chown -R $USER:$USER /mnt/ssd/IPCam_OrangePi_Dashboard
```

Clone source:

```bash
cd /mnt/ssd
git clone https://git.ttcorp.net/orangepivietnam/IPCam_OrangePi_Dashboard
cd IPCam_OrangePi_Dashboard
```

## 4) MediaMTX cấu hình tối thiểu

Trong `mediamtx/mediamtx.yml` cần có tối thiểu:

```yaml
api: yes
apiAddress: :9997

webrtc: yes
webrtcAddress: :8889
webrtcAllowOrigin: '*'

record: yes
recordFormat: fmp4
recordPath: /mnt/ssd/IPCam_OrangePi_Dashboard/mediamtx/recordings/%path/%Y-%m-%d_%H-%M-%S-%f
recordPartDuration: 5m
```

Ghi chú:

- `recordPath` nên trỏ thẳng vào SSD/NVMe
- Dashboard sẽ tự đồng bộ camera vào `mediamtx.yml`
- Dashboard cần truy cập được MediaMTX API ở `127.0.0.1:9997`

### 4.1) Nếu MediaMTX API dùng auth

Nếu MediaMTX bật auth và dashboard bị `401 Unauthorized`, thêm user có quyền `api`:

```yaml
authMethod: internal
authInternalUsers:
  - user: dashboard
    pass: dashboard_password
    ips: ['127.0.0.1', '::1', '192.168.1.0/24']
    permissions:
      - action: api
```

Sau đó khai báo trong `api/data/config.json`:

```json
{
  "mediamtx_api_user": "dashboard",
  "mediamtx_api_pass": "dashboard_password"
}
```

## 5) Chạy MediaMTX trên Orange Pi 5

Nếu project đã có `mediamtx/docker-compose.yml`, chạy:

```bash
cd /mnt/ssd/IPCam_OrangePi_Dashboard
docker compose -f mediamtx/docker-compose.yml up -d
```

Kiểm tra:

```bash
docker compose -f mediamtx/docker-compose.yml ps
curl http://127.0.0.1:9997/v3/paths/list
```

## 6) Cài backend FastAPI

### 6.1) Cài dependencies

```bash
cd /mnt/ssd/IPCam_OrangePi_Dashboard
python3 -m venv api/.venv
source api/.venv/bin/activate
pip install -r api/requirements.txt
```

### 6.2) Cấu hình backend

Backend chỉ đọc cấu hình từ `api/data/config.json`.

File này chứa:

- thông số MediaMTX
- thư mục recordings
- danh sách camera
- lịch ghi hình
- cổng backend

Chạy lần đầu, backend có thể tự tạo file nếu chưa có.

Các giá trị nên dùng trên Orange Pi 5:

- `mediamtx_api_url`: `http://127.0.0.1:9997`
- `mediamtx_webrtc_url`: `http://127.0.0.1:8889`
- `recordings_dir`: `/mnt/ssd/IPCam_OrangePi_Dashboard/mediamtx/recordings`
- `api_port`: `8008`

Ví dụ `api/data/config.json`:

```json
{
  "mediamtx_api_url": "http://127.0.0.1:9997",
  "mediamtx_webrtc_url": "http://127.0.0.1:8889",
  "mediamtx_api_user": null,
  "mediamtx_api_pass": null,
  "recordings_dir": "/mnt/ssd/IPCam_OrangePi_Dashboard/mediamtx/recordings",
  "api_port": 8008,
  "cameras": [],
  "schedule": {
    "enabled": true,
    "weekdays_from": "18:00",
    "weekdays_to": "08:00",
    "weekend_all_day": true
  }
}
```

### 6.3) Chạy backend

```bash
cd /mnt/ssd/IPCam_OrangePi_Dashboard
source api/.venv/bin/activate
python3 -m api.run
```

Kiểm tra:

```bash
curl http://127.0.0.1:8008/api/health
```

## 7) Build frontend

```bash
cd /mnt/ssd/IPCam_OrangePi_Dashboard
npm install
npm run build
```

Output nằm ở `dist/`.

## 8) Serve frontend production

Có thể dùng `Nginx` hoặc `Apache`. Mục tiêu là:

- serve thư mục `dist/`
- reverse proxy `/api` về backend `127.0.0.1:8008`
- reverse proxy `/videos` về backend `127.0.0.1:8008`

### 8.1) Ví dụ Nginx

```nginx
server {
  listen 80;
  server_name _;

  root /mnt/ssd/IPCam_OrangePi_Dashboard/dist;
  index index.html;

  location / {
    try_files $uri $uri/ /index.html;
  }

  location /api/ {
    proxy_pass http://127.0.0.1:8008;
  }

  location /videos/ {
    proxy_pass http://127.0.0.1:8008;
  }
}
```

### 8.2) Ví dụ Apache

```apache
<VirtualHost *:80>
  ServerName _
  DocumentRoot /mnt/ssd/IPCam_OrangePi_Dashboard/dist

  <Directory /mnt/ssd/IPCam_OrangePi_Dashboard/dist>
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
  </Directory>

  RewriteEngine On
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule ^ /index.html [L]

  ProxyPreserveHost On
  ProxyPass /api/ http://127.0.0.1:8008/api/
  ProxyPassReverse /api/ http://127.0.0.1:8008/api/

  ProxyPass /videos/ http://127.0.0.1:8008/videos/
  ProxyPassReverse /videos/ http://127.0.0.1:8008/videos/
</VirtualHost>
```

Nếu dùng Apache:

```bash
sudo a2enmod rewrite proxy proxy_http
sudo systemctl reload apache2
```

## 9) Systemd service cho backend

Tạo file `/etc/systemd/system/ipcam-dashboard.service`:

```ini
[Unit]
Description=IPCam Dashboard Backend
After=network.target

[Service]
WorkingDirectory=/mnt/ssd/IPCam_OrangePi_Dashboard
ExecStart=/mnt/ssd/IPCam_OrangePi_Dashboard/api/.venv/bin/python /mnt/ssd/IPCam_OrangePi_Dashboard/api/run.py
Restart=always
RestartSec=2

[Install]
WantedBy=multi-user.target
```

Enable:

```bash
sudo systemctl daemon-reload
sudo systemctl enable --now ipcam-dashboard
sudo systemctl status ipcam-dashboard
```

## 10) Firewall/cổng cần mở

Tùy hệ thống mạng, cần cho phép:

- `8554/tcp` cho RTSP
- `8889/tcp` cho WebRTC HTTP
- `9997/tcp` cho MediaMTX API
- `8189/udp` cho ICE/WebRTC
- `80/tcp` hoặc `443/tcp` nếu serve dashboard qua web server

## 11) Kiểm tra nhanh sau triển khai

- Backend: `curl http://127.0.0.1:8008/api/health`
- MediaMTX API: `curl http://127.0.0.1:9997/v3/paths/list`
- Frontend: mở `http://<ip-orange-pi>/`
- Trong Settings:
  - thêm camera bằng RTSP URL
  - lưu cấu hình
  - kiểm tra camera xuất hiện trong Live View
  - kiểm tra file recordings được tạo trên SSD/NVMe

## 12) Ghi chú vận hành

- Nên để toàn bộ project và recordings trên cùng SSD/NVMe
- Nếu ghi nhiều camera liên tục, cần theo dõi dung lượng trống định kỳ
- Orange Pi 5 RAM `16GB` phù hợp hơn khi số camera lớn hơn hoặc cần playback đồng thời
- Khi cần ổn định cao, nên dùng nguồn tốt và tản nhiệt phù hợp cho Orange Pi 5

