feat(configuration): env config file discovery (#4618)
This allows Authelia to discover config files and config options via environment variables. Co-authored-by: Amir Zarrinkafsh <nightah@me.com>pull/4632/head
parent
18032dd05d
commit
0130edb870
|
@ -11,15 +11,16 @@ WORKDIR /app
|
|||
# Set environment variables
|
||||
ENV PATH="/app:${PATH}" \
|
||||
PUID=0 \
|
||||
PGID=0
|
||||
PGID=0 \
|
||||
X_AUTHELIA_CONFIG="/config/configuration.yml"
|
||||
|
||||
RUN \
|
||||
apk --no-cache add ca-certificates su-exec tzdata
|
||||
apk --no-cache add ca-certificates su-exec tzdata
|
||||
|
||||
COPY LICENSE .healthcheck.env entrypoint.sh healthcheck.sh ./
|
||||
|
||||
RUN \
|
||||
chmod 0666 /app/.healthcheck.env
|
||||
chmod 0666 /app/.healthcheck.env
|
||||
|
||||
COPY authelia-${TARGETOS}-${TARGETARCH}-musl ./authelia
|
||||
|
||||
|
@ -28,5 +29,4 @@ EXPOSE 9091
|
|||
VOLUME /config
|
||||
|
||||
ENTRYPOINT ["/app/entrypoint.sh"]
|
||||
CMD ["--config", "/config/configuration.yml"]
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=1m CMD /app/healthcheck.sh
|
||||
|
|
|
@ -20,14 +20,14 @@ FROM golang:1.19.4-alpine AS builder-backend
|
|||
WORKDIR /go/src/app
|
||||
|
||||
RUN \
|
||||
echo ">> Downloading required apk's..." && \
|
||||
apk --no-cache add gcc musl-dev
|
||||
echo ">> Downloading required apk's..." && \
|
||||
apk --no-cache add gcc musl-dev
|
||||
|
||||
COPY go.mod go.sum ./
|
||||
|
||||
RUN \
|
||||
echo ">> Downloading go modules..." && \
|
||||
go mod download
|
||||
echo ">> Downloading go modules..." && \
|
||||
go mod download
|
||||
|
||||
COPY / ./
|
||||
|
||||
|
@ -36,12 +36,12 @@ COPY --from=builder-frontend /node/src/internal/server/public_html internal/serv
|
|||
|
||||
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=1 CGO_CPPFLAGS="-D_FORTIFY_SOURCE=2 -fstack-protector-strong" CGO_LDFLAGS="-Wl,-z,relro,-z,now" go test -c --tags coverage -covermode=atomic \
|
||||
-ldflags "${LDFLAGS_EXTRA}" -o authelia -coverpkg github.com/authelia/authelia/...
|
||||
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=1 CGO_CPPFLAGS="-D_FORTIFY_SOURCE=2 -fstack-protector-strong" CGO_LDFLAGS="-Wl,-z,relro,-z,now" go test -c --tags coverage -covermode=atomic \
|
||||
-ldflags "${LDFLAGS_EXTRA}" -o authelia -coverpkg github.com/authelia/authelia/...
|
||||
|
||||
# ===================================
|
||||
# ===== Authelia official image =====
|
||||
|
@ -58,7 +58,8 @@ EXPOSE 9091
|
|||
|
||||
VOLUME /config
|
||||
|
||||
ENV PATH="/app:${PATH}"
|
||||
ENV PATH="/app:${PATH}" \
|
||||
X_AUTHELIA_CONFIG="/config/configuration.yml"
|
||||
|
||||
CMD ["authelia", "-test.coverprofile=/authelia/coverage.txt", "COVERAGE", "--config", "/config/configuration.yml"]
|
||||
CMD ["authelia", "-test.coverprofile=/authelia/coverage.txt", "COVERAGE"]
|
||||
HEALTHCHECK --interval=30s --timeout=3s CMD /app/healthcheck.sh
|
||||
|
|
|
@ -18,14 +18,14 @@ FROM golang:1.19.4-alpine AS builder-backend
|
|||
WORKDIR /go/src/app
|
||||
|
||||
RUN \
|
||||
echo ">> Downloading required apk's..." && \
|
||||
apk --no-cache add gcc musl-dev
|
||||
echo ">> Downloading required apk's..." && \
|
||||
apk --no-cache add gcc musl-dev
|
||||
|
||||
COPY go.mod go.sum ./
|
||||
|
||||
RUN \
|
||||
echo ">> Downloading go modules..." && \
|
||||
go mod download
|
||||
echo ">> Downloading go modules..." && \
|
||||
go mod download
|
||||
|
||||
COPY / ./
|
||||
|
||||
|
@ -34,11 +34,11 @@ COPY --from=builder-frontend /node/src/internal/server/public_html internal/serv
|
|||
|
||||
ARG LDFLAGS_EXTRA
|
||||
RUN \
|
||||
mv api internal/server/public_html/api && \
|
||||
chmod 0666 /go/src/app/.healthcheck.env && \
|
||||
echo ">> Starting go build..." && \
|
||||
CGO_ENABLED=1 CGO_CPPFLAGS="-D_FORTIFY_SOURCE=2 -fstack-protector-strong" CGO_LDFLAGS="-Wl,-z,relro,-z,now" go build \
|
||||
-ldflags "-linkmode=external -s -w ${LDFLAGS_EXTRA}" -trimpath -buildmode=pie -o authelia ./cmd/authelia
|
||||
mv api internal/server/public_html/api && \
|
||||
chmod 0666 /go/src/app/.healthcheck.env && \
|
||||
echo ">> Starting go build..." && \
|
||||
CGO_ENABLED=1 CGO_CPPFLAGS="-D_FORTIFY_SOURCE=2 -fstack-protector-strong" CGO_LDFLAGS="-Wl,-z,relro,-z,now" go build \
|
||||
-ldflags "-linkmode=external -s -w ${LDFLAGS_EXTRA}" -trimpath -buildmode=pie -o authelia ./cmd/authelia
|
||||
|
||||
# ===================================
|
||||
# ===== Authelia official image =====
|
||||
|
@ -50,20 +50,20 @@ WORKDIR /app
|
|||
# Set environment variables
|
||||
ENV PATH="/app:${PATH}" \
|
||||
PUID=0 \
|
||||
PGID=0
|
||||
PGID=0 \
|
||||
X_AUTHELIA_CONFIG="/config/configuration.yml"
|
||||
|
||||
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 /go/src/app/.healthcheck.env ./
|
||||
|
||||
RUN \
|
||||
chmod 0666 /app/.healthcheck.env
|
||||
chmod 0666 /app/.healthcheck.env
|
||||
|
||||
EXPOSE 9091
|
||||
|
||||
VOLUME /config
|
||||
|
||||
ENTRYPOINT ["/app/entrypoint.sh"]
|
||||
CMD ["--config", "/config/configuration.yml"]
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=1m CMD /app/healthcheck.sh
|
||||
|
|
|
@ -12,18 +12,23 @@ weight: 101200
|
|||
toc: true
|
||||
---
|
||||
|
||||
## Loading Behaviour
|
||||
## Loading Behaviour and Discovery
|
||||
|
||||
There are several options which affect the loading of files:
|
||||
|
||||
| Name | Argument | Description |
|
||||
|:-----------------:|:-------------------------------:|:----------------------------------------------------------------------------------:|
|
||||
| Files/Directories | `--config`, `-c` | A list of file or directory (non-recursive) paths to load configuration files from |
|
||||
| Filters | `--config.experimental.filters` | A list of filters applied to every file from the Files or Directories options |
|
||||
| Name | Argument | Environment Variable | Description |
|
||||
|:-----------------:|:-------------------------------:|:---------------------------:|:----------------------------------------------------------------------------------:|
|
||||
| Files/Directories | `--config`, `-c` | `X_AUTHELIA_CONFIG` | A list of file or directory (non-recursive) paths to load configuration files from |
|
||||
| Filters | `--config.experimental.filters` | `X_AUTHELIA_CONFIG_FILTERS` | A list of filters applied to every file from the Files or Directories options |
|
||||
|
||||
__*Note:* when specifying directories and files, the individual files specified must not be within any of the
|
||||
directories specified.__
|
||||
|
||||
Configuration options can be discovered via either the Argument or Environment Variable, but not both at the same time.
|
||||
If both are specified the Argument takes precedence and the Environment Variable is ignored. It is generally recommended
|
||||
that if you're using a container that you use the Environment Variable as this will allow you to execute other commands
|
||||
from the context of the container more easily.
|
||||
|
||||
## Formats
|
||||
|
||||
The only supported configuration file format is [YAML](#yaml).
|
||||
|
|
|
@ -537,9 +537,11 @@ const (
|
|||
cmdConfigDefaultContainer = "/config/configuration.yml"
|
||||
cmdConfigDefaultDaemon = "/etc/authelia/configuration.yml"
|
||||
|
||||
cmdFlagNameConfig = "config"
|
||||
cmdFlagNameConfig = "config"
|
||||
cmdFlagEnvNameConfig = "X_AUTHELIA_CONFIG"
|
||||
|
||||
cmdFlagNameConfigExpFilters = "config.experimental.filters"
|
||||
cmdFlagEnvNameConfigFilters = "X_AUTHELIA_CONFIG_FILTERS"
|
||||
|
||||
cmdFlagNameCharSet = "charset"
|
||||
cmdFlagValueCharSet = "alphanumeric"
|
||||
|
@ -655,4 +657,42 @@ The following filters are available:
|
|||
'expand-env' filter for example.
|
||||
|
||||
For a full list of functions see: https://www.authelia.com/configuration/methods/files/#functions`
|
||||
|
||||
helpTopicConfig = `Configuration can be specified in multiple layers where each layer is a different source from
|
||||
the last. The layers are loaded in the order below where each layer potentially overrides the individual settings from
|
||||
previous layers with the individual settings it provides (i.e. if the same setting is specified twice).
|
||||
|
||||
Layers:
|
||||
- File/Directory Paths
|
||||
- Environment Variables
|
||||
- Secrets
|
||||
|
||||
File/Directory Paths:
|
||||
|
||||
File/Directory Paths can be specified either via the '--config' CLI argument or the 'X_AUTHELIA_CONFIG' environment
|
||||
variable. If both the environment variable AND the CLI argument are specified the environment variable is completely
|
||||
ignored. These values both take lists separated by commas.
|
||||
|
||||
Directories that are loaded via this method load all files with relevant extensions from the directory, this is not
|
||||
recursive. This means all files with these extensions must be Authelia configuration files with valid syntax.
|
||||
|
||||
The paths specified are loaded in order, where individual settings specified by later files potentially overrides
|
||||
individual settings by later files (i.e. if the same setting is specified twice). Files specified Files in
|
||||
directories are loaded in lexicographic order.
|
||||
|
||||
The files loaded via this method can be interpolated or templated via the configuration filters. Read more about
|
||||
this topic by running: authelia -h authelia filters
|
||||
|
||||
Environment Variables:
|
||||
|
||||
Most configuration options in Authelia can be specified via an environment variable. The available options and the
|
||||
specific environment variable mapping can be found here: https://www.authelia.com/configuration/methods/environment/
|
||||
|
||||
Secrets:
|
||||
|
||||
Some configuration options in Authelia can be specified via an environment variable which refers to the location of
|
||||
a file; also known as a secret. Every configuration key that ends with the following strings can be loaded in this
|
||||
way: 'key', 'secret', 'password', 'token'.
|
||||
|
||||
The available options and the specific secret mapping can be found here: https://www.authelia.com/configuration/methods/secrets/`
|
||||
)
|
||||
|
|
|
@ -277,7 +277,7 @@ func (ctx *CmdCtx) ConfigEnsureExistsRunE(cmd *cobra.Command, _ []string) (err e
|
|||
result XEnvCLIResult
|
||||
)
|
||||
|
||||
if configs, result, err = loadXEnvCLIStringSliceValue(cmd, "", cmdFlagNameConfig); err != nil {
|
||||
if configs, result, err = loadXEnvCLIStringSliceValue(cmd, cmdFlagEnvNameConfig, cmdFlagNameConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -45,9 +45,9 @@ func NewRootCmd() (cmd *cobra.Command) {
|
|||
DisableAutoGenTag: true,
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().StringSliceP(cmdFlagNameConfig, "c", []string{"configuration.yml"}, "configuration files or directories to load")
|
||||
cmd.PersistentFlags().StringSliceP(cmdFlagNameConfig, "c", []string{"configuration.yml"}, "configuration files or directories to load, for more information run 'authelia -h authelia config'")
|
||||
|
||||
cmd.PersistentFlags().StringSlice(cmdFlagNameConfigExpFilters, nil, "list of filters to apply to all configuration files, for more information: authelia --help authelia filters")
|
||||
cmd.PersistentFlags().StringSlice(cmdFlagNameConfigExpFilters, nil, "list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters'")
|
||||
|
||||
cmd.AddCommand(
|
||||
newAccessControlCommand(ctx),
|
||||
|
@ -56,7 +56,8 @@ func NewRootCmd() (cmd *cobra.Command) {
|
|||
newStorageCmd(ctx),
|
||||
newValidateConfigCmd(ctx),
|
||||
|
||||
newHelpTopic("filters", "Help for the config filters", helpTopicConfigFilters),
|
||||
newHelpTopic("config", "Help for the config file/directory paths", helpTopicConfig),
|
||||
newHelpTopic("filters", "help topic for the config filters", helpTopicConfigFilters),
|
||||
)
|
||||
|
||||
return cmd
|
||||
|
|
|
@ -246,7 +246,7 @@ func loadXEnvCLIConfigValues(cmd *cobra.Command) (configs []string, filters []co
|
|||
filterNames []string
|
||||
)
|
||||
|
||||
if configs, _, err = loadXEnvCLIStringSliceValue(cmd, "", cmdFlagNameConfig); err != nil {
|
||||
if configs, _, err = loadXEnvCLIStringSliceValue(cmd, cmdFlagEnvNameConfig, cmdFlagNameConfig); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ func loadXEnvCLIConfigValues(cmd *cobra.Command) (configs []string, filters []co
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
if filterNames, _, err = loadXEnvCLIStringSliceValue(cmd, "", cmdFlagNameConfigExpFilters); err != nil {
|
||||
if filterNames, _, err = loadXEnvCLIStringSliceValue(cmd, cmdFlagEnvNameConfigFilters, cmdFlagNameConfigExpFilters); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@ RUN mkdir -p /config && chown dev:dev /config
|
|||
|
||||
USER dev
|
||||
|
||||
ENV PATH="/app:${PATH}"
|
||||
ENV PATH="/app:${PATH}" \
|
||||
X_AUTHELIA_CONFIG="/config/configuration.yml"
|
||||
|
||||
VOLUME /config
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ ARG USER_ID
|
|||
ARG GROUP_ID
|
||||
|
||||
RUN yarn global add pnpm && \
|
||||
pnpm config set --global store-dir /tmp/.pnpm-store && \
|
||||
deluser node && \
|
||||
addgroup --gid ${GROUP_ID} dev && \
|
||||
adduser --uid ${USER_ID} -G dev -D dev
|
||||
|
|
|
@ -14,7 +14,7 @@ services:
|
|||
volumes:
|
||||
- './example/compose/authelia/resources/:/resources'
|
||||
- '../../web:/app'
|
||||
- '~/.local/share/pnpm/store:/tmp/.pnpm-store'
|
||||
- '~/.local/share/pnpm/store:/app/.pnpm-store'
|
||||
labels:
|
||||
# Traefik 1.x
|
||||
- 'traefik.frontend.rule=Host:login.example.com'
|
||||
|
|
|
@ -4,6 +4,6 @@ set -e
|
|||
|
||||
while true;
|
||||
do
|
||||
AUTHELIA_SERVER_DISABLE_HEALTHCHECK=true CGO_ENABLED=1 dlv --listen 0.0.0.0:2345 --headless=true --output=./authelia --continue --accept-multiclient debug cmd/authelia/*.go -- --config /config/configuration.yml
|
||||
AUTHELIA_SERVER_DISABLE_HEALTHCHECK=true CGO_ENABLED=1 dlv --listen 0.0.0.0:2345 --headless=true --output=./authelia --continue --accept-multiclient debug cmd/authelia/*.go
|
||||
sleep 10
|
||||
done
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/authelia/authelia/v4/internal/model"
|
||||
"github.com/authelia/authelia/v4/internal/storage"
|
||||
|
@ -73,7 +73,7 @@ func (s *CLISuite) TestShouldPrintVersion() {
|
|||
}
|
||||
|
||||
func (s *CLISuite) TestShouldValidateConfig() {
|
||||
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "validate-config", "--config=/config/configuration.yml"})
|
||||
output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "validate-config"})
|
||||
s.Assert().NoError(err)
|
||||
s.Assert().Contains(output, "Configuration parsed and loaded successfully without errors.")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue