refactor: configuration agnostic healthcheck (#2231)
This makes the healthcheck simple and configured directly by Authelia's configuration on startup.pull/2239/head^2
parent
cbedf79f86
commit
c5c6bda8b0
|
@ -21,3 +21,6 @@ examples
|
|||
internal/server/public_html
|
||||
authelia.service
|
||||
bootstrap.sh
|
||||
|
||||
# Overrides
|
||||
!.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=
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
<div markdown="1">
|
||||
type: boolean
|
||||
{: .label .label-config .label-purple }
|
||||
default: false
|
||||
{: .label .label-config .label-blue }
|
||||
required: no
|
||||
{: .label .label-config .label-green }
|
||||
</div>
|
||||
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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"`
|
||||
}
|
||||
|
|
|
@ -139,6 +139,7 @@ var ValidKeys = []string{
|
|||
"server.path",
|
||||
"server.enable_pprof",
|
||||
"server.enable_expvars",
|
||||
"server.disable_healthcheck",
|
||||
"server.tls.key",
|
||||
"server.tls.certificate",
|
||||
|
||||
|
|
|
@ -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
|
||||
`
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue