diff --git a/.dockerignore b/.dockerignore
index 1a3b82626..c14a03acc 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -21,3 +21,6 @@ examples
internal/server/public_html
authelia.service
bootstrap.sh
+
+# Overrides
+!.healthcheck.env
diff --git a/.healthcheck.env b/.healthcheck.env
new file mode 100644
index 000000000..20df13dd0
--- /dev/null
+++ b/.healthcheck.env
@@ -0,0 +1,5 @@
+# Default Template
+X_AUTHELIA_HEALTHCHECK_SCHEME=http
+X_AUTHELIA_HEALTHCHECK_HOST=localhost
+X_AUTHELIA_HEALTHCHECK_PORT=9091
+X_AUTHELIA_HEALTHCHECK_PATH=
diff --git a/Dockerfile b/Dockerfile
index ced510a5e..3274125f9 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -17,6 +17,7 @@ ARG LDFLAGS_EXTRA
RUN \
mv public_html internal/server/public_html && \
+chmod 0666 /go/src/app/.healthcheck.env && \
echo ">> Starting go build..." && \
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -tags netgo \
-ldflags "-s -w ${LDFLAGS_EXTRA}" -trimpath -o authelia ./cmd/authelia
@@ -30,7 +31,7 @@ WORKDIR /app
RUN apk --no-cache add ca-certificates su-exec tzdata
-COPY --from=builder-backend /go/src/app/authelia /go/src/app/LICENSE /go/src/app/entrypoint.sh /go/src/app/healthcheck.sh ./
+COPY --from=builder-backend /go/src/app/authelia /go/src/app/LICENSE /go/src/app/entrypoint.sh /go/src/app/healthcheck.sh /go/src/app/.healthcheck.env ./
EXPOSE 9091
diff --git a/Dockerfile.arm32v7 b/Dockerfile.arm32v7
index bfced427b..ec4724dc9 100644
--- a/Dockerfile.arm32v7
+++ b/Dockerfile.arm32v7
@@ -17,6 +17,7 @@ ARG LDFLAGS_EXTRA
RUN \
mv public_html internal/server/public_html && \
+chmod 0666 /go/src/app/.healthcheck.env && \
echo ">> Starting go build..." && \
GOOS=linux GOARCH=arm CGO_ENABLED=0 go build -tags netgo \
-ldflags "-s -w ${LDFLAGS_EXTRA}" -trimpath -o authelia ./cmd/authelia
@@ -31,7 +32,7 @@ WORKDIR /app
RUN \
apk --no-cache add ca-certificates su-exec tzdata
-COPY --from=builder-backend /go/src/app/authelia /go/src/app/LICENSE /go/src/app/entrypoint.sh /go/src/app/healthcheck.sh ./
+COPY --from=builder-backend /go/src/app/authelia /go/src/app/LICENSE /go/src/app/entrypoint.sh /go/src/app/healthcheck.sh /go/src/app/.healthcheck.env ./
EXPOSE 9091
diff --git a/Dockerfile.arm64v8 b/Dockerfile.arm64v8
index 9d0985747..a645e19d7 100644
--- a/Dockerfile.arm64v8
+++ b/Dockerfile.arm64v8
@@ -17,6 +17,7 @@ ARG LDFLAGS_EXTRA
RUN \
mv public_html internal/server/public_html && \
+chmod 0666 /go/src/app/.healthcheck.env && \
echo ">> Starting go build..." && \
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -tags netgo \
-ldflags "-s -w ${LDFLAGS_EXTRA}" -trimpath -o authelia ./cmd/authelia
@@ -31,7 +32,7 @@ WORKDIR /app
RUN \
apk --no-cache add ca-certificates su-exec tzdata
-COPY --from=builder-backend /go/src/app/authelia /go/src/app/LICENSE /go/src/app/entrypoint.sh /go/src/app/healthcheck.sh ./
+COPY --from=builder-backend /go/src/app/authelia /go/src/app/LICENSE /go/src/app/entrypoint.sh /go/src/app/healthcheck.sh /go/src/app/.healthcheck.env ./
EXPOSE 9091
diff --git a/Dockerfile.coverage b/Dockerfile.coverage
index 225ed9a01..6c34d60d2 100644
--- a/Dockerfile.coverage
+++ b/Dockerfile.coverage
@@ -32,6 +32,7 @@ ARG LDFLAGS_EXTRA
RUN \
mv api internal/server/public_html/api && \
cd cmd/authelia && \
+chmod 0666 /go/src/app/.healthcheck.env && \
echo ">> Starting go build (coverage via go test)..." && \
CGO_ENABLED=0 go test -c --tags coverage -covermode=atomic \
-ldflags "${LDFLAGS_EXTRA}" -o authelia -coverpkg github.com/authelia/authelia/...
@@ -45,7 +46,7 @@ RUN apk --no-cache add ca-certificates tzdata
WORKDIR /app
-COPY --from=builder-backend /go/src/app/cmd/authelia/authelia /go/src/app/LICENSE /go/src/app/healthcheck.sh ./
+COPY --from=builder-backend /go/src/app/cmd/authelia/authelia /go/src/app/LICENSE /go/src/app/healthcheck.sh /go/src/app/.healthcheck.env ./
EXPOSE 9091
diff --git a/config.template.yml b/config.template.yml
index c552a45af..356e909dd 100644
--- a/config.template.yml
+++ b/config.template.yml
@@ -53,6 +53,10 @@ server:
## Enables the expvars endpoint.
enable_expvars: false
+ ## Disables writing the health check vars to /app/.healthcheck.env which makes healthcheck.sh return exit code 0.
+ ## This is disabled by default if either /app/.healthcheck.env or /app/healthcheck.sh do not exist.
+ disable_healthcheck: false
+
## Authelia by default doesn't accept TLS communication on the server port. This section overrides this behaviour.
tls:
## The path to the DER base64/PEM format private key.
diff --git a/docs/configuration/server.md b/docs/configuration/server.md
index 40172e93a..3acbb5095 100644
--- a/docs/configuration/server.md
+++ b/docs/configuration/server.md
@@ -20,6 +20,7 @@ server:
write_buffer_size: 4096
enable_pprof: false
enable_expvars: false
+ disable_healthcheck: false
tls:
key: ""
certificate: ""
@@ -134,6 +135,23 @@ required: no
Enables the go expvars endpoints.
+### disable_healthcheck
+
+type: boolean
+{: .label .label-config .label-purple }
+default: false
+{: .label .label-config .label-blue }
+required: no
+{: .label .label-config .label-green }
+
+
+On startup Authelia checks for the existence of /app/healthcheck.sh and /app/.healthcheck.env and if both of these exist
+it writes the configuration vars for the healthcheck to the /app/.healthcheck.env file. In instances where this is not
+desirable it's possible to disable these interactions entirely.
+
+An example situation where this is the case is in Kubernetes when set security policies that prevent writing to the
+ephemeral storage of a container or just don't want to enable the internal health check.
+
### tls
Authelia typically listens for plain unencrypted connections. This is by design as most environments allow to
diff --git a/healthcheck.sh b/healthcheck.sh
index 147e18d74..afd152fae 100755
--- a/healthcheck.sh
+++ b/healthcheck.sh
@@ -1,23 +1,21 @@
#!/bin/sh
-AUTHELIA_CONFIG=$(pgrep -af authelia | awk '{print $NF}')
-AUTHELIA_SCHEME=$(grep ^tls "${AUTHELIA_CONFIG}")
-AUTHELIA_HOST=$(grep ^host "${AUTHELIA_CONFIG}" | sed -e 's/host: //' -e 's/\r//')
-AUTHELIA_PORT=$(grep ^port "${AUTHELIA_CONFIG}" | sed -e 's/port: //' -e 's/\r//')
-AUTHELIA_PATH=$(grep ^\ \ path "${AUTHELIA_CONFIG}" | sed -e 's/ path: //' -e 's/\r//' -e 's/^/\//')
-
-if [ -z "${AUTHELIA_SCHEME}" ]; then
- AUTHELIA_SCHEME=http
-else
- AUTHELIA_SCHEME=https
+if [ -z "${X_AUTHELIA_HEALTHCHECK}" ]; then
+ exit 0
fi
-if [ -z "${AUTHELIA_HOST}" ] || [ "${AUTHELIA_HOST}" = "0.0.0.0" ]; then
- AUTHELIA_HOST=localhost
+source /app/.healthcheck.env
+
+if [ -z "${X_AUTHELIA_HEALTHCHECK_SCHEME}" ]; then
+ X_AUTHELIA_HEALTHCHECK_SCHEME=http
fi
-if [ -z "${AUTHELIA_PORT}" ]; then
- AUTHELIA_PORT=9091
+if [ -z "${X_AUTHELIA_HEALTHCHECK_HOST}" ]; then
+ X_AUTHELIA_HEALTHCHECK_HOST=localhost
fi
-wget --quiet --no-check-certificate --tries=1 --spider "${AUTHELIA_SCHEME}://${AUTHELIA_HOST}:${AUTHELIA_PORT}${AUTHELIA_PATH}/api/health" || exit 1
+if [ -z "${X_AUTHELIA_HEALTHCHECK_PORT}" ]; then
+ X_AUTHELIA_HEALTHCHECK_PORT=9091
+fi
+
+wget --quiet --no-check-certificate --tries=1 --spider "${X_AUTHELIA_HEALTHCHECK_SCHEME}://${X_AUTHELIA_HEALTHCHECK_HOST}:${X_AUTHELIA_HEALTHCHECK_PORT}${X_AUTHELIA_HEALTHCHECK_PATH}/api/health" || exit 1
diff --git a/internal/configuration/config.template.yml b/internal/configuration/config.template.yml
index c552a45af..356e909dd 100644
--- a/internal/configuration/config.template.yml
+++ b/internal/configuration/config.template.yml
@@ -53,6 +53,10 @@ server:
## Enables the expvars endpoint.
enable_expvars: false
+ ## Disables writing the health check vars to /app/.healthcheck.env which makes healthcheck.sh return exit code 0.
+ ## This is disabled by default if either /app/.healthcheck.env or /app/healthcheck.sh do not exist.
+ disable_healthcheck: false
+
## Authelia by default doesn't accept TLS communication on the server port. This section overrides this behaviour.
tls:
## The path to the DER base64/PEM format private key.
diff --git a/internal/configuration/schema/server.go b/internal/configuration/schema/server.go
index 07169ad8a..d07165cb0 100644
--- a/internal/configuration/schema/server.go
+++ b/internal/configuration/schema/server.go
@@ -2,13 +2,14 @@ package schema
// ServerConfiguration represents the configuration of the http server.
type ServerConfiguration struct {
- Host string `koanf:"host"`
- Port int `koanf:"port"`
- Path string `koanf:"path"`
- ReadBufferSize int `koanf:"read_buffer_size"`
- WriteBufferSize int `koanf:"write_buffer_size"`
- EnablePprof bool `koanf:"enable_endpoint_pprof"`
- EnableExpvars bool `koanf:"enable_endpoint_expvars"`
+ Host string `koanf:"host"`
+ Port int `koanf:"port"`
+ Path string `koanf:"path"`
+ ReadBufferSize int `koanf:"read_buffer_size"`
+ WriteBufferSize int `koanf:"write_buffer_size"`
+ EnablePprof bool `koanf:"enable_endpoint_pprof"`
+ EnableExpvars bool `koanf:"enable_endpoint_expvars"`
+ DisableHealthcheck bool `koanf:"disable_healthcheck"`
TLS ServerTLSConfiguration `koanf:"tls"`
}
diff --git a/internal/configuration/validator/const.go b/internal/configuration/validator/const.go
index e15420db9..590d56c2c 100644
--- a/internal/configuration/validator/const.go
+++ b/internal/configuration/validator/const.go
@@ -139,6 +139,7 @@ var ValidKeys = []string{
"server.path",
"server.enable_pprof",
"server.enable_expvars",
+ "server.disable_healthcheck",
"server.tls.key",
"server.tls.certificate",
diff --git a/internal/server/const.go b/internal/server/const.go
index 6950d07f5..9251aa95e 100644
--- a/internal/server/const.go
+++ b/internal/server/const.go
@@ -6,3 +6,11 @@ const apiFile = "openapi.yml"
const indexFile = "index.html"
const dev = "dev"
+
+const healthCheckEnv = `# Written by Authelia Process
+X_AUTHELIA_HEALTHCHECK=1
+X_AUTHELIA_HEALTHCHECK_SCHEME=%s
+X_AUTHELIA_HEALTHCHECK_HOST=%s
+X_AUTHELIA_HEALTHCHECK_PORT=%d
+X_AUTHELIA_HEALTHCHECK_PATH=%s
+`
diff --git a/internal/server/server.go b/internal/server/server.go
index ef5c2f6ce..a12eb850e 100644
--- a/internal/server/server.go
+++ b/internal/server/server.go
@@ -192,9 +192,17 @@ func Start(configuration schema.Configuration, providers middlewares.Providers)
}
if configuration.Server.TLS.Certificate != "" && configuration.Server.TLS.Key != "" {
+ if err = writeHealthCheckEnv(configuration.Server.DisableHealthcheck, "https", configuration.Server.Host, configuration.Server.Path, configuration.Server.Port); err != nil {
+ logger.Fatalf("Could not configure healthcheck: %v", err)
+ }
+
logger.Infof("Listening for TLS connections on %s%s", addrPattern, configuration.Server.Path)
logger.Fatal(server.ServeTLS(listener, configuration.Server.TLS.Certificate, configuration.Server.TLS.Key))
} else {
+ if err = writeHealthCheckEnv(configuration.Server.DisableHealthcheck, "http", configuration.Server.Host, configuration.Server.Path, configuration.Server.Port); err != nil {
+ logger.Fatalf("Could not configure healthcheck: %v", err)
+ }
+
logger.Infof("Listening for non-TLS connections on %s%s", addrPattern, configuration.Server.Path)
logger.Fatal(server.Serve(listener))
}
diff --git a/internal/server/template.go b/internal/server/template.go
index 1c65fb55f..70c327fd0 100644
--- a/internal/server/template.go
+++ b/internal/server/template.go
@@ -64,3 +64,36 @@ func ServeTemplatedFile(publicDir, file, base, rememberMe, resetPassword, sessio
}
}
}
+
+func writeHealthCheckEnv(disabled bool, scheme, host, path string, port int) (err error) {
+ if disabled {
+ return nil
+ }
+
+ _, err = os.Stat("/app/healthcheck.sh")
+ if err != nil {
+ return nil
+ }
+
+ _, err = os.Stat("/app/.healthcheck.env")
+ if err != nil {
+ return nil
+ }
+
+ file, err := os.OpenFile("/app/.healthcheck.env", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
+ if err != nil {
+ return err
+ }
+
+ defer func() {
+ _ = file.Close()
+ }()
+
+ if host == "0.0.0.0" {
+ host = "localhost"
+ }
+
+ _, err = file.WriteString(fmt.Sprintf(healthCheckEnv, scheme, host, port, path))
+
+ return err
+}