From 7cace210d645af8c55f88f79f986993b3bb874b9 Mon Sep 17 00:00:00 2001 From: Tony Tran Date: Tue, 28 Apr 2026 10:18:44 +0700 Subject: [PATCH] fix variable in env --- .env.example | 14 ++++++++++++++ .gitignore | 6 +++++- INSTALL.md | 33 +++++++++++++++++++-------------- README.md | 12 +++++++++++- api/app/main.py | 7 +++++++ api/requirements.txt | 1 + api/run.py | 22 ++++++++++++++++++++++ 7 files changed, 79 insertions(+), 16 deletions(-) create mode 100644 .env.example create mode 100644 api/run.py diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..97db6bf --- /dev/null +++ b/.env.example @@ -0,0 +1,14 @@ +DASHBOARD_PORT=8008 + +MEDIAMTX_API_URL=http://127.0.0.1:9997 +MEDIAMTX_WEBRTC_URL=http://127.0.0.1:8889 +RECORDINGS_DIR=/recordings + +MEDIAMTX_API_USER= +MEDIAMTX_API_PASS= + +CORS_ORIGINS=http://localhost:5173 + +VITE_DEV_BACKEND_URL=http://localhost:8008 +VITE_API_BASE_URL=/api +VITE_MEDIAMTX_WEBRTC_URL= diff --git a/.gitignore b/.gitignore index dcee78e..01232e2 100644 --- a/.gitignore +++ b/.gitignore @@ -24,8 +24,12 @@ dist-ssr *.sw? api/.venv/ +api/__pycache__ +api/__init__.py api/app/__pycache__/ api/data +.env + # recordings -mediamtx/recordings \ No newline at end of file +mediamtx/recordings diff --git a/INSTALL.md b/INSTALL.md index f26577d..6ff8bc4 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -65,11 +65,11 @@ authInternalUsers: - action: api ``` -Sau đó trên máy chạy dashboard backend: +Sau đó set trong file `.env` của dashboard backend: -```bash -export MEDIAMTX_API_USER="dashboard" -export MEDIAMTX_API_PASS="dashboard_password" +``` +MEDIAMTX_API_USER=dashboard +MEDIAMTX_API_PASS=dashboard_password ``` Trong `paths`, bạn có thể để dashboard tự thêm path bằng API (Settings → Add Camera). @@ -128,7 +128,15 @@ pip install -r api/requirements.txt ### 3.2 Cấu hình -Chạy backend lần đầu sẽ tự tạo `api/data/config.json`. +Tạo file `.env`: + +```bash +cp .env.example .env +``` + +Backend sẽ tự load `.env` khi start. + +Chạy backend lần đầu sẽ tự tạo `api/data/config.json` (lưu danh sách camera + schedule). Bạn có thể chỉnh: @@ -156,18 +164,16 @@ export MEDIAMTX_WEBRTC_URL="http://192.168.88.10:8889" export RECORDINGS_DIR="/recordings" ``` -Nếu MediaMTX API có auth, export biến môi trường: +Nếu MediaMTX API có auth, set trong `.env`: -```bash -export MEDIAMTX_API_USER="..." -export MEDIAMTX_API_PASS="..." -``` +- `MEDIAMTX_API_USER` +- `MEDIAMTX_API_PASS` ### 3.3 Chạy backend ```bash source api/.venv/bin/activate -uvicorn api.app.main:app --host 0.0.0.0 --port 8008 +python3 api/run.py ``` ## 4) Frontend (build static) @@ -228,9 +234,8 @@ After=network.target [Service] WorkingDirectory=/opt/ipcam-dashboard -Environment=MEDIAMTX_API_USER= -Environment=MEDIAMTX_API_PASS= -ExecStart=/opt/ipcam-dashboard/api/.venv/bin/uvicorn api.app.main:app --host 0.0.0.0 --port 8008 +EnvironmentFile=/opt/ipcam-dashboard/.env +ExecStart=/opt/ipcam-dashboard/api/.venv/bin/python /opt/ipcam-dashboard/api/run.py Restart=always RestartSec=2 diff --git a/README.md b/README.md index 46cadd9..166973d 100644 --- a/README.md +++ b/README.md @@ -25,13 +25,21 @@ Dashboard giám sát camera IP gọn nhẹ chạy trên Orange Pi, dựa trên M ## Chạy dev (máy dev) +### 0) Tạo file .env + +```bash +cp .env.example .env +``` + +Sửa các biến trong `.env` theo IP/port thực tế (MediaMTX, recordings, CORS). + ### 1) Chạy backend ```bash python3 -m venv api/.venv source api/.venv/bin/activate pip install -r api/requirements.txt -uvicorn api.app.main:app --host 0.0.0.0 --port 8008 +python3 api/run.py ``` ### 2) Chạy frontend @@ -45,6 +53,8 @@ Frontend dev server đã được cấu hình proxy `/api` và `/videos` sang `h ## Cấu hình +Khuyến nghị cấu hình bằng file `.env` (copy từ `.env.example`). + Backend tự tạo file cấu hình tại `api/data/config.json` khi chạy lần đầu. - `mediamtx_api_url`: ví dụ `http://127.0.0.1:9997` diff --git a/api/app/main.py b/api/app/main.py index 43781f4..8191cd4 100644 --- a/api/app/main.py +++ b/api/app/main.py @@ -23,6 +23,13 @@ from .models import ( from .recordings import list_recordings from .scheduler import Scheduler +try: + from dotenv import load_dotenv + + load_dotenv(Path(__file__).resolve().parents[2] / ".env") +except Exception: + pass + def _cors_origins() -> list[str]: raw = os.getenv("CORS_ORIGINS", "http://localhost:5173") diff --git a/api/requirements.txt b/api/requirements.txt index 446d91c..df26fa5 100644 --- a/api/requirements.txt +++ b/api/requirements.txt @@ -3,4 +3,5 @@ uvicorn[standard]>=0.27 httpx>=0.27 pydantic>=2.6 python-multipart>=0.0.9 +python-dotenv>=1.0.1 diff --git a/api/run.py b/api/run.py new file mode 100644 index 0000000..b944eb6 --- /dev/null +++ b/api/run.py @@ -0,0 +1,22 @@ +from __future__ import annotations + +import os +from pathlib import Path + +import uvicorn + +try: + from dotenv import load_dotenv + + load_dotenv(Path(__file__).resolve().parents[1] / ".env") +except Exception: + pass + + +def main() -> None: + port = int(os.getenv("DASHBOARD_PORT", "8008")) + uvicorn.run("api.app.main:app", host="0.0.0.0", port=port, reload=False) + + +if __name__ == "__main__": + main()