diff --git a/README.md b/README.md index 43df06d..408c32e 100644 --- a/README.md +++ b/README.md @@ -192,7 +192,7 @@ cd MediaStationGo docker compose up -d ``` -> 🌐 打开 ,使用 `admin` / `admin123` 登录。 +> 🌐 服务启动后会自动识别本机 IP,日志中显示访问地址(如 `http://192.168.x.x:8080`),使用 `admin` / `admin123` 登录。 ### 💻 裸机部署 diff --git a/README_EN.md b/README_EN.md index b09926d..2f36582 100644 --- a/README_EN.md +++ b/README_EN.md @@ -192,7 +192,7 @@ cd MediaStationGo docker compose up -d ``` -> 🌐 Open and log in with `admin` / `admin123`. +> 🌐 The server auto-detects your local IP on startup and logs the access URL (e.g. `http://192.168.x.x:8080`). Log in with `admin` / `admin123`. ### 💻 Bare Metal diff --git a/cmd/server/main.go b/cmd/server/main.go index b7374e1..5efa001 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -14,6 +14,7 @@ import ( "context" "errors" "fmt" + "net" "net/http" "os" "os/signal" @@ -87,7 +88,11 @@ func main() { } go func() { - logger.Info("listening", zap.String("addr", srv.Addr)) + localIP := getLocalIP() + logger.Info("server is ready", + zap.String("local", fmt.Sprintf("http://%s:%d", localIP, cfg.App.Port)), + zap.String("listen", srv.Addr), + ) if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { logger.Fatal("listen failed", zap.Error(err)) } @@ -148,3 +153,30 @@ func newLogger(cfg *config.Config) (*zap.Logger, error) { } return zap.NewProduction() } + +// getLocalIP returns the first non-loopback IPv4 address of the machine. +// Falls back to "localhost" if no suitable interface is found. +func getLocalIP() string { + interfaces, err := net.Interfaces() + if err != nil { + return "localhost" + } + for _, iface := range interfaces { + if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 { + continue + } + addrs, err := iface.Addrs() + if err != nil { + continue + } + for _, addr := range addrs { + switch v := addr.(type) { + case *net.IPNet: + if ip := v.IP.To4(); ip != nil { + return ip.String() + } + } + } + } + return "localhost" +}