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
|
internal/server/public_html
|
||||||
authelia.service
|
authelia.service
|
||||||
bootstrap.sh
|
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 \
|
RUN \
|
||||||
mv public_html internal/server/public_html && \
|
mv public_html internal/server/public_html && \
|
||||||
|
chmod 0666 /go/src/app/.healthcheck.env && \
|
||||||
echo ">> Starting go build..." && \
|
echo ">> Starting go build..." && \
|
||||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -tags netgo \
|
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -tags netgo \
|
||||||
-ldflags "-s -w ${LDFLAGS_EXTRA}" -trimpath -o authelia ./cmd/authelia
|
-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
|
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
|
EXPOSE 9091
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ ARG LDFLAGS_EXTRA
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
mv public_html internal/server/public_html && \
|
mv public_html internal/server/public_html && \
|
||||||
|
chmod 0666 /go/src/app/.healthcheck.env && \
|
||||||
echo ">> Starting go build..." && \
|
echo ">> Starting go build..." && \
|
||||||
GOOS=linux GOARCH=arm CGO_ENABLED=0 go build -tags netgo \
|
GOOS=linux GOARCH=arm CGO_ENABLED=0 go build -tags netgo \
|
||||||
-ldflags "-s -w ${LDFLAGS_EXTRA}" -trimpath -o authelia ./cmd/authelia
|
-ldflags "-s -w ${LDFLAGS_EXTRA}" -trimpath -o authelia ./cmd/authelia
|
||||||
|
@ -31,7 +32,7 @@ WORKDIR /app
|
||||||
RUN \
|
RUN \
|
||||||
apk --no-cache add ca-certificates su-exec tzdata
|
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
|
EXPOSE 9091
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ ARG LDFLAGS_EXTRA
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
mv public_html internal/server/public_html && \
|
mv public_html internal/server/public_html && \
|
||||||
|
chmod 0666 /go/src/app/.healthcheck.env && \
|
||||||
echo ">> Starting go build..." && \
|
echo ">> Starting go build..." && \
|
||||||
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -tags netgo \
|
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -tags netgo \
|
||||||
-ldflags "-s -w ${LDFLAGS_EXTRA}" -trimpath -o authelia ./cmd/authelia
|
-ldflags "-s -w ${LDFLAGS_EXTRA}" -trimpath -o authelia ./cmd/authelia
|
||||||
|
@ -31,7 +32,7 @@ WORKDIR /app
|
||||||
RUN \
|
RUN \
|
||||||
apk --no-cache add ca-certificates su-exec tzdata
|
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
|
EXPOSE 9091
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ ARG LDFLAGS_EXTRA
|
||||||
RUN \
|
RUN \
|
||||||
mv api internal/server/public_html/api && \
|
mv api internal/server/public_html/api && \
|
||||||
cd cmd/authelia && \
|
cd cmd/authelia && \
|
||||||
|
chmod 0666 /go/src/app/.healthcheck.env && \
|
||||||
echo ">> Starting go build (coverage via go test)..." && \
|
echo ">> Starting go build (coverage via go test)..." && \
|
||||||
CGO_ENABLED=0 go test -c --tags coverage -covermode=atomic \
|
CGO_ENABLED=0 go test -c --tags coverage -covermode=atomic \
|
||||||
-ldflags "${LDFLAGS_EXTRA}" -o authelia -coverpkg github.com/authelia/authelia/...
|
-ldflags "${LDFLAGS_EXTRA}" -o authelia -coverpkg github.com/authelia/authelia/...
|
||||||
|
@ -45,7 +46,7 @@ RUN apk --no-cache add ca-certificates tzdata
|
||||||
|
|
||||||
WORKDIR /app
|
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
|
EXPOSE 9091
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,10 @@ server:
|
||||||
## Enables the expvars endpoint.
|
## Enables the expvars endpoint.
|
||||||
enable_expvars: false
|
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.
|
## Authelia by default doesn't accept TLS communication on the server port. This section overrides this behaviour.
|
||||||
tls:
|
tls:
|
||||||
## The path to the DER base64/PEM format private key.
|
## The path to the DER base64/PEM format private key.
|
||||||
|
|
|
@ -20,6 +20,7 @@ server:
|
||||||
write_buffer_size: 4096
|
write_buffer_size: 4096
|
||||||
enable_pprof: false
|
enable_pprof: false
|
||||||
enable_expvars: false
|
enable_expvars: false
|
||||||
|
disable_healthcheck: false
|
||||||
tls:
|
tls:
|
||||||
key: ""
|
key: ""
|
||||||
certificate: ""
|
certificate: ""
|
||||||
|
@ -134,6 +135,23 @@ required: no
|
||||||
|
|
||||||
Enables the go expvars endpoints.
|
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
|
### tls
|
||||||
|
|
||||||
Authelia typically listens for plain unencrypted connections. This is by design as most environments allow to
|
Authelia typically listens for plain unencrypted connections. This is by design as most environments allow to
|
||||||
|
|
|
@ -1,23 +1,21 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
AUTHELIA_CONFIG=$(pgrep -af authelia | awk '{print $NF}')
|
if [ -z "${X_AUTHELIA_HEALTHCHECK}" ]; then
|
||||||
AUTHELIA_SCHEME=$(grep ^tls "${AUTHELIA_CONFIG}")
|
exit 0
|
||||||
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
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${AUTHELIA_HOST}" ] || [ "${AUTHELIA_HOST}" = "0.0.0.0" ]; then
|
source /app/.healthcheck.env
|
||||||
AUTHELIA_HOST=localhost
|
|
||||||
|
if [ -z "${X_AUTHELIA_HEALTHCHECK_SCHEME}" ]; then
|
||||||
|
X_AUTHELIA_HEALTHCHECK_SCHEME=http
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${AUTHELIA_PORT}" ]; then
|
if [ -z "${X_AUTHELIA_HEALTHCHECK_HOST}" ]; then
|
||||||
AUTHELIA_PORT=9091
|
X_AUTHELIA_HEALTHCHECK_HOST=localhost
|
||||||
fi
|
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.
|
## Enables the expvars endpoint.
|
||||||
enable_expvars: false
|
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.
|
## Authelia by default doesn't accept TLS communication on the server port. This section overrides this behaviour.
|
||||||
tls:
|
tls:
|
||||||
## The path to the DER base64/PEM format private key.
|
## The path to the DER base64/PEM format private key.
|
||||||
|
|
|
@ -9,6 +9,7 @@ type ServerConfiguration struct {
|
||||||
WriteBufferSize int `koanf:"write_buffer_size"`
|
WriteBufferSize int `koanf:"write_buffer_size"`
|
||||||
EnablePprof bool `koanf:"enable_endpoint_pprof"`
|
EnablePprof bool `koanf:"enable_endpoint_pprof"`
|
||||||
EnableExpvars bool `koanf:"enable_endpoint_expvars"`
|
EnableExpvars bool `koanf:"enable_endpoint_expvars"`
|
||||||
|
DisableHealthcheck bool `koanf:"disable_healthcheck"`
|
||||||
|
|
||||||
TLS ServerTLSConfiguration `koanf:"tls"`
|
TLS ServerTLSConfiguration `koanf:"tls"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,6 +139,7 @@ var ValidKeys = []string{
|
||||||
"server.path",
|
"server.path",
|
||||||
"server.enable_pprof",
|
"server.enable_pprof",
|
||||||
"server.enable_expvars",
|
"server.enable_expvars",
|
||||||
|
"server.disable_healthcheck",
|
||||||
"server.tls.key",
|
"server.tls.key",
|
||||||
"server.tls.certificate",
|
"server.tls.certificate",
|
||||||
|
|
||||||
|
|
|
@ -6,3 +6,11 @@ const apiFile = "openapi.yml"
|
||||||
const indexFile = "index.html"
|
const indexFile = "index.html"
|
||||||
|
|
||||||
const dev = "dev"
|
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 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.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))
|
logger.Fatal(server.ServeTLS(listener, configuration.Server.TLS.Certificate, configuration.Server.TLS.Key))
|
||||||
} else {
|
} 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.Infof("Listening for non-TLS connections on %s%s", addrPattern, configuration.Server.Path)
|
||||||
logger.Fatal(server.Serve(listener))
|
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