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
|
# Set environment variables
|
||||||
ENV PATH="/app:${PATH}" \
|
ENV PATH="/app:${PATH}" \
|
||||||
PUID=0 \
|
PUID=0 \
|
||||||
PGID=0
|
PGID=0 \
|
||||||
|
X_AUTHELIA_CONFIG="/config/configuration.yml"
|
||||||
|
|
||||||
RUN \
|
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 ./
|
COPY LICENSE .healthcheck.env entrypoint.sh healthcheck.sh ./
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
chmod 0666 /app/.healthcheck.env
|
chmod 0666 /app/.healthcheck.env
|
||||||
|
|
||||||
COPY authelia-${TARGETOS}-${TARGETARCH}-musl ./authelia
|
COPY authelia-${TARGETOS}-${TARGETARCH}-musl ./authelia
|
||||||
|
|
||||||
|
@ -28,5 +29,4 @@ EXPOSE 9091
|
||||||
VOLUME /config
|
VOLUME /config
|
||||||
|
|
||||||
ENTRYPOINT ["/app/entrypoint.sh"]
|
ENTRYPOINT ["/app/entrypoint.sh"]
|
||||||
CMD ["--config", "/config/configuration.yml"]
|
|
||||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=1m CMD /app/healthcheck.sh
|
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
|
WORKDIR /go/src/app
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
echo ">> Downloading required apk's..." && \
|
echo ">> Downloading required apk's..." && \
|
||||||
apk --no-cache add gcc musl-dev
|
apk --no-cache add gcc musl-dev
|
||||||
|
|
||||||
COPY go.mod go.sum ./
|
COPY go.mod go.sum ./
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
echo ">> Downloading go modules..." && \
|
echo ">> Downloading go modules..." && \
|
||||||
go mod download
|
go mod download
|
||||||
|
|
||||||
COPY / ./
|
COPY / ./
|
||||||
|
|
||||||
|
@ -36,12 +36,12 @@ COPY --from=builder-frontend /node/src/internal/server/public_html internal/serv
|
||||||
|
|
||||||
ARG LDFLAGS_EXTRA
|
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 && \
|
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=1 CGO_CPPFLAGS="-D_FORTIFY_SOURCE=2 -fstack-protector-strong" CGO_LDFLAGS="-Wl,-z,relro,-z,now" go test -c --tags coverage -covermode=atomic \
|
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/...
|
-ldflags "${LDFLAGS_EXTRA}" -o authelia -coverpkg github.com/authelia/authelia/...
|
||||||
|
|
||||||
# ===================================
|
# ===================================
|
||||||
# ===== Authelia official image =====
|
# ===== Authelia official image =====
|
||||||
|
@ -58,7 +58,8 @@ EXPOSE 9091
|
||||||
|
|
||||||
VOLUME /config
|
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
|
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
|
WORKDIR /go/src/app
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
echo ">> Downloading required apk's..." && \
|
echo ">> Downloading required apk's..." && \
|
||||||
apk --no-cache add gcc musl-dev
|
apk --no-cache add gcc musl-dev
|
||||||
|
|
||||||
COPY go.mod go.sum ./
|
COPY go.mod go.sum ./
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
echo ">> Downloading go modules..." && \
|
echo ">> Downloading go modules..." && \
|
||||||
go mod download
|
go mod download
|
||||||
|
|
||||||
COPY / ./
|
COPY / ./
|
||||||
|
|
||||||
|
@ -34,11 +34,11 @@ COPY --from=builder-frontend /node/src/internal/server/public_html internal/serv
|
||||||
|
|
||||||
ARG LDFLAGS_EXTRA
|
ARG LDFLAGS_EXTRA
|
||||||
RUN \
|
RUN \
|
||||||
mv api internal/server/public_html/api && \
|
mv api internal/server/public_html/api && \
|
||||||
chmod 0666 /go/src/app/.healthcheck.env && \
|
chmod 0666 /go/src/app/.healthcheck.env && \
|
||||||
echo ">> Starting go build..." && \
|
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 \
|
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
|
-ldflags "-linkmode=external -s -w ${LDFLAGS_EXTRA}" -trimpath -buildmode=pie -o authelia ./cmd/authelia
|
||||||
|
|
||||||
# ===================================
|
# ===================================
|
||||||
# ===== Authelia official image =====
|
# ===== Authelia official image =====
|
||||||
|
@ -50,20 +50,20 @@ WORKDIR /app
|
||||||
# Set environment variables
|
# Set environment variables
|
||||||
ENV PATH="/app:${PATH}" \
|
ENV PATH="/app:${PATH}" \
|
||||||
PUID=0 \
|
PUID=0 \
|
||||||
PGID=0
|
PGID=0 \
|
||||||
|
X_AUTHELIA_CONFIG="/config/configuration.yml"
|
||||||
|
|
||||||
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 /go/src/app/.healthcheck.env ./
|
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 \
|
RUN \
|
||||||
chmod 0666 /app/.healthcheck.env
|
chmod 0666 /app/.healthcheck.env
|
||||||
|
|
||||||
EXPOSE 9091
|
EXPOSE 9091
|
||||||
|
|
||||||
VOLUME /config
|
VOLUME /config
|
||||||
|
|
||||||
ENTRYPOINT ["/app/entrypoint.sh"]
|
ENTRYPOINT ["/app/entrypoint.sh"]
|
||||||
CMD ["--config", "/config/configuration.yml"]
|
|
||||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=1m CMD /app/healthcheck.sh
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=1m CMD /app/healthcheck.sh
|
||||||
|
|
|
@ -12,18 +12,23 @@ weight: 101200
|
||||||
toc: true
|
toc: true
|
||||||
---
|
---
|
||||||
|
|
||||||
## Loading Behaviour
|
## Loading Behaviour and Discovery
|
||||||
|
|
||||||
There are several options which affect the loading of files:
|
There are several options which affect the loading of files:
|
||||||
|
|
||||||
| Name | Argument | Description |
|
| Name | Argument | Environment Variable | Description |
|
||||||
|:-----------------:|:-------------------------------:|:----------------------------------------------------------------------------------:|
|
|:-----------------:|:-------------------------------:|:---------------------------:|:----------------------------------------------------------------------------------:|
|
||||||
| Files/Directories | `--config`, `-c` | A list of file or directory (non-recursive) paths to load configuration files from |
|
| 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` | A list of filters applied to every file from the Files or Directories options |
|
| 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
|
__*Note:* when specifying directories and files, the individual files specified must not be within any of the
|
||||||
directories specified.__
|
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
|
## Formats
|
||||||
|
|
||||||
The only supported configuration file format is [YAML](#yaml).
|
The only supported configuration file format is [YAML](#yaml).
|
||||||
|
|
|
@ -537,9 +537,11 @@ const (
|
||||||
cmdConfigDefaultContainer = "/config/configuration.yml"
|
cmdConfigDefaultContainer = "/config/configuration.yml"
|
||||||
cmdConfigDefaultDaemon = "/etc/authelia/configuration.yml"
|
cmdConfigDefaultDaemon = "/etc/authelia/configuration.yml"
|
||||||
|
|
||||||
cmdFlagNameConfig = "config"
|
cmdFlagNameConfig = "config"
|
||||||
|
cmdFlagEnvNameConfig = "X_AUTHELIA_CONFIG"
|
||||||
|
|
||||||
cmdFlagNameConfigExpFilters = "config.experimental.filters"
|
cmdFlagNameConfigExpFilters = "config.experimental.filters"
|
||||||
|
cmdFlagEnvNameConfigFilters = "X_AUTHELIA_CONFIG_FILTERS"
|
||||||
|
|
||||||
cmdFlagNameCharSet = "charset"
|
cmdFlagNameCharSet = "charset"
|
||||||
cmdFlagValueCharSet = "alphanumeric"
|
cmdFlagValueCharSet = "alphanumeric"
|
||||||
|
@ -655,4 +657,42 @@ The following filters are available:
|
||||||
'expand-env' filter for example.
|
'expand-env' filter for example.
|
||||||
|
|
||||||
For a full list of functions see: https://www.authelia.com/configuration/methods/files/#functions`
|
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
|
result XEnvCLIResult
|
||||||
)
|
)
|
||||||
|
|
||||||
if configs, result, err = loadXEnvCLIStringSliceValue(cmd, "", cmdFlagNameConfig); err != nil {
|
if configs, result, err = loadXEnvCLIStringSliceValue(cmd, cmdFlagEnvNameConfig, cmdFlagNameConfig); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,9 +45,9 @@ func NewRootCmd() (cmd *cobra.Command) {
|
||||||
DisableAutoGenTag: true,
|
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(
|
cmd.AddCommand(
|
||||||
newAccessControlCommand(ctx),
|
newAccessControlCommand(ctx),
|
||||||
|
@ -56,7 +56,8 @@ func NewRootCmd() (cmd *cobra.Command) {
|
||||||
newStorageCmd(ctx),
|
newStorageCmd(ctx),
|
||||||
newValidateConfigCmd(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
|
return cmd
|
||||||
|
|
|
@ -246,7 +246,7 @@ func loadXEnvCLIConfigValues(cmd *cobra.Command) (configs []string, filters []co
|
||||||
filterNames []string
|
filterNames []string
|
||||||
)
|
)
|
||||||
|
|
||||||
if configs, _, err = loadXEnvCLIStringSliceValue(cmd, "", cmdFlagNameConfig); err != nil {
|
if configs, _, err = loadXEnvCLIStringSliceValue(cmd, cmdFlagEnvNameConfig, cmdFlagNameConfig); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@ func loadXEnvCLIConfigValues(cmd *cobra.Command) (configs []string, filters []co
|
||||||
return nil, nil, err
|
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
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,8 @@ RUN mkdir -p /config && chown dev:dev /config
|
||||||
|
|
||||||
USER dev
|
USER dev
|
||||||
|
|
||||||
ENV PATH="/app:${PATH}"
|
ENV PATH="/app:${PATH}" \
|
||||||
|
X_AUTHELIA_CONFIG="/config/configuration.yml"
|
||||||
|
|
||||||
VOLUME /config
|
VOLUME /config
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ ARG USER_ID
|
||||||
ARG GROUP_ID
|
ARG GROUP_ID
|
||||||
|
|
||||||
RUN yarn global add pnpm && \
|
RUN yarn global add pnpm && \
|
||||||
pnpm config set --global store-dir /tmp/.pnpm-store && \
|
|
||||||
deluser node && \
|
deluser node && \
|
||||||
addgroup --gid ${GROUP_ID} dev && \
|
addgroup --gid ${GROUP_ID} dev && \
|
||||||
adduser --uid ${USER_ID} -G dev -D dev
|
adduser --uid ${USER_ID} -G dev -D dev
|
||||||
|
|
|
@ -14,7 +14,7 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- './example/compose/authelia/resources/:/resources'
|
- './example/compose/authelia/resources/:/resources'
|
||||||
- '../../web:/app'
|
- '../../web:/app'
|
||||||
- '~/.local/share/pnpm/store:/tmp/.pnpm-store'
|
- '~/.local/share/pnpm/store:/app/.pnpm-store'
|
||||||
labels:
|
labels:
|
||||||
# Traefik 1.x
|
# Traefik 1.x
|
||||||
- 'traefik.frontend.rule=Host:login.example.com'
|
- 'traefik.frontend.rule=Host:login.example.com'
|
||||||
|
|
|
@ -4,6 +4,6 @@ set -e
|
||||||
|
|
||||||
while true;
|
while true;
|
||||||
do
|
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
|
sleep 10
|
||||||
done
|
done
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/suite"
|
"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/model"
|
||||||
"github.com/authelia/authelia/v4/internal/storage"
|
"github.com/authelia/authelia/v4/internal/storage"
|
||||||
|
@ -73,7 +73,7 @@ func (s *CLISuite) TestShouldPrintVersion() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CLISuite) TestShouldValidateConfig() {
|
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().NoError(err)
|
||||||
s.Assert().Contains(output, "Configuration parsed and loaded successfully without errors.")
|
s.Assert().Contains(output, "Configuration parsed and loaded successfully without errors.")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue