Skip to content

Commit 11610b2

Browse files
committed
feat: add built-in healthcheck function and update healthcheck command in Dockerfiles
1 parent 22abb4a commit 11610b2

4 files changed

Lines changed: 43 additions & 3 deletions

File tree

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ EXPOSE 8080 8081
5555

5656
# Health check
5757
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
58-
CMD wget -q --spider http://localhost:8080/api/health || exit 1
58+
CMD ["/app/labelgate", "healthcheck"]
5959

6060
# Default command
6161
ENTRYPOINT ["/app/labelgate"]

cmd/labelgate/main.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ package main
44
import (
55
"context"
66
"fmt"
7+
"net"
8+
"net/http"
79
"os"
810
"os/signal"
911
"syscall"
@@ -37,6 +39,11 @@ func main() {
3739
os.Exit(0)
3840
}
3941

42+
// Built-in healthcheck for distroless containers (no wget/curl available)
43+
if flag.Arg(0) == "healthcheck" {
44+
os.Exit(runHealthcheck(*configPath))
45+
}
46+
4047
// Setup logger
4148
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
4249

@@ -231,6 +238,39 @@ func buildAgentConfigs(cfg *config.Config) map[string]*agent.AgentConfigEntry {
231238
return result
232239
}
233240

241+
// runHealthcheck performs an HTTP health check against the local API server.
242+
// It reuses the same config.Load path (env vars > config file > defaults)
243+
func runHealthcheck(configPath string) int {
244+
addr := ":8080"
245+
basePath := "/api"
246+
247+
if cfg, err := config.Load(configPath); err == nil {
248+
addr = cfg.Api.Address
249+
basePath = cfg.Api.BasePath
250+
}
251+
252+
_, port, err := net.SplitHostPort(addr)
253+
if err != nil {
254+
fmt.Fprintf(os.Stderr, "healthcheck: invalid address %q: %v\n", addr, err)
255+
return 1
256+
}
257+
258+
url := "http://localhost:" + port + basePath + "/health"
259+
client := &http.Client{Timeout: 2 * time.Second}
260+
resp, err := client.Get(url)
261+
if err != nil {
262+
fmt.Fprintf(os.Stderr, "healthcheck failed: %v\n", err)
263+
return 1
264+
}
265+
defer resp.Body.Close()
266+
267+
if resp.StatusCode != http.StatusOK {
268+
fmt.Fprintf(os.Stderr, "healthcheck failed: status %d\n", resp.StatusCode)
269+
return 1
270+
}
271+
return 0
272+
}
273+
234274
// runAgent runs labelgate in agent mode.
235275
func runAgent(ctx context.Context, cfg *config.Config) error {
236276
// Initialize Docker provider

compose.dev.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ services:
5151
# - "8081:8081"
5252

5353
healthcheck:
54-
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080/api/health"]
54+
test: ["/app/labelgate", "healthcheck"]
5555
interval: 30s
5656
timeout: 3s
5757
retries: 3

full.Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ EXPOSE 8080 8081
6969

7070
# Health check
7171
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
72-
CMD wget -q --spider http://localhost:8080/api/health || exit 1
72+
CMD ["/app/labelgate", "healthcheck"]
7373

7474
# Default command
7575
ENTRYPOINT ["/app/labelgate"]

0 commit comments

Comments
 (0)