2026-08-18 06:50:50 +08:00
|
|
|
|
# ============================================================
|
|
|
|
|
|
# OPC 智能园区后端 · Docker Compose 一键部署
|
|
|
|
|
|
#
|
|
|
|
|
|
# 启动: docker compose up -d --build
|
|
|
|
|
|
# 停止: docker compose down
|
|
|
|
|
|
# 查看: docker compose logs -f backend
|
|
|
|
|
|
# 重建: docker compose up -d --build backend
|
|
|
|
|
|
#
|
|
|
|
|
|
# 部署前配置(可选,均可用环境变量覆盖):
|
|
|
|
|
|
# export MQTT_PUBLIC_HOST=192.168.1.50 # 展播端能访问到的 Broker 地址(服务器局域网 IP)
|
|
|
|
|
|
# export EMQX_USER=dpmserver EMQX_PASS=xxxxx
|
|
|
|
|
|
# export DASHSCOPE_API_KEY=sk-xxxx # AI/语音(未配置时 AI 走本地规则引擎)
|
|
|
|
|
|
# export DPM_S2S_ENABLED=0 # 不需要实时语音对话可关闭
|
|
|
|
|
|
#
|
|
|
|
|
|
# 端口:
|
|
|
|
|
|
# · 10085 HTTP(API + 管理后台 + 媒体)
|
|
|
|
|
|
# · 8765 s2s 实时语音 WebSocket(DPM_S2S_ENABLED=1 时)
|
|
|
|
|
|
# · 1883/8083/18083 EMQX(MQTT / MQTT-WS / 控制台)
|
|
|
|
|
|
# ============================================================
|
|
|
|
|
|
|
|
|
|
|
|
services:
|
|
|
|
|
|
# ---------- MQTT Broker(EMQX 5.x) ----------
|
|
|
|
|
|
emqx:
|
|
|
|
|
|
image: emqx/emqx:5.8
|
|
|
|
|
|
container_name: dpm-emqx
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- "1883:1883" # MQTT
|
|
|
|
|
|
- "8083:8083" # MQTT over WebSocket(展播端 /api/config 下发)
|
|
|
|
|
|
- "18083:18083" # EMQX Dashboard(可选,账号 admin / public)
|
|
|
|
|
|
environment:
|
|
|
|
|
|
EMQX_NAME: dpm-emqx
|
|
|
|
|
|
EMQX_HOST: node.emqx.dpm.local
|
|
|
|
|
|
EMQX_NODE__COOKIE: dpm-emqx-cookie
|
|
|
|
|
|
EMQX_DASHBOARD__DEFAULT_PASSWORD: "${EMQX_DASHBOARD_PASS:-public}"
|
|
|
|
|
|
# 鉴权:禁止匿名,单账号 dpmserver(与 backend/.env 一致)
|
|
|
|
|
|
EMQX_ALLOW_ANONYMOUS: "false"
|
|
|
|
|
|
EMQX_AUTH__USER__1__LOGIN: "${EMQX_USER:-dpmserver}"
|
|
|
|
|
|
EMQX_AUTH__USER__1__PASSWORD: "${EMQX_PASS:-123456}"
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- emqx_data:/opt/emqx/data
|
|
|
|
|
|
- emqx_log:/opt/emqx/log
|
|
|
|
|
|
healthcheck:
|
|
|
|
|
|
test: ["CMD", "emqx", "ctl", "status"]
|
|
|
|
|
|
interval: 10s
|
|
|
|
|
|
timeout: 5s
|
|
|
|
|
|
retries: 12
|
|
|
|
|
|
start_period: 15s
|
|
|
|
|
|
networks:
|
|
|
|
|
|
- dpm_net
|
|
|
|
|
|
|
|
|
|
|
|
# ---------- 园区后端(FastAPI :10085 + s2s :8765) ----------
|
|
|
|
|
|
backend:
|
|
|
|
|
|
build:
|
|
|
|
|
|
context: .
|
|
|
|
|
|
dockerfile: backend/Dockerfile
|
|
|
|
|
|
image: dpm-backend:latest
|
|
|
|
|
|
container_name: dpm-backend
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
depends_on:
|
|
|
|
|
|
emqx:
|
|
|
|
|
|
condition: service_healthy
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- "10085:10085" # API / 管理后台 / 媒体
|
|
|
|
|
|
- "8765:8765" # s2s 实时语音(DPM_S2S_ENABLED=1 时)
|
|
|
|
|
|
environment:
|
|
|
|
|
|
DPM_PORT: "10085"
|
|
|
|
|
|
DPM_MQTT_ENABLED: "1"
|
|
|
|
|
|
MQTT_BROKER_HOST: emqx
|
|
|
|
|
|
MQTT_BROKER_PORT: "1883"
|
|
|
|
|
|
MQTT_USERNAME: "${EMQX_USER:-dpmserver}"
|
|
|
|
|
|
MQTT_PASSWORD: "${EMQX_PASS:-123456}"
|
|
|
|
|
|
# 展播端(Tauri 大屏)经后端 /api/config 获取的 WebSocket 地址:
|
2026-08-18 09:05:23 +08:00
|
|
|
|
# 必须填"展播机能访问到的服务器地址",默认 192.168.1.9(同机部署)
|
|
|
|
|
|
DPM_MQTT_WS: "ws://${MQTT_PUBLIC_HOST:-192.168.1.9}:8083/mqtt"
|
2026-08-18 06:50:50 +08:00
|
|
|
|
DPM_S2S_ENABLED: "${DPM_S2S_ENABLED:-1}"
|
|
|
|
|
|
DASHSCOPE_API_KEY: "${DASHSCOPE_API_KEY:-}"
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- dpm_media:/app/backend/media # 媒体资源(上传持久化)
|
|
|
|
|
|
- dpm_knowledge:/app/backend/knowledge # 知识库 park.md(可热更新,删除 kb_index.json 触发重建)
|
|
|
|
|
|
- dpm_data:/app/backend/data.json # 播放列表 / 设置
|
|
|
|
|
|
healthcheck:
|
2026-08-18 09:05:23 +08:00
|
|
|
|
test: ["CMD", "python", "-c", "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://192.168.1.9:10085/api/health', timeout=4).status==200 else 1)"]
|
2026-08-18 06:50:50 +08:00
|
|
|
|
interval: 15s
|
|
|
|
|
|
timeout: 5s
|
|
|
|
|
|
retries: 5
|
|
|
|
|
|
start_period: 30s
|
|
|
|
|
|
networks:
|
|
|
|
|
|
- dpm_net
|
|
|
|
|
|
|
|
|
|
|
|
networks:
|
|
|
|
|
|
dpm_net:
|
|
|
|
|
|
driver: bridge
|
|
|
|
|
|
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
emqx_data:
|
|
|
|
|
|
emqx_log:
|
|
|
|
|
|
dpm_media:
|
|
|
|
|
|
dpm_knowledge:
|
|
|
|
|
|
dpm_data:
|