Răsfoiți Sursa

Add more extensive healthcheck support

- Add new cli argument: -healthcheck
- Add HEALTHCHECK instruction to Dockerfile
- Update Docker Compose examples
Frédéric Guillot 5 ani în urmă
părinte
comite
bbf93430b7

+ 8 - 0
cli/cli.go

@@ -28,6 +28,7 @@ const (
 	flagDebugModeHelp       = "Show debug logs"
 	flagConfigFileHelp      = "Load configuration file"
 	flagConfigDumpHelp      = "Print parsed configuration values"
+	flagHealthCheckHelp     = `Perform a health check on the given endpoint (the value "auto" try to guess the health check endpoint).`
 )
 
 // Parse parses command line arguments.
@@ -44,6 +45,7 @@ func Parse() {
 		flagDebugMode       bool
 		flagConfigFile      string
 		flagConfigDump      bool
+		flagHealthCheck     string
 	)
 
 	flag.BoolVar(&flagInfo, "info", false, flagInfoHelp)
@@ -59,6 +61,7 @@ func Parse() {
 	flag.StringVar(&flagConfigFile, "config-file", "", flagConfigFileHelp)
 	flag.StringVar(&flagConfigFile, "c", "", flagConfigFileHelp)
 	flag.BoolVar(&flagConfigDump, "config-dump", false, flagConfigDumpHelp)
+	flag.StringVar(&flagHealthCheck, "healthcheck", "", flagHealthCheckHelp)
 	flag.Parse()
 
 	cfg := config.NewParser()
@@ -88,6 +91,11 @@ func Parse() {
 		logger.EnableDebug()
 	}
 
+	if flagHealthCheck != "" {
+		doHealthCheck(flagHealthCheck)
+		return
+	}
+
 	if flagInfo {
 		info()
 		return

+ 34 - 0
cli/health_check.go

@@ -0,0 +1,34 @@
+// Copyright 2021 Frédéric Guillot. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+package cli // import "miniflux.app/cli"
+
+import (
+	"net/http"
+	"time"
+
+	"miniflux.app/config"
+	"miniflux.app/logger"
+)
+
+func doHealthCheck(healthCheckEndpoint string) {
+	if healthCheckEndpoint == "auto" {
+		healthCheckEndpoint = "http://" + config.Opts.ListenAddr() + config.Opts.BasePath() + "/healthcheck"
+	}
+
+	logger.Debug(`Executing health check on %s`, healthCheckEndpoint)
+
+	client := &http.Client{Timeout: 3 * time.Second}
+	resp, err := client.Get(healthCheckEndpoint)
+	if err != nil {
+		logger.Fatal(`Health check failure: %v`, err)
+	}
+	defer resp.Body.Close()
+
+	if resp.StatusCode != 200 {
+		logger.Fatal(`Health check failed with status code %d`, resp.StatusCode)
+	}
+
+	logger.Debug(`Health check is OK`)
+}

+ 8 - 1
contrib/docker-compose/basic.yml

@@ -3,16 +3,19 @@ services:
   miniflux:
     image: miniflux/miniflux:latest
     container_name: miniflux
+    restart: always
     ports:
       - "80:8080"
     depends_on:
-      - db
+      db:
+        condition: service_healthy
     environment:
       - DATABASE_URL=postgres://miniflux:secret@db/miniflux?sslmode=disable
       - RUN_MIGRATIONS=1
       - CREATE_ADMIN=1
       - ADMIN_USERNAME=admin
       - ADMIN_PASSWORD=test123
+      - DEBUG=1
   db:
     image: postgres:latest
     container_name: postgres
@@ -21,5 +24,9 @@ services:
       - POSTGRES_PASSWORD=secret
     volumes:
       - miniflux-db:/var/lib/postgresql/data
+    healthcheck:
+      test: ["CMD", "pg_isready", "-U", "miniflux"]
+      interval: 10s
+      start_period: 30s
 volumes:
   miniflux-db:

+ 6 - 1
contrib/docker-compose/caddy.yml

@@ -16,7 +16,8 @@ services:
     image: miniflux/miniflux:latest
     container_name: miniflux
     depends_on:
-      - db
+      db:
+        condition: service_healthy
     environment:
       - DATABASE_URL=postgres://miniflux:secret@db/miniflux?sslmode=disable
       - RUN_MIGRATIONS=1
@@ -32,6 +33,10 @@ services:
       - POSTGRES_PASSWORD=secret
     volumes:
       - miniflux-db:/var/lib/postgresql/data
+    healthcheck:
+      test: ["CMD", "pg_isready", "-U", "miniflux"]
+      interval: 10s
+      start_period: 30s
 volumes:
   miniflux-db:
   caddy_data:

+ 6 - 1
contrib/docker-compose/traefik.yml

@@ -21,7 +21,8 @@ services:
     image: miniflux/miniflux:latest
     container_name: miniflux
     depends_on:
-      - db
+      db:
+        condition: service_healthy
     expose:
       - "8080"
     environment:
@@ -44,5 +45,9 @@ services:
       - POSTGRES_PASSWORD=secret
     volumes:
       - miniflux-db:/var/lib/postgresql/data
+    healthcheck:
+      test: ["CMD", "pg_isready", "-U", "miniflux"]
+      interval: 10s
+      start_period: 30s
 volumes:
   miniflux-db:

+ 8 - 1
miniflux.1

@@ -1,5 +1,5 @@
 .\" Manpage for miniflux.
-.TH "MINIFLUX" "1" "September 28, 2020" "\ \&" "\ \&"
+.TH "MINIFLUX" "1" "February 20, 2021" "\ \&" "\ \&"
 
 .SH NAME
 miniflux \- Minimalist and opinionated feed reader
@@ -43,6 +43,13 @@ Show debug logs\&.
 Flush all sessions (disconnect users)\&.
 .RE
 .PP
+.B \-healthcheck
+.RS 4
+Perform a health check on the given endpoint\&.
+.br
+The value "auto" try to guess the health check endpoint\&.
+.RE
+.PP
 .B \-i
 .RS 4
 Show application information\&.

+ 1 - 1
packaging/docker/Dockerfile

@@ -20,7 +20,7 @@ LABEL org.opencontainers.image.documentation=https://miniflux.app/docs/
 
 EXPOSE 8080
 ENV LISTEN_ADDR 0.0.0.0:8080
-
+HEALTHCHECK --start-period=30s CMD ["/usr/bin/miniflux", "-healthcheck", "auto"]
 RUN apk --no-cache add ca-certificates tzdata
 COPY --from=build /go/src/app/miniflux /usr/bin/miniflux
 USER nobody