shouldBindJson 使用错误
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m51s

This commit is contained in:
shanshanzhong 2026-03-06 01:30:39 -08:00
parent 67d2c8cca8
commit 7914b2aa78
5 changed files with 111 additions and 87 deletions

11
.env.example Normal file
View File

@ -0,0 +1,11 @@
# 复制此文件为 .env 并填写真实值
# cp .env.example .env
# MySQL root 密码(同时需要在 configs/ppanel.yaml 的 MySQL.Password 中填写相同的值)
MYSQL_ROOT_PASSWORD=CHANGE_ME_TO_STRONG_PASSWORD
# Grafana 管理员密码
GRAFANA_PASSWORD=CHANGE_ME_TO_STRONG_PASSWORD
# PPanel Server 镜像标签(留空使用 latest
PPANEL_SERVER_TAG=latest

View File

@ -1,9 +1,15 @@
# PPanel 服务部署 (云端/无源码版)
# 使用方法:
# 1. 确保已将 docker-compose.cloud.yml, configs/, loki/, grafana/, prometheus/ 目录上传到服务器同一目录
# 2. 确保 configs/ 目录下有 ppanel.yaml 配置文件
# 3. 确保 logs/ 目录存在 (mkdir logs)
# 使用方法:
# 1. 确保已将 docker-compose.cloud.yml, configs/, loki/, grafana/, prometheus/, tempo/ 目录上传到服务器同一目录
# 2. 确保 configs/ 目录下有 ppanel.yaml 配置文件(参考 etc/ppanel.yaml
# 3. 确保 logs/ 目录存在 (mkdir -p logs tempo_data)
# 4. 运行: docker-compose -f docker-compose.cloud.yml up -d
#
# 网络说明:
# 所有服务均在 ppanel_net bridge 网络中,通过容器名互联
# MySQL / Redis / Tempo 不对外暴露端口(仅内网访问)
# 监控端口Grafana/Prometheus/Loki/Tempo绑定到 127.0.0.1,需通过 SSH 隧道或 Nginx 反代访问
# 对外只暴露 8080 (ppanel API)
services:
# ----------------------------------------------------
@ -18,49 +24,22 @@ services:
- ./logs:/app/logs
environment:
- TZ=Asia/Shanghai
# 链路追踪配置 (OTLP)
- OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4317
- OTEL_SERVICE_NAME=ppanel-server
- OTEL_TRACES_EXPORTER=otlp
- OTEL_METRICS_EXPORTER=prometheus # 指标由 tempo 抓取,不使用 OTLP
network_mode: host
ports:
- "8080:8080"
networks:
- ppanel_net
ulimits:
nproc: 65535
nofile:
soft: 65535
hard: 65535
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
depends_on:
- mysql
- redis
- tempo
# ----------------------------------------------------
# 14. Tempo (链路追踪存储 - 替代/增强 Jaeger)
# ----------------------------------------------------
tempo:
image: grafana/tempo:2.4.1
container_name: ppanel-tempo
user: root
restart: always
command:
- "-config.file=/etc/tempo.yaml"
- "-target=all"
volumes:
- ./tempo/tempo-config.yaml:/etc/tempo.yaml # - tempo_data:/var/tempo
- ./tempo_data:/var/tempo # 改为映射到当前目录,确保数据彻底干净
ports:
- "3200:3200"
- "4317:4317"
- "4318:4318"
- "9095:9095"
networks:
- ppanel_net
mysql:
condition: service_healthy
redis:
condition: service_healthy
tempo:
condition: service_started
logging:
driver: "json-file"
options:
@ -74,10 +53,9 @@ services:
image: mysql:8.0
container_name: ppanel-mysql
restart: always
ports:
- "3306:3306" # 临时开放外部访问,用完记得关闭!
# 不对外暴露端口,仅内网访问(容器名: mysql端口: 3306
environment:
MYSQL_ROOT_PASSWORD: "jpcV41ppanel" # 请修改为强密码
MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD:?请在 .env 文件中设置 MYSQL_ROOT_PASSWORD}"
MYSQL_DATABASE: "ppanel"
TZ: Asia/Shanghai
command:
@ -97,6 +75,11 @@ services:
hard: 65535
networks:
- ppanel_net
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p${MYSQL_ROOT_PASSWORD}"]
interval: 10s
timeout: 5s
retries: 5
logging:
driver: "json-file"
options:
@ -110,8 +93,7 @@ services:
image: redis:8.2.1
container_name: ppanel-redis
restart: always
ports:
- "6379:6379"
# 不对外暴露端口,仅内网访问(容器名: redis端口: 6379
command:
- redis-server
- --tcp-backlog 65535
@ -125,6 +107,11 @@ services:
hard: 65535
networks:
- ppanel_net
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
logging:
driver: "json-file"
options:
@ -132,19 +119,21 @@ services:
max-file: "3"
# ----------------------------------------------------
# 4. Loki (日志存储)
# 4. Tempo (链路追踪存储)
# ----------------------------------------------------
loki:
image: grafana/loki:3.0.0
container_name: ppanel-loki
tempo:
image: grafana/tempo:2.4.1
container_name: ppanel-tempo
user: root
restart: always
command:
- "-config.file=/etc/tempo.yaml"
- "-target=all"
volumes:
# 必须上传 loki 目录到服务器
- ./loki/loki-config.yaml:/etc/loki/local-config.yaml
- loki_data:/loki
command: -config.file=/etc/loki/local-config.yaml
ports:
- "3100:3100"
- ./tempo/tempo-config.yaml:/etc/tempo.yaml
- ./tempo_data:/var/tempo
# 不对外暴露端口,仅内网访问(容器名: tempo
# ppanel-server 通过容器名 tempo:4317 发送 trace
networks:
- ppanel_net
logging:
@ -154,7 +143,27 @@ services:
max-file: "3"
# ----------------------------------------------------
# 5. Promtail (日志采集)
# 5. Loki (日志存储)
# ----------------------------------------------------
loki:
image: grafana/loki:3.0.0
container_name: ppanel-loki
restart: always
volumes:
- ./loki/loki-config.yaml:/etc/loki/local-config.yaml
- loki_data:/loki
command: -config.file=/etc/loki/local-config.yaml
# 不对外暴露端口,仅内网访问
networks:
- ppanel_net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# ----------------------------------------------------
# 6. Promtail (日志采集)
# ----------------------------------------------------
promtail:
image: grafana/promtail:3.0.0
@ -164,9 +173,7 @@ services:
- ./loki/promtail-config.yaml:/etc/promtail/config.yaml
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /var/run/docker.sock:/var/run/docker.sock
# 采集当前目录下的 logs 文件夹
- ./logs:/var/log/ppanel-server:ro
# 采集 Nginx 访问日志(用于追踪邀请码来源)
- /var/log/nginx:/var/log/nginx:ro
command: -config.file=/etc/promtail/config.yaml
networks:
@ -180,27 +187,29 @@ services:
max-file: "3"
# ----------------------------------------------------
# 6. Grafana (日志界面)
# 7. Grafana (可观测面板)
# 访问: ssh -L 3333:localhost:3333 your-server 后浏览器打开 http://localhost:3333
# 或配置 Nginx 反代(建议加认证)
# ----------------------------------------------------
grafana:
image: grafana/grafana:latest
container_name: ppanel-grafana
restart: always
ports:
- "3333:3000"
- "127.0.0.1:3333:3000" # 仅本机可访问,需 SSH 隧道或 Nginx 反代
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:?请在 .env 文件中设置 GRAFANA_PASSWORD}
- GF_USERS_ALLOW_SIGN_UP=false
- GF_FEATURE_TOGGLES_ENABLE=appObservability #- GF_INSTALL_PLUGINS=redis-datasource
- GF_FEATURE_TOGGLES_ENABLE=appObservability
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
extra_hosts:
- "host.docker.internal:host-gateway"
networks:
- ppanel_net
depends_on:
- loki
- tempo
- prometheus
logging:
driver: "json-file"
options:
@ -208,25 +217,22 @@ services:
max-file: "3"
# ----------------------------------------------------
# 7. Prometheus (指标采集)
# 8. Prometheus (指标采集)
# ----------------------------------------------------
prometheus:
image: prom/prometheus:latest
container_name: ppanel-prometheus
restart: always
ports:
- "9090:9090" # 暴露端口便于调试
- "127.0.0.1:9090:9090" # 仅本机可访问
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
extra_hosts:
- "host.docker.internal:host-gateway"
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.enable-lifecycle'
- '--web.enable-remote-write-receiver'
networks:
- ppanel_net
logging:
@ -236,7 +242,7 @@ services:
max-file: "3"
# ----------------------------------------------------
# 8. Redis Exporter (Redis指标导出)
# 9. Redis Exporter
# ----------------------------------------------------
redis-exporter:
image: oliver006/redis_exporter:latest
@ -255,13 +261,12 @@ services:
max-file: "3"
# ----------------------------------------------------
# 9. Nginx Exporter (监控宿主机 Nginx)
# 10. Nginx Exporter (监控宿主机 Nginx)
# ----------------------------------------------------
nginx-exporter:
image: nginx/nginx-prometheus-exporter:latest
container_name: ppanel-nginx-exporter
restart: always
# 使用 host.docker.internal 访问宿主机
command:
- -nginx.scrape-uri=http://host.docker.internal:8090/nginx_status
extra_hosts:
@ -275,7 +280,7 @@ services:
max-file: "3"
# ----------------------------------------------------
# 10. MySQL Exporter (MySQL指标导出)
# 11. MySQL Exporter
# ----------------------------------------------------
mysql-exporter:
image: prom/mysqld-exporter:latest
@ -347,7 +352,6 @@ volumes:
prometheus_data:
tempo_data:
networks:
ppanel_net:
name: ppanel_net

