shouldBindJson 使用错误
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m51s
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m51s
This commit is contained in:
parent
67d2c8cca8
commit
7914b2aa78
11
.env.example
Normal file
11
.env.example
Normal 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
|
||||||
@ -1,9 +1,15 @@
|
|||||||
# PPanel 服务部署 (云端/无源码版)
|
# PPanel 服务部署 (云端/无源码版)
|
||||||
# 使用方法:
|
# 使用方法:
|
||||||
# 1. 确保已将 docker-compose.cloud.yml, configs/, loki/, grafana/, prometheus/ 目录上传到服务器同一目录
|
# 1. 确保已将 docker-compose.cloud.yml, configs/, loki/, grafana/, prometheus/, tempo/ 目录上传到服务器同一目录
|
||||||
# 2. 确保 configs/ 目录下有 ppanel.yaml 配置文件
|
# 2. 确保 configs/ 目录下有 ppanel.yaml 配置文件(参考 etc/ppanel.yaml)
|
||||||
# 3. 确保 logs/ 目录存在 (mkdir logs)
|
# 3. 确保 logs/ 目录存在 (mkdir -p logs tempo_data)
|
||||||
# 4. 运行: docker-compose -f docker-compose.cloud.yml up -d
|
# 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:
|
services:
|
||||||
# ----------------------------------------------------
|
# ----------------------------------------------------
|
||||||
@ -18,49 +24,22 @@ services:
|
|||||||
- ./logs:/app/logs
|
- ./logs:/app/logs
|
||||||
environment:
|
environment:
|
||||||
- TZ=Asia/Shanghai
|
- TZ=Asia/Shanghai
|
||||||
# 链路追踪配置 (OTLP)
|
ports:
|
||||||
- OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4317
|
- "8080:8080"
|
||||||
- OTEL_SERVICE_NAME=ppanel-server
|
networks:
|
||||||
- OTEL_TRACES_EXPORTER=otlp
|
- ppanel_net
|
||||||
- OTEL_METRICS_EXPORTER=prometheus # 指标由 tempo 抓取,不使用 OTLP
|
|
||||||
network_mode: host
|
|
||||||
ulimits:
|
ulimits:
|
||||||
nproc: 65535
|
nproc: 65535
|
||||||
nofile:
|
nofile:
|
||||||
soft: 65535
|
soft: 65535
|
||||||
hard: 65535
|
hard: 65535
|
||||||
logging:
|
|
||||||
driver: "json-file"
|
|
||||||
options:
|
|
||||||
max-size: "10m"
|
|
||||||
max-file: "3"
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- mysql
|
mysql:
|
||||||
- redis
|
condition: service_healthy
|
||||||
- tempo
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
# ----------------------------------------------------
|
|
||||||
# 14. Tempo (链路追踪存储 - 替代/增强 Jaeger)
|
|
||||||
# ----------------------------------------------------
|
|
||||||
tempo:
|
tempo:
|
||||||
image: grafana/tempo:2.4.1
|
condition: service_started
|
||||||
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
|
|
||||||
logging:
|
logging:
|
||||||
driver: "json-file"
|
driver: "json-file"
|
||||||
options:
|
options:
|
||||||
@ -74,10 +53,9 @@ services:
|
|||||||
image: mysql:8.0
|
image: mysql:8.0
|
||||||
container_name: ppanel-mysql
|
container_name: ppanel-mysql
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
# 不对外暴露端口,仅内网访问(容器名: mysql,端口: 3306)
|
||||||
- "3306:3306" # 临时开放外部访问,用完记得关闭!
|
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD: "jpcV41ppanel" # 请修改为强密码
|
MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD:?请在 .env 文件中设置 MYSQL_ROOT_PASSWORD}"
|
||||||
MYSQL_DATABASE: "ppanel"
|
MYSQL_DATABASE: "ppanel"
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
command:
|
command:
|
||||||
@ -97,6 +75,11 @@ services:
|
|||||||
hard: 65535
|
hard: 65535
|
||||||
networks:
|
networks:
|
||||||
- ppanel_net
|
- ppanel_net
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p${MYSQL_ROOT_PASSWORD}"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
logging:
|
logging:
|
||||||
driver: "json-file"
|
driver: "json-file"
|
||||||
options:
|
options:
|
||||||
@ -110,8 +93,7 @@ services:
|
|||||||
image: redis:8.2.1
|
image: redis:8.2.1
|
||||||
container_name: ppanel-redis
|
container_name: ppanel-redis
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
# 不对外暴露端口,仅内网访问(容器名: redis,端口: 6379)
|
||||||
- "6379:6379"
|
|
||||||
command:
|
command:
|
||||||
- redis-server
|
- redis-server
|
||||||
- --tcp-backlog 65535
|
- --tcp-backlog 65535
|
||||||
@ -125,6 +107,11 @@ services:
|
|||||||
hard: 65535
|
hard: 65535
|
||||||
networks:
|
networks:
|
||||||
- ppanel_net
|
- ppanel_net
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
logging:
|
logging:
|
||||||
driver: "json-file"
|
driver: "json-file"
|
||||||
options:
|
options:
|
||||||
@ -132,19 +119,21 @@ services:
|
|||||||
max-file: "3"
|
max-file: "3"
|
||||||
|
|
||||||
# ----------------------------------------------------
|
# ----------------------------------------------------
|
||||||
# 4. Loki (日志存储)
|
# 4. Tempo (链路追踪存储)
|
||||||
# ----------------------------------------------------
|
# ----------------------------------------------------
|
||||||
loki:
|
tempo:
|
||||||
image: grafana/loki:3.0.0
|
image: grafana/tempo:2.4.1
|
||||||
container_name: ppanel-loki
|
container_name: ppanel-tempo
|
||||||
|
user: root
|
||||||
restart: always
|
restart: always
|
||||||
|
command:
|
||||||
|
- "-config.file=/etc/tempo.yaml"
|
||||||
|
- "-target=all"
|
||||||
volumes:
|
volumes:
|
||||||
# 必须上传 loki 目录到服务器
|
- ./tempo/tempo-config.yaml:/etc/tempo.yaml
|
||||||
- ./loki/loki-config.yaml:/etc/loki/local-config.yaml
|
- ./tempo_data:/var/tempo
|
||||||
- loki_data:/loki
|
# 不对外暴露端口,仅内网访问(容器名: tempo)
|
||||||
command: -config.file=/etc/loki/local-config.yaml
|
# ppanel-server 通过容器名 tempo:4317 发送 trace
|
||||||
ports:
|
|
||||||
- "3100:3100"
|
|
||||||
networks:
|
networks:
|
||||||
- ppanel_net
|
- ppanel_net
|
||||||
logging:
|
logging:
|
||||||
@ -154,7 +143,27 @@ services:
|
|||||||
max-file: "3"
|
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:
|
promtail:
|
||||||
image: grafana/promtail:3.0.0
|
image: grafana/promtail:3.0.0
|
||||||
@ -164,9 +173,7 @@ services:
|
|||||||
- ./loki/promtail-config.yaml:/etc/promtail/config.yaml
|
- ./loki/promtail-config.yaml:/etc/promtail/config.yaml
|
||||||
- /var/lib/docker/containers:/var/lib/docker/containers:ro
|
- /var/lib/docker/containers:/var/lib/docker/containers:ro
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
# 采集当前目录下的 logs 文件夹
|
|
||||||
- ./logs:/var/log/ppanel-server:ro
|
- ./logs:/var/log/ppanel-server:ro
|
||||||
# 采集 Nginx 访问日志(用于追踪邀请码来源)
|
|
||||||
- /var/log/nginx:/var/log/nginx:ro
|
- /var/log/nginx:/var/log/nginx:ro
|
||||||
command: -config.file=/etc/promtail/config.yaml
|
command: -config.file=/etc/promtail/config.yaml
|
||||||
networks:
|
networks:
|
||||||
@ -180,27 +187,29 @@ services:
|
|||||||
max-file: "3"
|
max-file: "3"
|
||||||
|
|
||||||
# ----------------------------------------------------
|
# ----------------------------------------------------
|
||||||
# 6. Grafana (日志界面)
|
# 7. Grafana (可观测面板)
|
||||||
|
# 访问: ssh -L 3333:localhost:3333 your-server 后浏览器打开 http://localhost:3333
|
||||||
|
# 或配置 Nginx 反代(建议加认证)
|
||||||
# ----------------------------------------------------
|
# ----------------------------------------------------
|
||||||
grafana:
|
grafana:
|
||||||
image: grafana/grafana:latest
|
image: grafana/grafana:latest
|
||||||
container_name: ppanel-grafana
|
container_name: ppanel-grafana
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- "3333:3000"
|
- "127.0.0.1:3333:3000" # 仅本机可访问,需 SSH 隧道或 Nginx 反代
|
||||||
environment:
|
environment:
|
||||||
- GF_SECURITY_ADMIN_PASSWORD=admin
|
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:?请在 .env 文件中设置 GRAFANA_PASSWORD}
|
||||||
- GF_USERS_ALLOW_SIGN_UP=false
|
- GF_USERS_ALLOW_SIGN_UP=false
|
||||||
- GF_FEATURE_TOGGLES_ENABLE=appObservability #- GF_INSTALL_PLUGINS=redis-datasource
|
- GF_FEATURE_TOGGLES_ENABLE=appObservability
|
||||||
volumes:
|
volumes:
|
||||||
- grafana_data:/var/lib/grafana
|
- grafana_data:/var/lib/grafana
|
||||||
- ./grafana/provisioning:/etc/grafana/provisioning
|
- ./grafana/provisioning:/etc/grafana/provisioning
|
||||||
extra_hosts:
|
|
||||||
- "host.docker.internal:host-gateway"
|
|
||||||
networks:
|
networks:
|
||||||
- ppanel_net
|
- ppanel_net
|
||||||
depends_on:
|
depends_on:
|
||||||
- loki
|
- loki
|
||||||
|
- tempo
|
||||||
|
- prometheus
|
||||||
logging:
|
logging:
|
||||||
driver: "json-file"
|
driver: "json-file"
|
||||||
options:
|
options:
|
||||||
@ -208,25 +217,22 @@ services:
|
|||||||
max-file: "3"
|
max-file: "3"
|
||||||
|
|
||||||
# ----------------------------------------------------
|
# ----------------------------------------------------
|
||||||
# 7. Prometheus (指标采集)
|
# 8. Prometheus (指标采集)
|
||||||
# ----------------------------------------------------
|
# ----------------------------------------------------
|
||||||
prometheus:
|
prometheus:
|
||||||
image: prom/prometheus:latest
|
image: prom/prometheus:latest
|
||||||
container_name: ppanel-prometheus
|
container_name: ppanel-prometheus
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- "9090:9090" # 暴露端口便于调试
|
- "127.0.0.1:9090:9090" # 仅本机可访问
|
||||||
volumes:
|
volumes:
|
||||||
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
|
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
|
||||||
- prometheus_data:/prometheus
|
- prometheus_data:/prometheus
|
||||||
extra_hosts:
|
|
||||||
- "host.docker.internal:host-gateway"
|
|
||||||
command:
|
command:
|
||||||
- '--config.file=/etc/prometheus/prometheus.yml'
|
- '--config.file=/etc/prometheus/prometheus.yml'
|
||||||
- '--storage.tsdb.path=/prometheus'
|
- '--storage.tsdb.path=/prometheus'
|
||||||
- '--web.enable-lifecycle'
|
- '--web.enable-lifecycle'
|
||||||
- '--web.enable-remote-write-receiver'
|
- '--web.enable-remote-write-receiver'
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
- ppanel_net
|
- ppanel_net
|
||||||
logging:
|
logging:
|
||||||
@ -236,7 +242,7 @@ services:
|
|||||||
max-file: "3"
|
max-file: "3"
|
||||||
|
|
||||||
# ----------------------------------------------------
|
# ----------------------------------------------------
|
||||||
# 8. Redis Exporter (Redis指标导出)
|
# 9. Redis Exporter
|
||||||
# ----------------------------------------------------
|
# ----------------------------------------------------
|
||||||
redis-exporter:
|
redis-exporter:
|
||||||
image: oliver006/redis_exporter:latest
|
image: oliver006/redis_exporter:latest
|
||||||
@ -255,13 +261,12 @@ services:
|
|||||||
max-file: "3"
|
max-file: "3"
|
||||||
|
|
||||||
# ----------------------------------------------------
|
# ----------------------------------------------------
|
||||||
# 9. Nginx Exporter (监控宿主机 Nginx)
|
# 10. Nginx Exporter (监控宿主机 Nginx)
|
||||||
# ----------------------------------------------------
|
# ----------------------------------------------------
|
||||||
nginx-exporter:
|
nginx-exporter:
|
||||||
image: nginx/nginx-prometheus-exporter:latest
|
image: nginx/nginx-prometheus-exporter:latest
|
||||||
container_name: ppanel-nginx-exporter
|
container_name: ppanel-nginx-exporter
|
||||||
restart: always
|
restart: always
|
||||||
# 使用 host.docker.internal 访问宿主机
|
|
||||||
command:
|
command:
|
||||||
- -nginx.scrape-uri=http://host.docker.internal:8090/nginx_status
|
- -nginx.scrape-uri=http://host.docker.internal:8090/nginx_status
|
||||||
extra_hosts:
|
extra_hosts:
|
||||||
@ -275,7 +280,7 @@ services:
|
|||||||
max-file: "3"
|
max-file: "3"
|
||||||
|
|
||||||
# ----------------------------------------------------
|
# ----------------------------------------------------
|
||||||
# 10. MySQL Exporter (MySQL指标导出)
|
# 11. MySQL Exporter
|
||||||
# ----------------------------------------------------
|
# ----------------------------------------------------
|
||||||
mysql-exporter:
|
mysql-exporter:
|
||||||
image: prom/mysqld-exporter:latest
|
image: prom/mysqld-exporter:latest
|
||||||
@ -347,7 +352,6 @@ volumes:
|
|||||||
prometheus_data:
|
prometheus_data:
|
||||||
tempo_data:
|
tempo_data:
|
||||||
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
ppanel_net:
|
ppanel_net:
|
||||||
name: ppanel_net
|
name: ppanel_net
|
||||||
|
|||||||
@ -15,19 +15,19 @@ Logger: # 日志配置
|
|||||||
Level: debug # 日志级别: debug, info, warn, error, panic, fatal
|
Level: debug # 日志级别: debug, info, warn, error, panic, fatal
|
||||||
|
|
||||||
MySQL:
|
MySQL:
|
||||||
Addr: 127.0.0.1:3306 # MySQL地址
|
Addr: mysql:3306 # Docker 容器名; 本地开发改为 127.0.0.1:3306
|
||||||
Username: root # MySQL用户名 (与创建的用户一致)
|
Username: root # MySQL用户名
|
||||||
Password: rootpassword # MySQL密码 (换成之前生成的随机密码)
|
Password: CHANGE_ME_MYSQL_PASSWORD # MySQL密码,与 .env MYSQL_ROOT_PASSWORD 一致
|
||||||
Dbname: ppanel # MySQL数据库名 (与脚本创建的数据库一致)
|
Dbname: ppanel # MySQL数据库名
|
||||||
Config: charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
|
Config: charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
|
||||||
MaxIdleConns: 10
|
MaxIdleConns: 10
|
||||||
MaxOpenConns: 100
|
MaxOpenConns: 100
|
||||||
LogMode: debug
|
LogMode: info # 生产建议 info,开发用 debug
|
||||||
LogZap: true
|
LogZap: true
|
||||||
SlowThreshold: 1000
|
SlowThreshold: 1000
|
||||||
|
|
||||||
Redis:
|
Redis:
|
||||||
Host: 127.0.0.1:6379 # Redis地址,格式:host:port
|
Host: redis:6379 # Docker 容器名; 本地开发改为 127.0.0.1:6379
|
||||||
Pass: # Redis密码,如果没有设置密码可以留空
|
Pass: # Redis密码,如果没有设置密码可以留空
|
||||||
DB: 0 # Redis数据库编号,默认0
|
DB: 0 # Redis数据库编号,默认0
|
||||||
PoolSize: 100 # 连接池大小(最大连接数),根据应用并发量调整,建议:小流量50-100,中流量100-300,大流量300-500
|
PoolSize: 100 # 连接池大小(最大连接数),根据应用并发量调整,建议:小流量50-100,中流量100-300,大流量300-500
|
||||||
@ -55,6 +55,12 @@ AppSignature:
|
|||||||
Signature:
|
Signature:
|
||||||
EnableSignature: false # 系统签名开关(实际运行会以数据库 system.signature.EnableSignature 为准)
|
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:
|
Administrator:
|
||||||
Email: admin@ppanel.dev # 后台登录邮箱,请修改
|
Email: admin@ppanel.dev # 后台登录邮箱,请修改
|
||||||
Password: CHANGE_ME_TO_STRONG_PASSWORD # 后台登录密码,请修改为强密码
|
Password: CHANGE_ME_TO_STRONG_PASSWORD # 后台登录密码,请修改为强密码
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import (
|
|||||||
func UnbindDeviceHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
func UnbindDeviceHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
var req types.UnbindDeviceRequest
|
var req types.UnbindDeviceRequest
|
||||||
_ = c.ShouldBindJSON(&req)
|
_ = c.ShouldBind(&req)
|
||||||
validateErr := svcCtx.Validate(&req)
|
validateErr := svcCtx.Validate(&req)
|
||||||
if validateErr != nil {
|
if validateErr != nil {
|
||||||
result.ParamErrorResult(c, validateErr)
|
result.ParamErrorResult(c, validateErr)
|
||||||
|
|||||||
@ -107,11 +107,14 @@ func (m *Service) Start() {
|
|||||||
MinVersion: tls.VersionTLS12,
|
MinVersion: tls.VersionTLS12,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
trace.StartAgent(trace.Config{
|
traceCfg := m.svc.Config.Trace
|
||||||
Name: "ppanel",
|
if traceCfg.Name == "" {
|
||||||
Sampler: 1.0,
|
traceCfg.Name = "ppanel"
|
||||||
Batcher: "",
|
}
|
||||||
})
|
if traceCfg.Sampler == 0 {
|
||||||
|
traceCfg.Sampler = 1.0
|
||||||
|
}
|
||||||
|
trace.StartAgent(traceCfg)
|
||||||
proc.AddShutdownListener(func() {
|
proc.AddShutdownListener(func() {
|
||||||
trace.StopAgent()
|
trace.StopAgent()
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user