package main import ( "bufio" "net" "net/url" "os" "strconv" "strings" "time" ) func main() { url := strings.TrimSpace(os.Getenv("BACKEND_HEALTHCHECK_URL")) if url == "" { port := strings.TrimSpace(os.Getenv("BACKEND_PORT")) if port == "" { port = strings.TrimSpace(os.Getenv("PORT")) } if port == "" { port = "3000" } url = "http://127.0.0.1:" + port + "/health" } statusCode, err := checkHTTP(url, 3*time.Second) if err != nil { _, _ = os.Stderr.WriteString("healthcheck request failed: " + err.Error() + "\n") os.Exit(1) } if statusCode < 200 || statusCode >= 400 { _, _ = os.Stderr.WriteString("healthcheck returned HTTP " + strconv.Itoa(statusCode) + "\n") os.Exit(1) } } func checkHTTP(rawURL string, timeout time.Duration) (int, error) { parsed, err := url.Parse(rawURL) if err != nil { return 0, err } host := parsed.Host if !strings.Contains(host, ":") { host += ":80" } path := parsed.RequestURI() if path == "" { path = "/" } conn, err := net.DialTimeout("tcp", host, timeout) if err != nil { return 0, err } defer conn.Close() _ = conn.SetDeadline(time.Now().Add(timeout)) request := "GET " + path + " HTTP/1.1\r\nHost: " + parsed.Host + "\r\nConnection: close\r\n\r\n" if _, err := conn.Write([]byte(request)); err != nil { return 0, err } line, err := bufio.NewReader(conn).ReadString('\n') if err != nil { return 0, err } parts := strings.Fields(line) if len(parts) < 2 { return 0, nil } return strconv.Atoi(parts[1]) }