View File

@ -15,19 +15,19 @@ Logger: # 日志配置
Level: debug # 日志级别: debug, info, warn, error, panic, fatal
MySQL:
Addr: 127.0.0.1:3306 # MySQL地址
Username: root # MySQL用户名 (与创建的用户一致)
Password: rootpassword # MySQL密码 (换成之前生成的随机密码)
Dbname: ppanel # MySQL数据库名 (与脚本创建的数据库一致)
Addr: mysql:3306 # Docker 容器名; 本地开发改为 127.0.0.1:3306
Username: root # MySQL用户名
Password: CHANGE_ME_MYSQL_PASSWORD # MySQL密码与 .env MYSQL_ROOT_PASSWORD 一致
Dbname: ppanel # MySQL数据库名
Config: charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
MaxIdleConns: 10
MaxOpenConns: 100
LogMode: debug
LogMode: info # 生产建议 info开发用 debug
LogZap: true
SlowThreshold: 1000
Redis:
Host: 127.0.0.1:6379 # Redis地址格式host:port
Host: redis:6379 # Docker 容器名; 本地开发改为 127.0.0.1:6379
Pass: # Redis密码如果没有设置密码可以留空
DB: 0 # Redis数据库编号默认0
PoolSize: 100 # 连接池大小最大连接数根据应用并发量调整建议小流量50-100中流量100-300大流量300-500
@ -55,6 +55,12 @@ AppSignature:
Signature:
EnableSignature: false # 系统签名开关(实际运行会以数据库 system.signature.EnableSignature 为准)
Trace: # 链路追踪配置 (OpenTelemetry)
Name: ppanel # 服务名
Sampler: 1.0 # 采样率 0.0-1.0,生产建议 0.1
Batcher: otlpgrpc # 本地开发留空""; 生产填 otlpgrpc
Endpoint: "tempo:4317" # Docker 容器名; 本地开发留空""
Administrator:
Email: admin@ppanel.dev # 后台登录邮箱,请修改
Password: CHANGE_ME_TO_STRONG_PASSWORD # 后台登录密码,请修改为强密码

View File

@ -12,7 +12,7 @@ import (
func UnbindDeviceHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
return func(c *gin.Context) {
var req types.UnbindDeviceRequest
_ = c.ShouldBindJSON(&req)
_ = c.ShouldBind(&req)
validateErr := svcCtx.Validate(&req)
if validateErr != nil {
result.ParamErrorResult(c, validateErr)

View File

@ -107,11 +107,14 @@ func (m *Service) Start() {
MinVersion: tls.VersionTLS12,
},
}
trace.StartAgent(trace.Config{
Name: "ppanel",
Sampler: 1.0,
Batcher: "",
})
traceCfg := m.svc.Config.Trace
if traceCfg.Name == "" {
traceCfg.Name = "ppanel"
}
if traceCfg.Sampler == 0 {
traceCfg.Sampler = 1.0
}
trace.StartAgent(traceCfg)
proc.AddShutdownListener(func() {
trace.StopAgent()
})