fix: 🐛 update CHANGELOG.md and Dockerfile for sing-box enhancements

- Updated CHANGELOG.md to include version 0.4.1 with fixes related to sing-box, including an upgrade to version 1.13.5 and improvements in configuration validation and error logging.
- Modified Dockerfile to reflect the new sing-box version.
- Enhanced error handling in the sing-box startup process, including configuration checks and stderr logging for better diagnostics.
This commit is contained in:
isboyjc
2026-04-04 22:59:35 +08:00
parent f03c3300b4
commit eedc090a4f
3 changed files with 51 additions and 6 deletions

View File

@@ -5,6 +5,18 @@
格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/)
版本号遵循 [语义化版本 2.0.0](https://semver.org/lang/zh-CN/)。
## [v0.4.1] - 2026-04-04
### 修复
- 升级 sing-box 从 1.11.8 到 **1.13.5**,修复 anytls 等新协议不支持导致订阅节点启动失败的问题
- sing-box 启动前新增 `sing-box check` 配置预检,配置无效时输出详细错误而非静默崩溃
- 捕获 sing-box stderr 输出到 `[sing-box]` 日志,便于排查运行时错误
- 检测 sing-box 进程启动后立即退出的情况,避免误报"端口未就绪"
- Docker healthcheck 从 `wget` 改为 `curl`debian-slim 无 wgetDockerfile 增加 curl 安装
- 修复 `docker-compose.dokploy.yml` 服务未加入 `dokploy-network` 的问题
- 修复中英文切换时订阅池统计模块动态文字未更新的问题
## [v0.4.0] - 2026-04-04
### 新增

View File

@@ -9,7 +9,7 @@ COPY . .
RUN CGO_ENABLED=1 GOOS=linux go build -o proxy-pool .
# 下载 sing-box 二进制
ARG SINGBOX_VERSION=1.11.8
ARG SINGBOX_VERSION=1.13.5
RUN ARCH=$(case "$(dpkg --print-architecture)" in amd64) echo "amd64";; arm64) echo "arm64";; *) echo "amd64";; esac) && \
curl -fsSL "https://github.com/SagerNet/sing-box/releases/download/v${SINGBOX_VERSION}/sing-box-${SINGBOX_VERSION}-linux-${ARCH}.tar.gz" \
-o /tmp/sing-box.tar.gz && \

View File

@@ -361,20 +361,45 @@ func convertPluginOpts(plugin string, opts map[string]interface{}) string {
// startLocked 启动 sing-box需持有锁
func (s *SingBoxProcess) startLocked() error {
if _, err := exec.LookPath(s.binPath); err != nil {
binPath, err := exec.LookPath(s.binPath)
if err != nil {
return fmt.Errorf("sing-box 未找到: %s请安装 sing-box 或设置 SINGBOX_PATH", s.binPath)
}
s.cmd = exec.Command(s.binPath, "run", "-c", s.configFile, "-D", s.configDir)
// 先检查配置是否有效
checkCmd := exec.Command(binPath, "check", "-c", s.configFile, "-D", s.configDir)
if checkOutput, err := checkCmd.CombinedOutput(); err != nil {
log.Printf("[custom] ❌ sing-box 配置检查失败:\n%s", string(checkOutput))
return fmt.Errorf("sing-box 配置无效: %s", string(checkOutput))
}
s.cmd = exec.Command(binPath, "run", "-c", s.configFile, "-D", s.configDir)
// 捕获 stderr 用于错误诊断
stderrPipe, _ := s.cmd.StderrPipe()
s.cmd.Stdout = os.Stdout
s.cmd.Stderr = os.Stderr
if err := s.cmd.Start(); err != nil {
return err
return fmt.Errorf("sing-box 启动失败: %w", err)
}
s.running = true
// 异步读取 stderr 并输出到日志
go func() {
buf := make([]byte, 4096)
for {
n, err := stderrPipe.Read(buf)
if n > 0 {
log.Printf("[sing-box] %s", strings.TrimSpace(string(buf[:n])))
}
if err != nil {
break
}
}
}()
// 监控进程退出
exitCh := make(chan struct{})
go func() {
if s.cmd != nil && s.cmd.Process != nil {
s.cmd.Wait()
@@ -382,12 +407,20 @@ func (s *SingBoxProcess) startLocked() error {
s.running = false
s.mu.Unlock()
}
close(exitCh)
}()
// 等待端口就绪(最多 10 秒)
log.Printf("[custom] sing-box 启动中,等待端口就绪...")
log.Printf("[custom] sing-box 启动中,等待端口就绪(配置: %s...", s.configFile)
ready := false
for i := 0; i < 20; i++ {
// 检查进程是否已退出
select {
case <-exitCh:
return fmt.Errorf("sing-box 进程启动后立即退出,请检查日志")
default:
}
time.Sleep(500 * time.Millisecond)
// 检查第一个端口是否可连
for _, port := range s.portMap {