diff --git a/.gitignore b/.gitignore index 262646f..b7aefbb 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,7 @@ wheels/ *.local # Runtime data(serverdata/ 承载全部资源目录) -# 数据库文件/日志/上传/密钥不入库;seed/ 与 prompts/ 模板需提交。 +# 数据库文件/日志/上传/密钥/中间件数据不入库;seed/ 与 prompts/ 模板需提交。 serverdata/data/*.db serverdata/data/*.db-* serverdata/data/*.json.tmp @@ -26,6 +26,12 @@ serverdata/logs/ serverdata/files/ serverdata/keys/ serverdata/uploads/ +serverdata/compute-data/ +serverdata/compute-logs/ +serverdata/mysql-data/ +serverdata/redis-data/ +serverdata/emqx-data/ +serverdata/emqx-log/ data/users.json data/tokens.json data/agents.json diff --git a/serverrun/compute-engine/build.sh b/serverrun/compute-engine/build.sh new file mode 100644 index 0000000..11681c5 --- /dev/null +++ b/serverrun/compute-engine/build.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# 构建算力引擎镜像(new-api 源码在 code/compute-engine,server-core 的兄弟仓库) +set -euo pipefail + +# 本脚本位于 server-core/serverrun/compute-engine/ +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# 计算源仓库:server-core/serverrun/compute-engine → ../../.. → code/ → compute-engine +SRC_DIR="$(cd "$SCRIPT_DIR/../../.." && pwd)" +ENGINE_SRC="${ENGINE_SRC:-$SRC_DIR/compute-engine}" +TAG="${COMPUTE_ENGINE_TAG:-opc-compute-engine:latest}" + +if [ ! -f "$ENGINE_SRC/Dockerfile" ]; then + echo "错误:未找到算力引擎源码 $ENGINE_SRC/Dockerfile" >&2 + echo "(clone: git clone http://code.infoepoch.cn/Pine/compute-engine.git $ENGINE_SRC)" >&2 + exit 1 +fi + +echo "构建算力引擎镜像:$TAG(源码 $ENGINE_SRC)..." +docker build -t "$TAG" "$ENGINE_SRC" +echo "构建完成:$TAG" diff --git a/serverrun/compute-engine/docker-compose.yml b/serverrun/compute-engine/docker-compose.yml new file mode 100644 index 0000000..a38e010 --- /dev/null +++ b/serverrun/compute-engine/docker-compose.yml @@ -0,0 +1,27 @@ +# 算力调度服务(compute-engine / new-api)编排 +# 仅服务:OpenAI 兼容 /v1 中继 + 额度/令牌/流水;仅 loopback :3000,不对外暴露。 +# 镜像:本地构建(build.sh)或 calciumion/new-api:latest。 + +services: + compute-engine: + image: ${COMPUTE_ENGINE_IMAGE:-opc-compute-engine:latest} + container_name: opc-compute-engine + restart: always + command: --log-dir /app/logs + ports: + - "127.0.0.1:3000:3000" # 仅 loopback,算力服务经内部 IP 调用 + environment: + - SQLITE_PATH=/data/new-api.db # 或 MySQL: SQL_DSN=mysql+asyncmy://... + - REDIS_CONN_STRING=redis://:redis_pass@redis:6379/0 + - SESSION_SECRET=${SESSION_SECRET:?请设置 SESSION_SECRET} + - TZ=Asia/Shanghai + volumes: + - ../../serverdata/compute-data:/data + - ../../serverdata/compute-logs:/app/logs + networks: + - opc-network + +networks: + opc-network: + name: opc-network + external: true diff --git a/serverrun/core/docker-compose.yml b/serverrun/core/docker-compose.yml new file mode 100644 index 0000000..35dfa1a --- /dev/null +++ b/serverrun/core/docker-compose.yml @@ -0,0 +1,30 @@ +# 主服务 core(server-core / dispatcher)编排 +# 统一对外生产服务 opc.pinesound.cn → core:8090(经网关,仅 loopback) + +services: + core: + build: + context: ../.. + dockerfile: serverrun/Dockerfile + image: opc-core:latest + container_name: opc-core + restart: always + ports: + - "127.0.0.1:8090:8090" + environment: + - PINEAGENTS_DEMO_DATABASE_URL=mysql+asyncmy://opc:opc_pass@mysql:3306/opc?charset=utf8mb4 + - REDIS_URL=redis://:redis_pass@redis:6379/0 + - SESSION_SECRET=${SESSION_SECRET:?请设置 SESSION_SECRET} + - TZ=Asia/Shanghai + volumes: + - ../../serverdata:/app/serverdata + depends_on: + - redis + - mysql + networks: + - opc-network + +networks: + opc-network: + name: opc-network + external: true diff --git a/serverrun/docker-compose.yml b/serverrun/docker-compose.yml deleted file mode 100644 index ca9e906..0000000 --- a/serverrun/docker-compose.yml +++ /dev/null @@ -1,85 +0,0 @@ -# 云超服后端服务群编排(serverrun/) -# 服务:core(server-core,统一入口)+ compute-engine(算力引擎)+ 基础设施(redis/mysql/emqx) -# 对外统一生产服务 opc.pinesound.cn → core:8090 - -services: - core: - build: - context: .. - dockerfile: serverrun/Dockerfile - container_name: opc-core - restart: always - ports: - - "127.0.0.1:8090:8090" # 统一入口(经网关暴露,仅 loopback) - environment: - - PINEAGENTS_DEMO_DATABASE_URL=mysql+asyncmy://opc:opc_pass@mysql:3306/opc?charset=utf8mb4 - - REDIS_URL=redis://:redis_pass@redis:6379/0 - - TZ=Asia/Shanghai - volumes: - - ./../serverdata:/app/serverdata # 资源目录挂载 - depends_on: - - redis - - mysql - networks: - - opc-network - - compute-engine: - image: calciumion/new-api:latest - container_name: opc-compute-engine - restart: always - command: --log-dir /app/logs - ports: - - "127.0.0.1:3000:3000" # 仅 loopback,算力服务经内部 IP 调用 - environment: - - SQLITE_PATH=/data/new-api.db - - REDIS_CONN_STRING=redis://:redis_pass@redis:6379/0 - - SESSION_SECRET=${SESSION_SECRET:?请设置 SESSION_SECRET} - - TZ=Asia/Shanghai - volumes: - - compute-data:/data - - compute-logs:/app/logs - depends_on: - - redis - networks: - - opc-network - - redis: - image: redis:7 - container_name: opc-redis - restart: always - command: ["redis-server", "--requirepass", "redis_pass"] - networks: - - opc-network - - mysql: - image: mysql:8 - container_name: opc-mysql - restart: always - environment: - MYSQL_ROOT_PASSWORD: root_pass - MYSQL_DATABASE: opc - MYSQL_USER: opc - MYSQL_PASSWORD: opc_pass - volumes: - - mysql-data:/var/lib/mysql - networks: - - opc-network - - # emqx(消息总线,大屏/桌面端实时)——可选,启用时打开注释 - # emqx: - # image: emqx/emqx:5.8 - # container_name: opc-emqx - # restart: always - # ports: - # - "127.0.0.1:1883:1883" - # networks: - # - opc-network - -volumes: - compute-data: - compute-logs: - mysql-data: - -networks: - opc-network: - driver: bridge diff --git a/serverrun/encrypt-certs.sh b/serverrun/encrypt-certs.sh new file mode 100644 index 0000000..51c40ca --- /dev/null +++ b/serverrun/encrypt-certs.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# 证书加密打包(参考 PineSoundServer encrypt-certs.sh) +# 用途:微信/HTTPS 证书加密归档,不入库。 +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$ROOT" + +ENC_KEY="${ENC_KEY:-}" +if [ -z "$ENC_KEY" ]; then + echo "错误:请设置 ENC_KEY" >&2 + exit 1 +fi + +CERT_DIR="serverdata/keys/certs" +if [ ! -d "$CERT_DIR" ]; then + echo "目录不存在:$CERT_DIR(先放置证书)" >&2 + exit 1 +fi + +tar -czf - -C "$CERT_DIR" . | openssl enc -aes-256-cbc -pbkdf2 -salt \ + -out serverrun/certs.tar.gz.enc -pass pass:"$ENC_KEY" +echo "已加密:serverrun/certs.tar.gz.enc" diff --git a/serverrun/envcopy.sh b/serverrun/envcopy.sh new file mode 100644 index 0000000..6dbc067 --- /dev/null +++ b/serverrun/envcopy.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# 配置加密:.env → .env.enc(参考 PineSoundServer envcopy.sh) +# 用途:生产机不落明文配置,仅保留加密包;部署时解密注入。 +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$ROOT" + +ENC_KEY="${ENC_KEY:-}" +if [ -z "$ENC_KEY" ]; then + echo "错误:请设置 ENC_KEY(openssl rand -hex 32)" >&2 + exit 1 +fi + +SRC="${1:-.env}" +DST="${SRC}.enc" +openssl enc -aes-256-cbc -pbkdf2 -salt -in "$SRC" -out "$DST" -pass pass:"$ENC_KEY" +echo "已加密:$SRC -> $DST" diff --git a/serverrun/mqtt/docker-compose.yml b/serverrun/mqtt/docker-compose.yml new file mode 100644 index 0000000..1b2c816 --- /dev/null +++ b/serverrun/mqtt/docker-compose.yml @@ -0,0 +1,23 @@ +# MQTT 消息服务(EMQX,大屏/桌面端实时总线) +services: + emqx: + image: emqx/emqx:5.8 + container_name: opc-emqx + restart: always + ports: + - "127.0.0.1:1883:1883" # MQTT + - "127.0.0.1:18083:18083" # 管理 API + - "127.0.0.1:8083:8083" # WebSocket + environment: + - EMQX_NAME=opc + - EMQX_HOST=node1.emqx.local + volumes: + - ../../serverdata/emqx-data:/opt/emqx/data + - ../../serverdata/emqx-log:/opt/emqx/log + networks: + - opc-network + +networks: + opc-network: + name: opc-network + external: true diff --git a/serverrun/mysql/docker-compose.yml b/serverrun/mysql/docker-compose.yml new file mode 100644 index 0000000..9949713 --- /dev/null +++ b/serverrun/mysql/docker-compose.yml @@ -0,0 +1,23 @@ +# MySQL 服务(业务主库,后续启用;先建编排) +services: + mysql: + image: mysql:8 + container_name: opc-mysql + restart: always + environment: + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root_pass} + MYSQL_DATABASE: opc + MYSQL_USER: opc + MYSQL_PASSWORD: ${MYSQL_PASSWORD:-opc_pass} + command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci + ports: + - "127.0.0.1:3306:3306" + volumes: + - ../../serverdata/mysql-data:/var/lib/mysql + networks: + - opc-network + +networks: + opc-network: + name: opc-network + external: true diff --git a/serverrun/redis/docker-compose.yml b/serverrun/redis/docker-compose.yml new file mode 100644 index 0000000..0b31cd6 --- /dev/null +++ b/serverrun/redis/docker-compose.yml @@ -0,0 +1,18 @@ +# Redis 缓存服务(会话/缓存/限流/分布式锁) +services: + redis: + image: redis:7 + container_name: opc-redis + restart: always + command: ["redis-server", "--requirepass", "redis_pass"] + ports: + - "127.0.0.1:6379:6379" + volumes: + - ../../serverdata/redis-data:/data + networks: + - opc-network + +networks: + opc-network: + name: opc-network + external: true diff --git a/serverrun/start-all.sh b/serverrun/start-all.sh new file mode 100644 index 0000000..6192371 --- /dev/null +++ b/serverrun/start-all.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# 一键编排启动全部服务(serverrun/,参考 PineSoundServer start-all.sh) +# 顺序:基础设施(redis/mysql/emqx) → 算力调度 → 主服务 core +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$ROOT/serverrun" + +echo "==========================================" +echo "① 基础设施:Redis / MySQL / MQTT(EMQX)" +echo "==========================================" +docker compose -f redis/docker-compose.yml up -d || true +docker compose -f mysql/docker-compose.yml up -d || true +docker compose -f mqtt/docker-compose.yml up -d || true + +echo "==========================================" +echo "② 算力调度服务 compute-engine" +echo "==========================================" +bash start-compute.sh || true + +echo "==========================================" +echo "③ 主服务 core(dispatcher 统一入口)" +echo "==========================================" +docker compose -f core/docker-compose.yml up -d --build || true + +echo "==========================================" +echo "完成。core 地址:http://127.0.0.1:8090(对外经网关 opc.pinesound.cn)" +echo "==========================================" diff --git a/serverrun/start-compute.sh b/serverrun/start-compute.sh new file mode 100644 index 0000000..6244639 --- /dev/null +++ b/serverrun/start-compute.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# 算力调度服务(compute-engine / new-api)启动 +set -euo pipefail +cd "$(dirname "${BASH_SOURCE[0]}")/compute-engine" + +echo "构建算力引擎镜像..." +bash build.sh + +echo "启动算力引擎(仅 loopback :3000)..." +docker compose up -d +echo "算力引擎就绪:http://127.0.0.1:3000(经 core 算力服务代理,不对外直连)" diff --git a/serverrun/start-emqx.sh b/serverrun/start-emqx.sh new file mode 100644 index 0000000..1faf31a --- /dev/null +++ b/serverrun/start-emqx.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# MQTT 消息服务(EMQX)启动 +set -euo pipefail +cd "$(dirname "${BASH_SOURCE[0]}")/mqtt" +docker compose up -d +echo "EMQX 就绪::1883(MQTT) / :18083(API)"