From dfb816888edf489c8ad51b5114dc0248c948991f Mon Sep 17 00:00:00 2001 From: Spoffy <4805393+Spoffy@users.noreply.github.com> Date: Mon, 12 Aug 2024 20:54:43 +0100 Subject: [PATCH] Adds docker compose examples (#1113) This adds three example docker-compose files: - A basic Grist instance backed by sqlite, with no additional services. - A Grist instance that uses Postgres, Redis and MinIO. - A Grist instance that uses OIDC authentication and traefik. These are intended to be customised by self-hosters for their own needs. All examples should work without any additional configuration. --- .gitignore | 5 + .../grist-local-testing/README.md | 12 + .../grist-local-testing/docker-compose.yml | 8 + .../grist-traefik-basic-auth/README.md | 24 + .../configs/traefik-config.yml | 35 + .../configs/traefik-dynamic-config.yml | 13 + .../docker-compose.yml | 44 + .../grist-traefik-oidc-auth/README.md | 32 + .../configs/authelia/configuration.yml | 1423 +++++++++++++++++ .../configs/authelia/users_database.yml | 14 + .../configs/traefik/config.yml | 30 + .../docker-compose.yml | 118 ++ .../grist-traefik-oidc-auth/env-template | 6 + .../generateSecureSecrets.sh | 32 + .../GRIST_CLIENT_SECRET_DIGEST | 0 .../secrets_template/HMAC_SECRET | 0 .../secrets_template/JWT_SECRET | 0 .../secrets_template/SESSION_SECRET | 0 .../secrets_template/STORAGE_ENCRYPTION_KEY | 0 .../secrets_template/certs/private.pem | 0 .../grist-with-postgres-redis-minio/.env | 3 + .../grist-with-postgres-redis-minio/README.md | 20 + .../docker-compose.yml | 76 + 23 files changed, 1895 insertions(+) create mode 100644 docker-compose-examples/grist-local-testing/README.md create mode 100644 docker-compose-examples/grist-local-testing/docker-compose.yml create mode 100644 docker-compose-examples/grist-traefik-basic-auth/README.md create mode 100644 docker-compose-examples/grist-traefik-basic-auth/configs/traefik-config.yml create mode 100644 docker-compose-examples/grist-traefik-basic-auth/configs/traefik-dynamic-config.yml create mode 100644 docker-compose-examples/grist-traefik-basic-auth/docker-compose.yml create mode 100644 docker-compose-examples/grist-traefik-oidc-auth/README.md create mode 100644 docker-compose-examples/grist-traefik-oidc-auth/configs/authelia/configuration.yml create mode 100644 docker-compose-examples/grist-traefik-oidc-auth/configs/authelia/users_database.yml create mode 100644 docker-compose-examples/grist-traefik-oidc-auth/configs/traefik/config.yml create mode 100644 docker-compose-examples/grist-traefik-oidc-auth/docker-compose.yml create mode 100644 docker-compose-examples/grist-traefik-oidc-auth/env-template create mode 100755 docker-compose-examples/grist-traefik-oidc-auth/generateSecureSecrets.sh create mode 100644 docker-compose-examples/grist-traefik-oidc-auth/secrets_template/GRIST_CLIENT_SECRET_DIGEST create mode 100644 docker-compose-examples/grist-traefik-oidc-auth/secrets_template/HMAC_SECRET create mode 100644 docker-compose-examples/grist-traefik-oidc-auth/secrets_template/JWT_SECRET create mode 100644 docker-compose-examples/grist-traefik-oidc-auth/secrets_template/SESSION_SECRET create mode 100644 docker-compose-examples/grist-traefik-oidc-auth/secrets_template/STORAGE_ENCRYPTION_KEY create mode 100644 docker-compose-examples/grist-traefik-oidc-auth/secrets_template/certs/private.pem create mode 100644 docker-compose-examples/grist-with-postgres-redis-minio/.env create mode 100644 docker-compose-examples/grist-with-postgres-redis-minio/README.md create mode 100644 docker-compose-examples/grist-with-postgres-redis-minio/docker-compose.yml diff --git a/.gitignore b/.gitignore index 3ec43ff9..95d698a2 100644 --- a/.gitignore +++ b/.gitignore @@ -83,3 +83,8 @@ xunit.xml # ext directory can be overwritten ext/** + +# Docker compose examples - persistent values and secrets +/docker-compose-examples/*/persist +/docker-compose-examples/*/secrets +/docker-compose-examples/grist-traefik-oidc-auth/.env diff --git a/docker-compose-examples/grist-local-testing/README.md b/docker-compose-examples/grist-local-testing/README.md new file mode 100644 index 00000000..cd610cfd --- /dev/null +++ b/docker-compose-examples/grist-local-testing/README.md @@ -0,0 +1,12 @@ +This is the simplest example that runs Grist, suitable for local testing. + +It is STRONGLY RECOMMENDED not to use this container in a way that makes it accessible to the internet. +This setup lacks basic security or authentication. + +Other examples demonstrate how to set up authentication and HTTPS. + +See https://support.getgrist.com/self-managed for more information. + +## How to run this example + +This example can be run with `docker compose up`. \ No newline at end of file diff --git a/docker-compose-examples/grist-local-testing/docker-compose.yml b/docker-compose-examples/grist-local-testing/docker-compose.yml new file mode 100644 index 00000000..028d4e0f --- /dev/null +++ b/docker-compose-examples/grist-local-testing/docker-compose.yml @@ -0,0 +1,8 @@ +services: + grist: + image: gristlabs/grist:latest + volumes: + # Where to store persistent data, such as documents. + - ${PERSIST_DIR}/grist:/persist + ports: + - 8484:8484 diff --git a/docker-compose-examples/grist-traefik-basic-auth/README.md b/docker-compose-examples/grist-traefik-basic-auth/README.md new file mode 100644 index 00000000..170361c4 --- /dev/null +++ b/docker-compose-examples/grist-traefik-basic-auth/README.md @@ -0,0 +1,24 @@ +This is the simplest example of Grist with authentication and HTTPS encryption. + +It uses Traefik as: +- A reverse proxy to manage certificates and provide HTTPS support +- A basic authentication provided using Traefik's Basic Auth middleware. + +This setup, after configuring HTTPS certificates correctly, should be acceptable on the public internet. + +However, it doesn't allow a user to sign-out due to the way browsers handle basic authentication. + +You may want to try a more secure authentication setup such Authelia, Authentik or traefik-forward-auth. +The OIDC auth example demonstrates a setup using Authelia. + +See https://support.getgrist.com/self-managed for more information. + +## How to run this example + +This example can be run with `docker compose up`. + +The default login is: +- Username: `test@example.org` +- Password: `test` + +This can be changed in `./configs/traefik-dynamic-config.yaml`. Instructions on how to do this are available in that file. diff --git a/docker-compose-examples/grist-traefik-basic-auth/configs/traefik-config.yml b/docker-compose-examples/grist-traefik-basic-auth/configs/traefik-config.yml new file mode 100644 index 00000000..ac1dd4ec --- /dev/null +++ b/docker-compose-examples/grist-traefik-basic-auth/configs/traefik-config.yml @@ -0,0 +1,35 @@ +providers: + # Enables reading docker label config values + docker: {} + # Read additional config from this file. + file: + directory: "/etc/traefik/dynamic" + +entrypoints: + # Defines a secure entrypoint using TLS encryption + websecure: + address: ":443" + http: + tls: true + # Defines an insecure entrypoint that redirects to the secure one. + web: + address: ":80" + http: + # Redirects HTTP to HTTPS + redirections: + entrypoint: + to: "websecure" + scheme: "https" + +# Enables automatic certificate renewal +certificatesResolvers: + letsencrypt: + acme: + email: "my_email@example.com" + storage: /acme/acme.json + tlschallenge: true + +# Enables the web UI +# This is disabled by default for security, but can be useful to debugging traefik. +api: + # insecure: true diff --git a/docker-compose-examples/grist-traefik-basic-auth/configs/traefik-dynamic-config.yml b/docker-compose-examples/grist-traefik-basic-auth/configs/traefik-dynamic-config.yml new file mode 100644 index 00000000..e4544c04 --- /dev/null +++ b/docker-compose-examples/grist-traefik-basic-auth/configs/traefik-dynamic-config.yml @@ -0,0 +1,13 @@ +http: + # Declaring the user list + middlewares: + grist-basic-auth: + basicAuth: + # The header that Grist will listen for authenticated usernames on. + headerField: "X-Forwarded-User" + # This is the list of users, in the format username:password. + # Passwords can be created using `htpasswd` + # E.g: `htpasswd -nB test@example.org` + users: + # The default username is "test@example.org". The default password is "test". + - "test@example.org:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/" diff --git a/docker-compose-examples/grist-traefik-basic-auth/docker-compose.yml b/docker-compose-examples/grist-traefik-basic-auth/docker-compose.yml new file mode 100644 index 00000000..63048281 --- /dev/null +++ b/docker-compose-examples/grist-traefik-basic-auth/docker-compose.yml @@ -0,0 +1,44 @@ +services: + grist: + image: gristlabs/grist:latest + environment: + # Sets the header to look at for authentication + GRIST_FORWARD_AUTH_HEADER: X-Forwarded-User + # Forces Grist to only use a single team called 'Example' + GRIST_SINGLE_ORG: my-grist-team # alternatively, GRIST_ORG_IN_PATH: "true" for multi-team operation + # Force users to login (disable anonymous access) + GRIST_FORCE_LOGIN: true + # Base URL Grist redirects to when navigating. Change this to your domain. + APP_HOME_URL: https://grist.localhost + # Default email for the "Admin" account + GRIST_DEFAULT_EMAIL: test@example.org + volumes: + # Where to store persistent data, such as documents. + - ${PERSIST_DIR}/grist:/persist + labels: + - "traefik.http.services.grist.loadbalancer.server.port=8484" + - "traefik.http.routers.grist.rule=Host(`grist.localhost`)" + - "traefik.http.routers.grist.tls.certresolver=letsencrypt" + - "traefik.http.routers.grist-auth.rule=Host(`grist.localhost`) && (PathPrefix(`/auth/login`) || PathPrefix(`/_oauth`))" + - "traefik.http.routers.grist-auth.middlewares=grist-basic-auth@file" + - "traefik.http.routers.grist-auth.tls.certresolver=letsencrypt" + + traefik: + image: traefik:latest + ports: + # HTTP Ports + - "80:80" + - "443:443" + # The Web UI (enabled by --api.insecure=true) + # - "8080:8080" + volumes: + # Set the config file for traefik - this is loaded automatically. + - ./configs/traefik-config.yml:/etc/traefik/traefik.yml + # Set the config file for the dynamic config, such as middleware. + - ./configs/traefik-dynamic-config.yml:/etc/traefik/dynamic/dynamic-config.yml + # Certificate location, if automatic certificate setup is enabled. + - ./configs/acme:/acme + # Traefik needs docker access when configured via docker labels. + - /var/run/docker.sock:/var/run/docker.sock + depends_on: + - grist diff --git a/docker-compose-examples/grist-traefik-oidc-auth/README.md b/docker-compose-examples/grist-traefik-oidc-auth/README.md new file mode 100644 index 00000000..b861d00a --- /dev/null +++ b/docker-compose-examples/grist-traefik-oidc-auth/README.md @@ -0,0 +1,32 @@ +This is an example of Grist with Authelia for OIDC authentication, and Traefik for HTTP encryption and routing. + +OIDC enables authentication using many existing providers, including Google, Microsoft, Amazon and Okta. + +This example uses Authelia, which is a locally hosted OIDC provider, so that it can work without further setup. +However, Authelia could be easily replaced by one of the providers listed above, or other self-hosted alternatives, +such as Authentik or Dex. + +This example could be hosted on a dedicated server, with the following changes: +- DNS setup +- HTTPS / Certificate setup (e.g Let's encrypt) + +See https://support.getgrist.com/install/oidc for more information on using Grist with OIDC. + +## How to run this example + +To run this example, you'll first need to generate several secrets needed by Authelia. + +This is automated for you in `generateSecureSecrets.sh`, which uses Authelia's docker image to populate the `./secrets` directory. + +This example can then be run with `docker compose up`. This will make Grist available on `https://grist.localhost` with a self-signed certificate (by default), after all the services have started. Note: it may take up to a minute for all of the services to start correctly. + +The self-signed certificate will cause a security warning in the web browser when you try to visit Grist. +This is fine for local testing and can be bypassed, but correct certificates should be set up if Grist is being made +available on the internet. + +### Users + +The default username is `test`, with password `test`. + +You can add or modify users in ./configs/authelia/user-database.yml. Additional instructions are provided in that file. + diff --git a/docker-compose-examples/grist-traefik-oidc-auth/configs/authelia/configuration.yml b/docker-compose-examples/grist-traefik-oidc-auth/configs/authelia/configuration.yml new file mode 100644 index 00000000..e5019d63 --- /dev/null +++ b/docker-compose-examples/grist-traefik-oidc-auth/configs/authelia/configuration.yml @@ -0,0 +1,1423 @@ +# yamllint disable rule:comments-indentation + +############################################################################### +## Original configuration file available at this URL: ## +## https://github.com/authelia/authelia/blob/master/config.template.yml ## +## ## +## This file is an edited version to support Grist as an OIDC client ## +############################################################################### + +#------------------------------------------------------------------------------ + +############################################################################### +## Authelia Configuration ## +############################################################################### + +## +## Notes: +## +## - the default location of this file is assumed to be configuration.yml unless otherwise noted +## - when using docker the container expects this by default to be at /config/configuration.yml +## - the default location where this file is loaded from can be overridden with the X_AUTHELIA_CONFIG environment var +## - the comments in this configuration file are helpful but users should consult the official documentation on the +## website at https://www.authelia.com/ or https://www.authelia.com/configuration/prologue/introduction/ +## - this configuration file template is not automatically updated +## + +## Certificates directory specifies where Authelia will load trusted certificates (public portion) from in addition to +## the system certificates store. +## They should be in base64 format, and have one of the following extensions: *.cer, *.crt, *.pem. +# certificates_directory: '/config/certificates/' + +## The theme to display: light, dark, grey, auto. +# theme: 'light' + +## Set the default 2FA method for new users and for when a user has a preferred method configured that has been +## disabled. This setting must be a method that is enabled. +## Options are totp, webauthn, mobile_push. +# default_2fa_method: '' + +## +## Server Configuration +## +server: + ## The address for the Main server to listen on in the address common syntax. + ## Formats: + ## - [://][:][/] + ## - [://][hostname]:[/] + ## Square brackets indicate optional portions of the format. Scheme must be 'tcp', 'tcp4', 'tcp6', or 'unix'. + ## The default scheme is 'unix' if the address is an absolute path otherwise it's 'tcp'. The default port is '9091'. + ## If the path is specified this configures the router to handle both the `/` path and the configured path. + address: 'tcp://:9091/' + + ## Set the path on disk to Authelia assets. + ## Useful to allow overriding of specific static assets. + # asset_path: '/config/assets/' + + ## 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. + # key: '' + + ## The path to the DER base64/PEM format public certificate. + # certificate: '' + + ## The list of certificates for client authentication. + # client_certificates: [] + + ## Server headers configuration/customization. + # headers: + + ## The CSP Template. Read the docs. + # csp_template: '' + + ## Server Buffers configuration. + # buffers: + + ## Buffers usually should be configured to be the same value. + ## Explanation at https://www.authelia.com/c/server#buffer-sizes + ## Read buffer size adjusts the server's max incoming request size in bytes. + ## Write buffer size does the same for outgoing responses. + + ## Read buffer. + # read: 4096 + + ## Write buffer. + # write: 4096 + + ## Server Timeouts configuration. + # timeouts: + + ## Read timeout in the duration common syntax. + # read: '6 seconds' + + ## Write timeout in the duration common syntax. + # write: '6 seconds' + + ## Idle timeout in the duration common syntax. + # idle: '30 seconds' + + ## Server Endpoints configuration. + ## This section is considered advanced and it SHOULD NOT be configured unless you've read the relevant documentation. + endpoints: + ## Enables the pprof endpoint. + # enable_pprof: false + + ## Enables the expvars endpoint. + # enable_expvars: false + + ## Configure the authz endpoints. + authz: + forward-auth: + implementation: 'ForwardAuth' + authn_strategies: [] + # ext-authz: + # implementation: 'ExtAuthz' + # authn_strategies: [] + # auth-request: + # implementation: 'AuthRequest' + # authn_strategies: [] + # legacy: + # implementation: 'Legacy' + # authn_strategies: [] + +## +## Log Configuration +## +log: + ## Level of verbosity for logs: info, debug, trace. + level: 'debug' + + ## Format the logs are written as: json, text. + # format: 'json' + + ## File path where the logs will be written. If not set logs are written to stdout. + # file_path: '/config/authelia.log' + + ## Whether to also log to stdout when a log_file_path is defined. + # keep_stdout: false + +## +## Telemetry Configuration +## +telemetry: + + ## + ## Metrics Configuration + ## + metrics: + ## Enable Metrics. + enabled: false + + ## The address for the Metrics server to listen on in the address common syntax. + ## Formats: + ## - [://][:][/] + ## - [://][hostname]:[/] + ## Square brackets indicate optional portions of the format. Scheme must be 'tcp', 'tcp4', 'tcp6', or 'unix'. + ## The default scheme is 'unix' if the address is an absolute path otherwise it's 'tcp'. The default port is '9959'. + ## If the path is not specified it defaults to `/metrics`. + # address: 'tcp://:9959/metrics' + + ## Metrics Server Buffers configuration. + # buffers: + + ## Read buffer. + # read: 4096 + + ## Write buffer. + # write: 4096 + + ## Metrics Server Timeouts configuration. + # timeouts: + + ## Read timeout in the duration common syntax. + # read: '6 seconds' + + ## Write timeout in the duration common syntax. + # write: '6 seconds' + + ## Idle timeout in the duration common syntax. + # idle: '30 seconds' + +## +## TOTP Configuration +## +## Parameters used for TOTP generation. +totp: + ## Disable TOTP. + disable: false + + ## The issuer name displayed in the Authenticator application of your choice. + # issuer: 'authelia.com' + + ## The TOTP algorithm to use. + ## It is CRITICAL you read the documentation before changing this option: + ## https://www.authelia.com/c/totp#algorithm + # algorithm: 'SHA1' + + ## The number of digits a user has to input. Must either be 6 or 8. + ## Changing this option only affects newly generated TOTP configurations. + ## It is CRITICAL you read the documentation before changing this option: + ## https://www.authelia.com/c/totp#digits + # digits: 6 + + ## The period in seconds a Time-based One-Time Password is valid for. + ## Changing this option only affects newly generated TOTP configurations. + # period: 30 + + ## The skew controls number of Time-based One-Time Passwords either side of the current one that are valid. + ## Warning: before changing skew read the docs link below. + # skew: 1 + ## See: https://www.authelia.com/c/totp#input-validation to read + ## the documentation. + + ## The size of the generated shared secrets. Default is 32 and is sufficient in most use cases, minimum is 20. + # secret_size: 32 + + ## The allowed algorithms for a user to pick from. + # allowed_algorithms: + # - 'SHA1' + + ## The allowed digits for a user to pick from. + # allowed_digits: + # - 6 + + ## The allowed periods for a user to pick from. + # allowed_periods: + # - 30 + + ## Disable the reuse security policy which prevents replays of one-time password code values. + # disable_reuse_security_policy: false + +## +## WebAuthn Configuration +## +## Parameters used for WebAuthn. +webauthn: + ## Disable WebAuthn. + disable: false + + ## The interaction timeout for WebAuthn dialogues in the duration common syntax. + # timeout: '60 seconds' + + ## The display name the browser should show the user for when using WebAuthn to login/register. + # display_name: 'Authelia' + + ## Conveyance preference controls if we collect the attestation statement including the AAGUID from the device. + ## Options are none, indirect, direct. + # attestation_conveyance_preference: 'indirect' + + ## User verification controls if the user must make a gesture or action to confirm they are present. + ## Options are required, preferred, discouraged. + # user_verification: 'preferred' + +## +## Duo Push API Configuration +## +## Parameters used to contact the Duo API. Those are generated when you protect an application of type +## "Partner Auth API" in the management panel. +# duo_api: + # disable: false + # hostname: 'api-123456789.example.com' + # integration_key: 'ABCDEF' + ## Secret can also be set using a secret: https://www.authelia.com/c/secrets + # secret_key: '1234567890abcdefghifjkl' + # enable_self_enrollment: false + +## +## Identity Validation Configuration +## +## This configuration tunes the identity validation flows. +identity_validation: + + ## Reset Password flow. Adjusts how the reset password flow operates. + reset_password: + ## Maximum allowed time before the JWT is generated and when the user uses it in the duration common syntax. + # jwt_lifespan: '5 minutes' + + ## The algorithm used for the Reset Password JWT. + # jwt_algorithm: 'HS256' + + ## The secret key used to sign and verify the JWT. + # jwt_secret: 'a_very_important_secret' + + ## Elevated Session flows. Adjusts the flow which require elevated sessions for example managing credentials, adding, + ## removing, etc. + # elevated_session: + ## Maximum allowed lifetime after the One-Time Code is generated that it is considered valid. + # code_lifespan: '5 minutes' + + ## Maximum allowed lifetime after the user uses the One-Time Code and the user must perform the validation again in + ## the duration common syntax. + # elevation_lifespan: '10 minutes' + + ## Number of characters the one-time password contains. + # characters: 8 + + ## In addition to the One-Time Code requires the user performs a second factor authentication. + # require_second_factor: false + + ## Skips the elevation requirement and entry of the One-Time Code if the user has performed second factor + ## authentication. + # skip_second_factor: false + +## +## NTP Configuration +## +## This is used to validate the servers time is accurate enough to validate TOTP. +# ntp: + ## The address of the NTP server to connect to in the address common syntax. + ## Format: [://][:]. + ## Square brackets indicate optional portions of the format. Scheme must be 'udp', 'udp4', or 'udp6'. + ## The default scheme is 'udp'. The default port is '123'. + # address: 'udp://time.cloudflare.com:123' + + ## NTP version. + # version: 4 + + ## Maximum allowed time offset between the host and the NTP server in the duration common syntax. + # max_desync: '3 seconds' + + ## Disables the NTP check on startup entirely. This means Authelia will not contact a remote service at all if you + ## set this to true, and can operate in a truly offline mode. + # disable_startup_check: false + + ## The default of false will prevent startup only if we can contact the NTP server and the time is out of sync with + ## the NTP server more than the configured max_desync. If you set this to true, an error will be logged but startup + ## will continue regardless of results. + # disable_failure: false + +## +## Authentication Backend Provider Configuration +## +## Used for verifying user passwords and retrieve information such as email address and groups users belong to. +## +## The available providers are: `file`, `ldap`. You must use only one of these providers. +authentication_backend: + ## Password Reset Options. + password_reset: + ## Disable both the HTML element and the API for reset password functionality. + disable: false + + ## External reset password url that redirects the user to an external reset portal. This disables the internal reset + ## functionality. + # custom_url: '' + + ## The amount of time to wait before we refresh data from the authentication backend in the duration common syntax. + ## To disable this feature set it to 'disable', this will slightly reduce security because for Authelia, users will + ## always belong to groups they belonged to at the time of login even if they have been removed from them in LDAP. + ## To force update on every request you can set this to '0' or 'always', this will increase processor demand. + ## See the below documentation for more information. + ## Refresh Interval docs: https://www.authelia.com/c/1fa#refresh-interval + # refresh_interval: '5 minutes' + + ## + ## LDAP (Authentication Provider) + ## + ## This is the recommended Authentication Provider in production + ## because it allows Authelia to offload the stateful operations + ## onto the LDAP service. + # ldap: + ## The address of the directory server to connect to in the address common syntax. + ## Format: [://][:]. + ## Square brackets indicate optional portions of the format. Scheme must be 'ldap', 'ldaps', or 'ldapi`. + ## The default scheme is 'ldapi' if the address is an absolute path otherwise it's 'ldaps'. + ## The default port is '636', unless the scheme is 'ldap' in which case it's '389'. + # address: 'ldaps://127.0.0.1:636' + + ## The LDAP implementation, this affects elements like the attribute utilised for resetting a password. + ## Acceptable options are as follows: + ## - 'activedirectory' - for Microsoft Active Directory. + ## - 'freeipa' - for FreeIPA. + ## - 'lldap' - for lldap. + ## - 'custom' - for custom specifications of attributes and filters. + ## This currently defaults to 'custom' to maintain existing behaviour. + ## + ## Depending on the option here certain other values in this section have a default value, notably all of the + ## attribute mappings have a default value that this config overrides, you can read more about these default values + ## at https://www.authelia.com/c/ldap#defaults + # implementation: 'custom' + + ## The dial timeout for LDAP in the duration common syntax. + # timeout: '5 seconds' + + ## Use StartTLS with the LDAP connection. + # start_tls: false + + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the address options hostname. + # server_name: 'ldap.example.com' + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: 'TLS1.2' + + ## Maximum TLS version for the connection. + # maximum_version: 'TLS1.3' + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # ... + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # ... + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # ... + # -----END RSA PRIVATE KEY----- + + ## The distinguished name of the container searched for objects in the directory information tree. + ## See also: additional_users_dn, additional_groups_dn. + # base_dn: 'dc=example,dc=com' + + ## The additional_users_dn is prefixed to base_dn and delimited by a comma when searching for users. + ## i.e. with this set to OU=Users and base_dn set to DC=a,DC=com; OU=Users,DC=a,DC=com is searched for users. + # additional_users_dn: 'ou=users' + + ## The users filter used in search queries to find the user profile based on input filled in login form. + ## Various placeholders are available in the user filter which you can read about in the documentation which can + ## be found at: https://www.authelia.com/c/ldap#users-filter-replacements + ## + ## Recommended settings are as follows: + ## - Microsoft Active Directory: (&({username_attribute}={input})(objectCategory=person)(objectClass=user)) + ## - OpenLDAP: + ## - (&({username_attribute}={input})(objectClass=person)) + ## - (&({username_attribute}={input})(objectClass=inetOrgPerson)) + ## + ## To allow sign in both with username and email, one can use a filter like + ## (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person)) + # users_filter: '(&({username_attribute}={input})(objectClass=person))' + + ## The additional_groups_dn is prefixed to base_dn and delimited by a comma when searching for groups. + ## i.e. with this set to OU=Groups and base_dn set to DC=a,DC=com; OU=Groups,DC=a,DC=com is searched for groups. + # additional_groups_dn: 'ou=groups' + + ## The groups filter used in search queries to find the groups based on relevant authenticated user. + ## Various placeholders are available in the groups filter which you can read about in the documentation which can + ## be found at: https://www.authelia.com/c/ldap#groups-filter-replacements + ## + ## If your groups use the `groupOfUniqueNames` structure use this instead: + ## (&(uniqueMember={dn})(objectClass=groupOfUniqueNames)) + # groups_filter: '(&(member={dn})(objectClass=groupOfNames))' + + ## The group search mode to use. Options are 'filter' or 'memberof'. It's essential to read the docs if you wish to + ## use 'memberof'. Also 'filter' is the best choice for most use cases. + # group_search_mode: 'filter' + + ## Follow referrals returned by the server. + ## This is especially useful for environments where read-only servers exist. Only implemented for write operations. + # permit_referrals: false + + ## The username and password of the admin user. + # user: 'cn=admin,dc=example,dc=com' + ## Password can also be set using a secret: https://www.authelia.com/c/secrets + # password: 'password' + + ## The attributes for users and objects from the directory server. + # attributes: + + ## The distinguished name attribute if your directory server supports it. Users should read the docs before + ## configuring. Only used for the 'memberof' group search mode. + # distinguished_name: '' + + ## The attribute holding the username of the user. This attribute is used to populate the username in the session + ## information. For your information, Microsoft Active Directory usually uses 'sAMAccountName' and OpenLDAP + ## usually uses 'uid'. Beware that this attribute holds the unique identifiers for the users binding the user and + ## the configuration stored in database; therefore only single value attributes are allowed and the value must + ## never be changed once attributed to a user otherwise it would break the configuration for that user. + ## Technically non-unique attributes like 'mail' can also be used but we don't recommend using them, we instead + ## advise to use a filter to perform alternative lookups and the attributes mentioned above + ## (sAMAccountName and uid) to follow https://datatracker.ietf.org/doc/html/rfc2307. + # username: 'uid' + + ## The attribute holding the display name of the user. This will be used to greet an authenticated user. + # display_name: 'displayName' + + ## The attribute holding the mail address of the user. If multiple email addresses are defined for a user, only + ## the first one returned by the directory server is used. + # mail: 'mail' + + ## The attribute which provides distinguished names of groups an object is a member of. + ## Only used for the 'memberof' group search mode. + # member_of: 'memberOf' + + ## The attribute holding the name of the group. + # group_name: 'cn' + + ## + ## File (Authentication Provider) + ## + ## With this backend, the users database is stored in a file which is updated when users reset their passwords. + ## Therefore, this backend is meant to be used in a dev environment and not in production since it prevents Authelia + ## to be scaled to more than one instance. The options under 'password' have sane defaults, and as it has security + ## implications it is highly recommended you leave the default values. Before considering changing these settings + ## please read the docs page below: + ## https://www.authelia.com/r/passwords#tuning + ## + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness + ## + file: + path: '/config/users_database.yml' + watch: true + search: + email: false + case_insensitive: false + #password: + #algorithm: 'argon2' + # argon2: + # variant: 'argon2id' + # iterations: 3 + # memory: 65536 + # parallelism: 4 + # key_length: 32 + # salt_length: 16 + # scrypt: + # iterations: 16 + # block_size: 8 + # parallelism: 1 + # key_length: 32 + # salt_length: 16 + # pbkdf2: + # variant: 'sha512' + # iterations: 310000 + # salt_length: 16 + # sha2crypt: + # variant: 'sha512' + # iterations: 50000 + # salt_length: 16 + # bcrypt: + # variant: 'standard' + # cost: 12 + +## +## Password Policy Configuration. +## +password_policy: + + ## The standard policy allows you to tune individual settings manually. + standard: + enabled: false + + ## Require a minimum length for passwords. + min_length: 8 + + ## Require a maximum length for passwords. + max_length: 0 + + ## Require uppercase characters. + require_uppercase: true + + ## Require lowercase characters. + require_lowercase: true + + ## Require numeric characters. + require_number: true + + ## Require special characters. + require_special: true + + ## zxcvbn is a well known and used password strength algorithm. It does not have tunable settings. + zxcvbn: + enabled: false + + ## Configures the minimum score allowed. + min_score: 3 + +## +## Privacy Policy Configuration +## +## Parameters used for displaying the privacy policy link and drawer. +privacy_policy: + + ## Enables the display of the privacy policy using the policy_url. + enabled: false + + ## Enables the display of the privacy policy drawer which requires users accept the privacy policy + ## on a per-browser basis. + require_user_acceptance: false + + ## The URL of the privacy policy document. Must be an absolute URL and must have the 'https://' scheme. + ## If the privacy policy enabled option is true, this MUST be provided. + policy_url: '' + +## +## Access Control Configuration +## +## Access control is a list of rules defining the authorizations applied for one resource to users or group of users. +## +## If 'access_control' is not defined, ACL rules are disabled and the 'bypass' rule is applied, i.e., access is allowed +## to anyone. Otherwise restrictions follow the rules defined. +## +## Note: One can use the wildcard * to match any subdomain. +## It must stand at the beginning of the pattern. (example: *.example.com) +## +## Note: You must put patterns containing wildcards between simple quotes for the YAML to be syntactically correct. +## +## Definition: A 'rule' is an object with the following keys: 'domain', 'subject', 'policy' and 'resources'. +## +## - 'domain' defines which domain or set of domains the rule applies to. +## +## - 'subject' defines the subject to apply authorizations to. This parameter is optional and matching any user if not +## provided. If provided, the parameter represents either a user or a group. It should be of the form +## 'user:' or 'group:'. +## +## - 'policy' is the policy to apply to resources. It must be either 'bypass', 'one_factor', 'two_factor' or 'deny'. +## +## - 'resources' is a list of regular expressions that matches a set of resources to apply the policy to. This parameter +## is optional and matches any resource if not provided. +## +## Note: the order of the rules is important. The first policy matching (domain, resource, subject) applies. +access_control: + ## Default policy can either be 'bypass', 'one_factor', 'two_factor' or 'deny'. It is the policy applied to any + ## resource if there is no policy to be applied to the user. + default_policy: 'one_factor' + + # networks: + # - name: 'internal' + # networks: + # - '10.10.0.0/16' + # - '192.168.2.0/24' + # - name: 'VPN' + # networks: '10.9.0.0/16' + + # rules: + ## Rules applied to everyone + # - domain: 'public.example.com' + # policy: 'bypass' + + ## Domain Regex examples. Generally we recommend just using a standard domain. + # - domain_regex: '^(?P\w+)\.example\.com$' + # policy: 'one_factor' + # - domain_regex: '^(?P\w+)\.example\.com$' + # policy: 'one_factor' + # - domain_regex: + # - '^appgroup-.*\.example\.com$' + # - '^appgroup2-.*\.example\.com$' + # policy: 'one_factor' + # - domain_regex: '^.*\.example\.com$' + # policy: 'two_factor' + + # - domain: 'secure.example.com' + # policy: 'one_factor' + ## Network based rule, if not provided any network matches. + # networks: + # - 'internal' + # - 'VPN' + # - '192.168.1.0/24' + # - '10.0.0.1' + + # - domain: + # - 'secure.example.com' + # - 'private.example.com' + # policy: 'two_factor' + + # - domain: 'singlefactor.example.com' + # policy: 'one_factor' + + ## Rules applied to 'admins' group + # - domain: 'mx2.mail.example.com' + # subject: 'group:admins' + # policy: 'deny' + + # - domain: '*.example.com' + # subject: + # - 'group:admins' + # - 'group:moderators' + # policy: 'two_factor' + + ## Rules applied to 'dev' group + # - domain: 'dev.example.com' + # resources: + # - '^/groups/dev/.*$' + # subject: 'group:dev' + # policy: 'two_factor' + + ## Rules applied to user 'john' + # - domain: 'dev.example.com' + # resources: + # - '^/users/john/.*$' + # subject: 'user:john' + # policy: 'two_factor' + + ## Rules applied to user 'harry' + # - domain: 'dev.example.com' + # resources: + # - '^/users/harry/.*$' + # subject: 'user:harry' + # policy: 'two_factor' + + ## Rules applied to user 'bob' + # - domain: '*.mail.example.com' + # subject: 'user:bob' + # policy: 'two_factor' + # - domain: 'dev.example.com' + # resources: + # - '^/users/bob/.*$' + # subject: 'user:bob' + # policy: 'two_factor' + +## +## Session Provider Configuration +## +## The session cookies identify the user once logged in. +## The available providers are: `memory`, `redis`. Memory is the provider unless redis is defined. +session: + ## The secret to encrypt the session data. This is only used with Redis / Redis Sentinel. + ## Secret can also be set using a secret: https://www.authelia.com/c/secrets + # secret: 'insecure_session_secret' + + ## Cookies configures the list of allowed cookie domains for sessions to be created on. + ## Undefined values will default to the values below. + cookies: + - + ## The name of the session cookie. + #name: 'authelia_session' + + ## The domain to protect. + ## Note: the Authelia portal must also be in that domain. + domain: '{{ mustEnv "APP_DOMAIN" }}' + + ## Required. The fully qualified URI of the portal to redirect users to on proxies that support redirections. + ## Rules: + ## - MUST use the secure scheme 'https://' + ## - The above 'domain' option MUST either: + ## - Match the host portion of this URI. + ## - Match the suffix of the host portion when prefixed with '.'. + authelia_url: 'https://auth.{{ mustEnv "APP_DOMAIN" }}' + + ## Optional. The fully qualified URI used as the redirection location if the portal is accessed directly. Not + ## configuring this option disables the automatic redirection behaviour. + ## + ## Note: this parameter is optional. If not provided, user won't be redirected upon successful authentication + ## unless they were redirected to Authelia by the proxy. + ## + ## Rules: + ## - MUST use the secure scheme 'https://' + ## - MUST not match the 'authelia_url' option. + ## - The above 'domain' option MUST either: + ## - Match the host portion of this URI. + ## - Match the suffix of the host portion when prefixed with '.'. + default_redirection_url: 'https://{{ mustEnv "APP_DOMAIN" }}' + + ## Sets the Cookie SameSite value. Possible options are none, lax, or strict. + ## Please read https://www.authelia.com/c/session#same_site + # same_site: 'lax' + + ## The value for inactivity, expiration, and remember_me are in seconds or the duration common syntax. + ## All three of these values affect the cookie/session validity period. Longer periods are considered less secure + ## because a stolen cookie will last longer giving attackers more time to spy or attack. + + ## The inactivity time before the session is reset. If expiration is set to 1h, and this is set to 5m, if the user + ## does not select the remember me option their session will get destroyed after 1h, or after 5m since the last + ## time Authelia detected user activity. + # inactivity: '5 minutes' + + ## The time before the session cookie expires and the session is destroyed if remember me IS NOT selected by the + ## user. + # expiration: '1 hour' + + ## The time before the cookie expires and the session is destroyed if remember me IS selected by the user. Setting + ## this value to -1 disables remember me for this session cookie domain. If allowed and the user uses the remember + ## me checkbox this overrides the expiration option and disables the inactivity option. + # remember_me: '1 month' + + ## Cookie Session Domain default 'name' value. + name: 'authelia_session' + + ## Cookie Session Domain default 'same_site' value. + same_site: 'lax' + + ## Cookie Session Domain default 'inactivity' value. + inactivity: '5m' + + ## Cookie Session Domain default 'expiration' value. + expiration: '1h' + + ## Cookie Session Domain default 'remember_me' value. + remember_me: '1M' + + ## + ## Redis Provider + ## + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness + ## + # redis: + # host: '127.0.0.1' + # port: 6379 + ## Use a unix socket instead + # host: '/var/run/redis/redis.sock' + + ## Username used for redis authentication. This is optional and a new feature in redis 6.0. + # username: 'authelia' + + ## Password can also be set using a secret: https://www.authelia.com/c/secrets + # password: 'authelia' + + ## This is the Redis DB Index https://redis.io/commands/select (sometimes referred to as database number, DB, etc). + # database_index: 0 + + ## The maximum number of concurrent active connections to Redis. + # maximum_active_connections: 8 + + ## The target number of idle connections to have open ready for work. Useful when opening connections is slow. + # minimum_idle_connections: 0 + + ## The Redis TLS configuration. If defined will require a TLS connection to the Redis instance(s). + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. + # server_name: 'myredis.example.com' + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: 'TLS1.2' + + ## Maximum TLS version for the connection. + # maximum_version: 'TLS1.3' + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # ... + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # ... + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # ... + # -----END RSA PRIVATE KEY----- + + ## The Redis HA configuration options. + ## This provides specific options to Redis Sentinel, sentinel_name must be defined (Master Name). + # high_availability: + ## Sentinel Name / Master Name. + # sentinel_name: 'mysentinel' + + ## Specific username for Redis Sentinel. The node username and password is configured above. + # sentinel_username: 'sentinel_specific_user' + + ## Specific password for Redis Sentinel. The node username and password is configured above. + # sentinel_password: 'sentinel_specific_pass' + + ## The additional nodes to pre-seed the redis provider with (for sentinel). + ## If the host in the above section is defined, it will be combined with this list to connect to sentinel. + ## For high availability to be used you must have either defined; the host above or at least one node below. + # nodes: + # - host: 'sentinel-node1' + # port: 6379 + # - host: 'sentinel-node2' + # port: 6379 + + ## Choose the host with the lowest latency. + # route_by_latency: false + + ## Choose the host randomly. + # route_randomly: false + +## +## Regulation Configuration +## +## This mechanism prevents attackers from brute forcing the first factor. It bans the user if too many attempts are made +## in a short period of time. +# regulation: + ## The number of failed login attempts before user is banned. Set it to 0 to disable regulation. + # max_retries: 3 + + ## The time range during which the user can attempt login before being banned in the duration common syntax. The user + ## is banned if the authentication failed 'max_retries' times in a 'find_time' seconds window. + # find_time: '2 minutes' + + ## The length of time before a banned user can login again in the duration common syntax. + # ban_time: '5 minutes' + +## +## Storage Provider Configuration +## +## The available providers are: `local`, `mysql`, `postgres`. You must use one and only one of these providers. +storage: + ## The encryption key that is used to encrypt sensitive information in the database. Must be a string with a minimum + ## length of 20. Please see the docs if you configure this with an undesirable key and need to change it, you MUST use + ## the CLI to change this in the database if you want to change it from a previously configured value. + # encryption_key: 'you_must_generate_a_random_string_of_more_than_twenty_chars_and_configure_this' + + ## + ## Local (Storage Provider) + ## + ## This stores the data in a SQLite3 Database. + ## This is only recommended for lightweight non-stateful installations. + ## + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness + ## + local: + ## Path to the SQLite3 Database. + path: '/persist/db.sqlite3' + + ## + ## MySQL / MariaDB (Storage Provider) + ## + # mysql: + ## The address of the MySQL server to connect to in the address common syntax. + ## Format: [://][:]. + ## Square brackets indicate optional portions of the format. Scheme must be 'tcp', 'tcp4', 'tcp6', or 'unix`. + ## The default scheme is 'unix' if the address is an absolute path otherwise it's 'tcp'. The default port is '3306'. + # address: 'tcp://127.0.0.1:3306' + + ## The database name to use. + # database: 'authelia' + + ## The username used for SQL authentication. + # username: 'authelia' + + ## The password used for SQL authentication. + ## Can also be set using a secret: https://www.authelia.com/c/secrets + # password: 'mypassword' + + ## The connection timeout in the duration common syntax. + # timeout: '5 seconds' + + ## MySQL TLS settings. Configuring this requires TLS. + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the address options hostname. + # server_name: 'mysql.example.com' + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: 'TLS1.2' + + ## Maximum TLS version for the connection. + # maximum_version: 'TLS1.3' + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # ... + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # ... + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # ... + # -----END RSA PRIVATE KEY----- + + ## + ## PostgreSQL (Storage Provider) + ## + # postgres: + ## The address of the PostgreSQL server to connect to in the address common syntax. + ## Format: [://][:]. + ## Square brackets indicate optional portions of the format. Scheme must be 'tcp', 'tcp4', 'tcp6', or 'unix`. + ## The default scheme is 'unix' if the address is an absolute path otherwise it's 'tcp'. The default port is '5432'. + # address: 'tcp://127.0.0.1:5432' + + ## The database name to use. + # database: 'authelia' + + ## The schema name to use. + # schema: 'public' + + ## The username used for SQL authentication. + # username: 'authelia' + + ## The password used for SQL authentication. + ## Can also be set using a secret: https://www.authelia.com/c/secrets + # password: 'mypassword' + + ## The connection timeout in the duration common syntax. + # timeout: '5 seconds' + + ## PostgreSQL TLS settings. Configuring this requires TLS. + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the address options hostname. + # server_name: 'postgres.example.com' + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: 'TLS1.2' + + ## Maximum TLS version for the connection. + # maximum_version: 'TLS1.3' + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # ... + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # ... + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # ... + # -----END RSA PRIVATE KEY----- + +## +## Notification Provider +## +## Notifications are sent to users when they require a password reset, a WebAuthn registration or a TOTP registration. +## The available providers are: filesystem, smtp. You must use only one of these providers. +notifier: + ## You can disable the notifier startup check by setting this to true. + disable_startup_check: false + + ## + ## File System (Notification Provider) + ## + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness + ## + filesystem: + filename: '/persist/notification.txt' + + ## + ## SMTP (Notification Provider) + ## + ## Use a SMTP server for sending notifications. Authelia uses the PLAIN or LOGIN methods to authenticate. + ## [Security] By default Authelia will: + ## - force all SMTP connections over TLS including unauthenticated connections + ## - use the disable_require_tls boolean value to disable this requirement + ## (only works for unauthenticated connections) + ## - validate the SMTP server x509 certificate during the TLS handshake against the hosts trusted certificates + ## (configure in tls section) + # smtp: + ## The address of the SMTP server to connect to in the address common syntax. + # address: 'smtp://127.0.0.1:25' + + ## The connection timeout in the duration common syntax. + # timeout: '5 seconds' + + ## The username used for SMTP authentication. + # username: 'test' + + ## The password used for SMTP authentication. + ## Can also be set using a secret: https://www.authelia.com/c/secrets + # password: 'password' + + ## The sender is used to is used for the MAIL FROM command and the FROM header. + ## If this is not defined and the username is an email, we use the username as this value. This can either be just + ## an email address or the RFC5322 'Name ' format. + # sender: 'Authelia ' + + ## HELO/EHLO Identifier. Some SMTP Servers may reject the default of localhost. + # identifier: 'localhost' + + ## Subject configuration of the emails sent. {title} is replaced by the text from the notifier. + # subject: '[Authelia] {title}' + + ## This address is used during the startup check to verify the email configuration is correct. + ## It's not important what it is except if your email server only allows local delivery. + # startup_check_address: 'test@authelia.com' + + ## By default we require some form of TLS. This disables this check though is not advised. + # disable_require_tls: false + + ## Disables sending HTML formatted emails. + # disable_html_emails: false + + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the address options hostname. + # server_name: 'smtp.example.com' + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: 'TLS1.2' + + ## Maximum TLS version for the connection. + # maximum_version: 'TLS1.3' + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # ... + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # ... + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # ... + # -----END RSA PRIVATE KEY----- + +## +## Identity Providers +## +identity_providers: + + ## + ## OpenID Connect (Identity Provider) + ## + ## It's recommended you read the documentation before configuration of this section: + ## https://www.authelia.com/c/oidc + oidc: + ## The hmac_secret is used to sign OAuth2 tokens (authorization code, access tokens and refresh tokens). + ## HMAC Secret can also be set using a secret: https://www.authelia.com/c/secrets + hmac_secret: {{ secret (mustEnv "HMAC_SECRET_FILE") }} + + ## The JWK's issuer option configures multiple JSON Web Keys. It's required that at least one of the JWK's + ## configured has the RS256 algorithm. For RSA keys (RS or PS) the minimum is a 2048 bit key. + jwks: + - + ## Key ID embedded into the JWT header for key matching. Must be an alphanumeric string with 7 or less characters. + ## This value is automatically generated if not provided. It's recommended to not configure this. + # key_id: 'example' + + ## The key algorithm used with this key. + algorithm: 'RS256' + + ## The key use expected with this key. Currently only 'sig' is supported. + use: 'sig' + + ## Required Private Key in PEM DER form. + key: {{ secret (mustEnv "JWT_PRIVATE_KEY_FILE") | mindent 10 "|" | msquote }} + + + ## Optional matching certificate chain in PEM DER form that matches the key. All certificates within the chain + ## must be valid and current, and from top to bottom each certificate must be signed by the subsequent one. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # ... + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # ... + # -----END CERTIFICATE----- + + ## Enables additional debug messages. + # enable_client_debug_messages: false + + ## SECURITY NOTICE: It's not recommended changing this option and values below 8 are strongly discouraged. + # minimum_parameter_entropy: 8 + + ## SECURITY NOTICE: It's not recommended changing this option, and highly discouraged to have it set to 'never' + ## for security reasons. + # enforce_pkce: 'public_clients_only' + + ## SECURITY NOTICE: It's not recommended changing this option. We encourage you to read the documentation and fully + ## understanding it before enabling this option. + # enable_jwt_access_token_stateless_introspection: false + + ## The signing algorithm used for signing the discovery and metadata responses. An issuer JWK with a matching + ## algorithm must be available when configured. Most clients completely ignore this and it has a performance cost. + # discovery_signed_response_alg: 'none' + + ## The signing key id used for signing the discovery and metadata responses. An issuer JWK with a matching key id + ## must be available when configured. Most clients completely ignore this and it has a performance cost. + # discovery_signed_response_key_id: '' + + ## Authorization Policies which can be utilized by clients. The 'policy_name' is an arbitrary value that you pick + ## which is utilized as the value for the 'authorization_policy' on the client. + # authorization_policies: + # policy_name: + # default_policy: 'two_factor' + # rules: + # - policy: 'one_factor' + # subject: 'group:services' + + ## The lifespans configure the expiration for these token types in the duration common syntax. In addition to this + ## syntax the lifespans can be customized per-client. + # lifespans: + ## Configures the default/fallback lifespan for given token types. This behaviour applies to all clients and all + ## grant types but you can override this behaviour using the custom lifespans. + # access_token: '1 hour' + # authorize_code: '1 minute' + # id_token: '1 hour' + # refresh_token: '90 minutes' + + ## Cross-Origin Resource Sharing (CORS) settings. + # cors: + ## List of endpoints in addition to the metadata endpoints to permit cross-origin requests on. + # endpoints: + # - 'authorization' + # - 'pushed-authorization-request' + # - 'token' + # - 'revocation' + # - 'introspection' + # - 'userinfo' + + ## List of allowed origins. + ## Any origin with https is permitted unless this option is configured or the + ## allowed_origins_from_client_redirect_uris option is enabled. + # allowed_origins: + # - 'https://example.com' + + ## Automatically adds the origin portion of all redirect URI's on all clients to the list of allowed_origins, + ## provided they have the scheme http or https and do not have the hostname of localhost. + # allowed_origins_from_client_redirect_uris: false + + ## Clients is a list of known clients and their configuration. + clients: + - + ## The Client ID is the OAuth 2.0 and OpenID Connect 1.0 Client ID which is used to link an application to a + ## configuration. + client_id: 'grist-local' + + ## The description to show to users when they end up on the consent screen. Defaults to the ID above. + client_name: 'Grist' + + ## The client secret is a shared secret between Authelia and the consumer of this client. + # yamllint disable-line rule:line-length + client_secret: {{ secret (mustEnv "GRIST_CLIENT_SECRET_DIGEST_FILE") }} + + ## Sector Identifiers are occasionally used to generate pairwise subject identifiers. In most cases this is not + ## necessary. It is critical to read the documentation for more information. + # sector_identifier_uri: 'https://example.com/sector.json' + + ## Sets the client to public. This should typically not be set, please see the documentation for usage. + # public: false + + ## Redirect URI's specifies a list of valid case-sensitive callbacks for this client. + redirect_uris: + - {{ mustEnv "GRIST_OAUTH_CALLBACK_URL" | quote }} + + ## Request URI's specifies a list of valid case-sensitive TLS-secured URIs for this client for use as + ## URIs to fetch Request Objects. + # request_uris: + # - 'https://oidc.example.com:8080/oidc/request-object.jwk' + + ## Audience this client is allowed to request. + # audience: [] + + ## Scopes this client is allowed to request. + scopes: + - 'openid' + - 'groups' + - 'email' + - 'profile' + + ## Grant Types configures which grants this client can obtain. + ## It's not recommended to define this unless you know what you're doing. + # grant_types: + # - 'authorization_code' + + ## Response Types configures which responses this client can be sent. + ## It's not recommended to define this unless you know what you're doing. + # response_types: + # - 'code' + + ## Response Modes configures which response modes this client supports. + # response_modes: + # - 'form_post' + # - 'query' + + ## The policy to require for this client; one_factor or two_factor. Can also be the key names for the + ## authorization policies section. + authorization_policy: 'one_factor' + + ## The custom lifespan name to use for this client. This must be configured independent of the client before + ## utilization. Custom lifespans are reusable similar to authorization policies. + # lifespan: '' + + ## The consent mode controls how consent is obtained. + # consent_mode: 'auto' + + ## This value controls the duration a consent on this client remains remembered when the consent mode is + ## configured as 'auto' or 'pre-configured' in the duration common syntax. + # pre_configured_consent_duration: '1 week' + + ## Requires the use of Pushed Authorization Requests for this client when set to true. + # require_pushed_authorization_requests: false + + ## Enforces the use of PKCE for this client when set to true. + # require_pkce: false + + ## Enforces the use of PKCE for this client when configured, and enforces the specified challenge method. + ## Options are 'plain' and 'S256'. + # pkce_challenge_method: 'S256' + + ## The permitted client authentication method for the Token Endpoint for this client. + ## For confidential client types this value defaults to 'client_secret_basic' and for the public client types it + ## defaults to 'none' per the specifications. + # token_endpoint_auth_method: 'client_secret_basic' + + ## The permitted client authentication signing algorithm for the Token Endpoint for this client when using + ## the 'client_secret_jwt' or 'private_key_jwt' token_endpoint_auth_method. + # token_endpoint_auth_signing_alg: 'RS256' + + ## The signing algorithm which must be used for request objects. A client JWK with a matching algorithm must be + ## available if configured. + # request_object_signing_alg: 'RS256' + + ## The signing algorithm used for signing the authorization response. An issuer JWK with a matching algorithm + ## must be available when configured. Configuring this value enables the JWT Secured Authorization Response + ## Mode (JARM) for this client. JARM is not understood by a majority of clients so you should only configure + ## this when you know it's supported. + ## Has no effect if authorization_signed_response_key_id is configured. + # authorization_signed_response_alg: 'none' + + ## The signing key id used for signing the authorization response. An issuer JWK with a matching key id must be + ## available when configured. Configuring this value enables the JWT Secured Authorization Response Mode (JARM) + ## for this client. JARM is not understood by a majority of clients so you should only configure this when you + ## know it's supported. + # authorization_signed_response_key_id: '' + + ## The signing algorithm used for ID Tokens. An issuer JWK with a matching algorithm must be available when + ## configured. Has no effect if id_token_signed_response_key_id is configured. + # id_token_signed_response_alg: 'RS256' + + ## The signing key id used for ID Tokens. An issuer JWK with a matching key id must be available when + ## configured. + # id_token_signed_response_key_id: '' + + ## The signing algorithm used for Access Tokens. An issuer JWK with a matching algorithm must be available. + ## Has no effect if access_token_signed_response_key_id is configured. Values other than 'none' enable RFC9068 + ## for this client. + # access_token_signed_response_alg: 'none' + + ## The signing key id used for Access Tokens. An issuer JWK with a matching key id must be available when + ## configured. Values other than a blank value enable RFC9068 for this client. + # access_token_signed_response_key_id: '' + + ## The signing algorithm used for User Info responses. An issuer JWK with a matching algorithm must be + ## available. Has no effect if userinfo_signing_key_id is configured. + # userinfo_signed_response_alg: 'none' + + ## The signing key id used for User Info responses. An issuer JWK with a matching key id must be available when + ## configured. + # userinfo_signed_response_key_id: '' + + ## The signing algorithm used for Introspection responses. An issuer JWK with a matching algorithm must be + ## available when configured. Has no effect if introspection_signed_response_key_id is configured. + # introspection_signed_response_alg: 'none' + + ## The signing key id used for Introspection responses. An issuer JWK with a matching key id must be available + ## when configured. + # introspection_signed_response_key_id: '' + + ## Trusted public keys configuration for request object signing for things such as 'private_key_jwt'. + ## URL of the HTTPS endpoint which serves the keys. Please note the 'jwks_uri' and the 'jwks' option below + ## are mutually exclusive. + # jwks_uri: 'https://app.example.com/jwks.json' + + ## Trusted public keys configuration for request object signing for things such as 'private_key_jwt'. + ## List of JWKs known and registered with this client. It's recommended to use the 'jwks_uri' option if + ## available due to key rotation. Please note the 'jwks' and the 'jwks_uri' option above are mutually exclusive. + # jwks: + # - + ## Key ID used to match the JWT's to an individual identifier. This option is required if configured. + # key_id: 'example' + + ## The key algorithm expected with this key. + # algorithm: 'RS256' + + ## The key use expected with this key. Currently only 'sig' is supported. + # use: 'sig' + + ## Required Public Key in PEM DER form. + # key: | + # -----BEGIN RSA PUBLIC KEY----- + # ... + # -----END RSA PUBLIC KEY----- + + ## The matching certificate chain in PEM DER form that matches the key if available. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # ... + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # ... + # -----END CERTIFICATE----- +... diff --git a/docker-compose-examples/grist-traefik-oidc-auth/configs/authelia/users_database.yml b/docker-compose-examples/grist-traefik-oidc-auth/configs/authelia/users_database.yml new file mode 100644 index 00000000..172a106f --- /dev/null +++ b/docker-compose-examples/grist-traefik-oidc-auth/configs/authelia/users_database.yml @@ -0,0 +1,14 @@ +# Primary users file. + +# Passwords are generated using 'authelia crypto hash generate argon2' +# E.g: +# docker run authelia/authelia:4 authelia crypto hash generate argon2 --password "test" +# See https://www.authelia.com/reference/guides/passwords/#yaml-format + +users: + test: + disabled: false + displayname: 'Test' + password: '$argon2id$v=19$m=65536,t=3,p=4$j1Jub3z0jWBmXNOjNpRK5w$d5176FINCAuzdT3uehQqMS08FC4fadAGrqyZL+0W+p4' + email: 'test@example.org' + groups: [] diff --git a/docker-compose-examples/grist-traefik-oidc-auth/configs/traefik/config.yml b/docker-compose-examples/grist-traefik-oidc-auth/configs/traefik/config.yml new file mode 100644 index 00000000..5067ebff --- /dev/null +++ b/docker-compose-examples/grist-traefik-oidc-auth/configs/traefik/config.yml @@ -0,0 +1,30 @@ +providers: + # Enables reading docker label config values + docker: {} + +entrypoints: + # Defines a secure entrypoint using TLS encryption + websecure: + address: ":443" + http: + tls: true + # Defines an insecure entrypoint that redirects to the secure one. + web: + address: ":80" + http: + # Redirects HTTP to HTTPS + redirections: + entrypoint: + to: "websecure" + scheme: "https" + +# Enables automatic certificate renewal +certificatesResolvers: + letsencrypt: + acme: + email: "my_email@example.com" + storage: /acme/acme.json + tlschallenge: true + +api: + insecure: true diff --git a/docker-compose-examples/grist-traefik-oidc-auth/docker-compose.yml b/docker-compose-examples/grist-traefik-oidc-auth/docker-compose.yml new file mode 100644 index 00000000..2c8b8ee9 --- /dev/null +++ b/docker-compose-examples/grist-traefik-oidc-auth/docker-compose.yml @@ -0,0 +1,118 @@ +secrets: + # These secrets are used by Authelia + JWT_SECRET: + file: ${SECRETS_DIR}/JWT_SECRET + SESSION_SECRET: + file: ${SECRETS_DIR}/SESSION_SECRET + STORAGE_ENCRYPTION_KEY: + file: ${SECRETS_DIR}/STORAGE_ENCRYPTION_KEY + # These secrets are for using Authelia as an OIDC provider + HMAC_SECRET: + file: ${SECRETS_DIR}/HMAC_SECRET + JWT_PRIVATE_KEY: + file: ${SECRETS_DIR}/certs/private.pem + GRIST_CLIENT_SECRET_DIGEST: + file: ${SECRETS_DIR}/GRIST_CLIENT_SECRET_DIGEST + +services: + grist: + image: gristlabs/grist:latest + environment: + # The URL of given OIDC provider. Used for redirects, among other things. + GRIST_OIDC_IDP_ISSUER: https://${AUTHELIA_DOMAIN} + # Client ID, as configured with the OIDC provider. + GRIST_OIDC_IDP_CLIENT_ID: grist-local + # Client secret, as provided by the OIDC provider. + GRIST_OIDC_IDP_CLIENT_SECRET: ${GRIST_CLIENT_SECRET} + # The URL to redirect to with the OIDC provider to log out. + # Some OIDC providers will automatically configure this. + GRIST_OIDC_IDP_END_SESSION_ENDPOINT: https://${AUTHELIA_DOMAIN}/logout + # Allow self-signed certificates so this example behaves correctly. + # REMOVE THIS IF HOSTING ON THE INTERNET. + NODE_TLS_REJECT_UNAUTHORIZED: 0 + + # Forces Grist to only use a single team called 'Example' + GRIST_SINGLE_ORG: my-grist-team # alternatively, GRIST_ORG_IN_PATH: "true" for multi-team operation + # Force users to login (disable anonymous access) + GRIST_FORCE_LOGIN: true + # Base URL Grist redirects to when navigating. Change this to your domain. + APP_HOME_URL: https://${GRIST_DOMAIN} + # Default email for the "Admin" account + GRIST_DEFAULT_EMAIL: ${DEFAULT_EMAIL:-test@example.org} + restart: always + volumes: + # Where to store persistent data, such as documents. + - ${PERSIST_DIR}/grist:/persist + labels: + - "traefik.http.services.grist.loadbalancer.server.port=8484" + - "traefik.http.routers.grist.rule=Host(`${GRIST_DOMAIN}`)" + - "traefik.http.routers.grist.service=grist" + # Uncomment and configure in traefik-config.yml to enable automatic HTTPS certificate setup. + #- "traefik.http.routers.grist.tls.certresolver=letsencrypt" + depends_on: + # Grist attempts to setup OIDC when it starts, making a request to the OIDC service. + # This will fail if Authelia isn't ready and reachable. + # Traefik will only start routing to Authelia when it's registered as healthy. + # Making Grist wait for Authelia to be healthy should avoid this issue. + authelia: + condition: service_healthy + traefik: + condition: service_started + + traefik: + image: traefik:latest + ports: + # HTTP Ports + - "80:80" + - "443:443" + # The Web UI (enabled by --api.insecure=true) + - "8080:8080" + - "8082:8082" + volumes: + # Set the config file for traefik - this is loaded automatically. + - ./configs/traefik/config.yml:/etc/traefik/traefik.yml + # Certificate location, if automatic certificate setup is enabled. + - ./secrets/acme_certificates:/acme + # Traefik needs docker access when configured via docker labels. + - /var/run/docker.sock:/var/run/docker.sock + networks: + default: + aliases: + # Enables Grist to resolve this domain to Traefik when doing OIDC setup. + - ${AUTHELIA_DOMAIN} + + authelia: + image: authelia/authelia:4 + secrets: + - HMAC_SECRET + - JWT_SECRET + - JWT_PRIVATE_KEY + - GRIST_CLIENT_SECRET_DIGEST + - SESSION_SECRET + - STORAGE_ENCRYPTION_KEY + environment: + AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET_FILE: '/run/secrets/JWT_SECRET' + AUTHELIA_SESSION_SECRET_FILE: '/run/secrets/SESSION_SECRET' + AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE: '/run/secrets/STORAGE_ENCRYPTION_KEY' + HMAC_SECRET_FILE: '/run/secrets/HMAC_SECRET' + JWT_PRIVATE_KEY_FILE: '/run/secrets/JWT_PRIVATE_KEY' + # Domain Grist is hosted at. Custom variable that's interpolated into the Authelia config + APP_DOMAIN: ${GRIST_DOMAIN} + # Where Authelia should redirect to after successful authentication. + GRIST_OAUTH_CALLBACK_URL: https://${GRIST_DOMAIN}/oauth2/callback + # Hash of the client secret provided to Grist. + GRIST_CLIENT_SECRET_DIGEST_FILE: "/run/secrets/GRIST_CLIENT_SECRET_DIGEST" + volumes: + - ./configs/authelia:/config + - ${PERSIST_DIR}/authelia:/persist + command: + - 'authelia' + - '--config=/config/configuration.yml' + # Enables templating in the config file + - '--config.experimental.filters=template' + labels: + - "traefik.http.services.authelia.loadbalancer.server.port=9091" + - "traefik.http.routers.authelia.rule=Host(`${AUTHELIA_DOMAIN}`)" + - "traefik.http.routers.authelia.service=authelia" + # Uncomment and configure in traefik-config.yml to enable automatic HTTPS certificate setup. + #- "traefik.http.routers.authelia.tls.certresolver=letsencrypt" diff --git a/docker-compose-examples/grist-traefik-oidc-auth/env-template b/docker-compose-examples/grist-traefik-oidc-auth/env-template new file mode 100644 index 00000000..e9e0bd79 --- /dev/null +++ b/docker-compose-examples/grist-traefik-oidc-auth/env-template @@ -0,0 +1,6 @@ +GRIST_DOMAIN=grist.localhost +AUTHELIA_DOMAIN=auth.grist.localhost +DEFAULT_EMAIL=test@example.org +PERSIST_DIR=./persist +SECRETS_DIR=./secrets +GRIST_CLIENT_SECRET= diff --git a/docker-compose-examples/grist-traefik-oidc-auth/generateSecureSecrets.sh b/docker-compose-examples/grist-traefik-oidc-auth/generateSecureSecrets.sh new file mode 100755 index 00000000..7c6a29ad --- /dev/null +++ b/docker-compose-examples/grist-traefik-oidc-auth/generateSecureSecrets.sh @@ -0,0 +1,32 @@ +# Helper script to securely generate random secrets for Authelia. + +SCRIPT_DIR=$(dirname $0) + +# Copy over template files to final locations +cp -R "$SCRIPT_DIR/secrets_template" "$SCRIPT_DIR/secrets" +cp "$SCRIPT_DIR/env-template" "$SCRIPT_DIR/.env" + +# Parses an Aurelia generated secret for the value +function getSecret { + cut -d ":" -f 2 <<< "$1" | tr -d '[:blank:]' +} + +function generateSecureString { + getSecret "$(docker run authelia/authelia:4 authelia crypto rand --charset=rfc3986 --length="$1")" +} + +generateSecureString 128 > "$SCRIPT_DIR/secrets/HMAC_SECRET" +generateSecureString 128 > "$SCRIPT_DIR/secrets/JWT_SECRET" +generateSecureString 128 > "$SCRIPT_DIR/secrets/SESSION_SECRET" +generateSecureString 128 > "$SCRIPT_DIR/secrets/STORAGE_ENCRYPTION_KEY" + +# Generates the OIDC secret key for the Grist client +CLIENT_SECRET_OUTPUT="$(docker run authelia/authelia:4 authelia crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986)" +CLIENT_SECRET=$(getSecret "$(grep 'Password' <<< $CLIENT_SECRET_OUTPUT)") +sed -i "/GRIST_CLIENT_SECRET=$/d" "$SCRIPT_DIR/.env" +echo "GRIST_CLIENT_SECRET=$CLIENT_SECRET" >> "$SCRIPT_DIR/.env" +getSecret "$(grep 'Digest' <<< $CLIENT_SECRET_OUTPUT)" >> "$SCRIPT_DIR/secrets/GRIST_CLIENT_SECRET_DIGEST" + +# Generate JWT certificates Authelia needs for OIDC +docker run -v ./secrets/certs:/certs authelia/authelia:4 authelia crypto certificate rsa generate -d /certs + diff --git a/docker-compose-examples/grist-traefik-oidc-auth/secrets_template/GRIST_CLIENT_SECRET_DIGEST b/docker-compose-examples/grist-traefik-oidc-auth/secrets_template/GRIST_CLIENT_SECRET_DIGEST new file mode 100644 index 00000000..e69de29b diff --git a/docker-compose-examples/grist-traefik-oidc-auth/secrets_template/HMAC_SECRET b/docker-compose-examples/grist-traefik-oidc-auth/secrets_template/HMAC_SECRET new file mode 100644 index 00000000..e69de29b diff --git a/docker-compose-examples/grist-traefik-oidc-auth/secrets_template/JWT_SECRET b/docker-compose-examples/grist-traefik-oidc-auth/secrets_template/JWT_SECRET new file mode 100644 index 00000000..e69de29b diff --git a/docker-compose-examples/grist-traefik-oidc-auth/secrets_template/SESSION_SECRET b/docker-compose-examples/grist-traefik-oidc-auth/secrets_template/SESSION_SECRET new file mode 100644 index 00000000..e69de29b diff --git a/docker-compose-examples/grist-traefik-oidc-auth/secrets_template/STORAGE_ENCRYPTION_KEY b/docker-compose-examples/grist-traefik-oidc-auth/secrets_template/STORAGE_ENCRYPTION_KEY new file mode 100644 index 00000000..e69de29b diff --git a/docker-compose-examples/grist-traefik-oidc-auth/secrets_template/certs/private.pem b/docker-compose-examples/grist-traefik-oidc-auth/secrets_template/certs/private.pem new file mode 100644 index 00000000..e69de29b diff --git a/docker-compose-examples/grist-with-postgres-redis-minio/.env b/docker-compose-examples/grist-with-postgres-redis-minio/.env new file mode 100644 index 00000000..1ade28c8 --- /dev/null +++ b/docker-compose-examples/grist-with-postgres-redis-minio/.env @@ -0,0 +1,3 @@ +DATABASE_PASSWORD=CHANGE THIS PASSWORD +MINIO_PASSWORD=CHANGE THIS PASSWORD +PERSIST_DIR=./persist diff --git a/docker-compose-examples/grist-with-postgres-redis-minio/README.md b/docker-compose-examples/grist-with-postgres-redis-minio/README.md new file mode 100644 index 00000000..517d1716 --- /dev/null +++ b/docker-compose-examples/grist-with-postgres-redis-minio/README.md @@ -0,0 +1,20 @@ +This examples shows how to start up Grist that: +- Uses Postgres as a home database, +- Redis as a state store. +- MinIO for snapshot storage + +It is STRONGLY RECOMMENDED not to use this container in a way that makes it accessible to the internet. +This setup lacks basic security or authentication. + +Other examples demonstrate how to set up authentication and HTTPS. + +See https://support.getgrist.com/self-managed for more information. + +This setup is based on one provided by Akito (https://github.com/theAkito). + +## How to run this example + +Before running this example, it's very strongly recommended to update the `_PASSWORD` environment variables +in `.env` to be long, randomly generated passwords. + +This example can be run with `docker compose up`. diff --git a/docker-compose-examples/grist-with-postgres-redis-minio/docker-compose.yml b/docker-compose-examples/grist-with-postgres-redis-minio/docker-compose.yml new file mode 100644 index 00000000..1202fd27 --- /dev/null +++ b/docker-compose-examples/grist-with-postgres-redis-minio/docker-compose.yml @@ -0,0 +1,76 @@ +services: + grist: + image: gristlabs/grist:latest + environment: + # Postgres database setup + TYPEORM_DATABASE: grist + TYPEORM_USERNAME: grist + TYPEORM_HOST: grist-db + TYPEORM_LOGGING: false + TYPEORM_PASSWORD: ${DATABASE_PASSWORD} + TYPEORM_PORT: 5432 + TYPEORM_TYPE: postgres + + # Redis setup + REDIS_URL: redis://grist-redis + + # MinIO setup. This requires the bucket set up on the MinIO instance with versioning enabled. + GRIST_DOCS_MINIO_ACCESS_KEY: grist + GRIST_DOCS_MINIO_SECRET_KEY: ${MINIO_PASSWORD} + GRIST_DOCS_MINIO_USE_SSL: 0 + GRIST_DOCS_MINIO_BUCKET: grist-docs + GRIST_DOCS_MINIO_ENDPOINT: grist-minio + GRIST_DOCS_MINIO_PORT: 9000 + + volumes: + # Where to store persistent data, such as documents. + - ${PERSIST_DIR}/grist:/persist + ports: + - 8484:8484 + depends_on: + - grist-db + - grist-redis + - grist-minio + - minio-setup + + grist-db: + image: postgres:alpine + environment: + POSTGRES_DB: grist + POSTGRES_USER: grist + POSTGRES_PASSWORD: ${DATABASE_PASSWORD} + volumes: + - ${PERSIST_DIR}/postgres:/var/lib/postgresql/data + + grist-redis: + image: redis:alpine + volumes: + - ${PERSIST_DIR}/redis:/data + + grist-minio: + image: minio/minio:latest + environment: + MINIO_ROOT_USER: grist + MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD} + volumes: + - ${PERSIST_DIR}/minio:/data + command: + server /data --console-address=":9001" + + # This sets up the buckets required in MinIO. It is only needed to make this example work. + # It isn't necessary for deployment and can be safely removed. + minio-setup: + image: minio/mc + environment: + MINIO_PASSWORD: ${MINIO_PASSWORD} + depends_on: + grist-minio: + condition: service_started + restart: on-failure + entrypoint: > + /bin/sh -c " + /usr/bin/mc alias set myminio http://grist-minio:9000 grist '$MINIO_PASSWORD'; + /usr/bin/mc mb myminio/grist-docs; + /usr/bin/mc anonymous set public myminio/grist-docs; + /usr/bin/mc version enable myminio/grist-docs; + "