diff --git a/config.template.yml b/config.template.yml
index ef53de1cf..3b8529c8a 100644
--- a/config.template.yml
+++ b/config.template.yml
@@ -498,6 +498,7 @@ storage:
username: authelia
## Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
password: mypassword
+ timeout: 5s
##
## PostgreSQL (Storage Provider)
@@ -509,6 +510,7 @@ storage:
# username: authelia
# ## Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
# password: mypassword
+ # timeout: 5s
# sslmode: disable
##
diff --git a/docs/configuration/storage/mariadb.md b/docs/configuration/storage/mariadb.md
index 047bcba25..43a36f191 100644
--- a/docs/configuration/storage/mariadb.md
+++ b/docs/configuration/storage/mariadb.md
@@ -84,3 +84,15 @@ required: yes
The password paired with the username used to connect to the database. Can also be defined using a
[secret](../secrets.md) which is also the recommended way when running as a container.
+
+### timeout
+
+type: duration
+{: .label .label-config .label-purple }
+default: 5s
+{: .label .label-config .label-blue }
+required: no
+{: .label .label-config .label-green }
+
+
+The SQL connection timeout.
diff --git a/docs/configuration/storage/mysql.md b/docs/configuration/storage/mysql.md
index 9a0e7528a..acb98f0b6 100644
--- a/docs/configuration/storage/mysql.md
+++ b/docs/configuration/storage/mysql.md
@@ -20,6 +20,7 @@ storage:
database: authelia
username: authelia
password: mypassword
+ timeout: 5s
```
## Options
@@ -84,3 +85,15 @@ required: yes
The password paired with the username used to connect to the database. Can also be defined using a
[secret](../secrets.md) which is also the recommended way when running as a container.
+
+### timeout
+
+type: duration
+{: .label .label-config .label-purple }
+default: 5s
+{: .label .label-config .label-blue }
+required: no
+{: .label .label-config .label-green }
+
+
+The SQL connection timeout.
diff --git a/docs/configuration/storage/postgres.md b/docs/configuration/storage/postgres.md
index abb97aa90..525aeeb91 100644
--- a/docs/configuration/storage/postgres.md
+++ b/docs/configuration/storage/postgres.md
@@ -80,6 +80,18 @@ required: yes
The password paired with the username used to connect to the database. Can also be defined using a
[secret](../secrets.md) which is also the recommended way when running as a container.
+### timeout
+
+type: duration
+{: .label .label-config .label-purple }
+default: 5s
+{: .label .label-config .label-blue }
+required: no
+{: .label .label-config .label-green }
+
+
+The SQL connection timeout.
+
### sslmode
type: string
diff --git a/internal/configuration/config.template.yml b/internal/configuration/config.template.yml
index ef53de1cf..3b8529c8a 100644
--- a/internal/configuration/config.template.yml
+++ b/internal/configuration/config.template.yml
@@ -498,6 +498,7 @@ storage:
username: authelia
## Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
password: mypassword
+ timeout: 5s
##
## PostgreSQL (Storage Provider)
@@ -509,6 +510,7 @@ storage:
# username: authelia
# ## Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
# password: mypassword
+ # timeout: 5s
# sslmode: disable
##
diff --git a/internal/configuration/schema/storage.go b/internal/configuration/schema/storage.go
index 168b61bc3..ecb2a65ca 100644
--- a/internal/configuration/schema/storage.go
+++ b/internal/configuration/schema/storage.go
@@ -1,5 +1,7 @@
package schema
+import "time"
+
// LocalStorageConfiguration represents the configuration when using local storage.
type LocalStorageConfiguration struct {
Path string `koanf:"path"`
@@ -7,11 +9,12 @@ type LocalStorageConfiguration struct {
// SQLStorageConfiguration represents the configuration of the SQL database.
type SQLStorageConfiguration struct {
- Host string `koanf:"host"`
- Port int `koanf:"port"`
- Database string `koanf:"database"`
- Username string `koanf:"username"`
- Password string `koanf:"password"`
+ Host string `koanf:"host"`
+ Port int `koanf:"port"`
+ Database string `koanf:"database"`
+ Username string `koanf:"username"`
+ Password string `koanf:"password"`
+ Timeout time.Duration `koanf:"timeout"`
}
// MySQLStorageConfiguration represents the configuration of a MySQL database.
@@ -31,3 +34,17 @@ type StorageConfiguration struct {
MySQL *MySQLStorageConfiguration `koanf:"mysql"`
PostgreSQL *PostgreSQLStorageConfiguration `koanf:"postgres"`
}
+
+// DefaultPostgreSQLStorageConfiguration represents the default PostgreSQL configuration.
+var DefaultPostgreSQLStorageConfiguration = PostgreSQLStorageConfiguration{
+ SQLStorageConfiguration: SQLStorageConfiguration{
+ Timeout: 5 * time.Second,
+ },
+}
+
+// DefaultMySQLStorageConfiguration represents the default MySQL configuration.
+var DefaultMySQLStorageConfiguration = MySQLStorageConfiguration{
+ SQLStorageConfiguration: SQLStorageConfiguration{
+ Timeout: 5 * time.Second,
+ },
+}
diff --git a/internal/configuration/validator/const.go b/internal/configuration/validator/const.go
index 699697bf5..55006f4bc 100644
--- a/internal/configuration/validator/const.go
+++ b/internal/configuration/validator/const.go
@@ -204,6 +204,7 @@ var ValidKeys = []string{
"storage.mysql.database",
"storage.mysql.username",
"storage.mysql.password",
+ "storage.mysql.timeout",
// PostgreSQL Storage Keys.
"storage.postgres.host",
@@ -211,6 +212,7 @@ var ValidKeys = []string{
"storage.postgres.database",
"storage.postgres.username",
"storage.postgres.password",
+ "storage.postgres.timeout",
"storage.postgres.sslmode",
// FileSystem Notifier Keys.
diff --git a/internal/configuration/validator/storage.go b/internal/configuration/validator/storage.go
index d1596757e..e130132ac 100644
--- a/internal/configuration/validator/storage.go
+++ b/internal/configuration/validator/storage.go
@@ -14,7 +14,7 @@ func ValidateStorage(configuration schema.StorageConfiguration, validator *schem
switch {
case configuration.MySQL != nil:
- validateSQLConfiguration(&configuration.MySQL.SQLStorageConfiguration, validator)
+ validateMySQLConfiguration(&configuration.MySQL.SQLStorageConfiguration, validator)
case configuration.PostgreSQL != nil:
validatePostgreSQLConfiguration(configuration.PostgreSQL, validator)
case configuration.Local != nil:
@@ -22,7 +22,11 @@ func ValidateStorage(configuration schema.StorageConfiguration, validator *schem
}
}
-func validateSQLConfiguration(configuration *schema.SQLStorageConfiguration, validator *schema.StructValidator) {
+func validateMySQLConfiguration(configuration *schema.SQLStorageConfiguration, validator *schema.StructValidator) {
+ if configuration.Timeout == 0 {
+ configuration.Timeout = schema.DefaultMySQLStorageConfiguration.Timeout
+ }
+
if configuration.Password == "" || configuration.Username == "" {
validator.Push(errors.New("the SQL username and password must be provided"))
}
@@ -33,7 +37,11 @@ func validateSQLConfiguration(configuration *schema.SQLStorageConfiguration, val
}
func validatePostgreSQLConfiguration(configuration *schema.PostgreSQLStorageConfiguration, validator *schema.StructValidator) {
- validateSQLConfiguration(&configuration.SQLStorageConfiguration, validator)
+ validateMySQLConfiguration(&configuration.SQLStorageConfiguration, validator)
+
+ if configuration.Timeout == 0 {
+ configuration.Timeout = schema.DefaultPostgreSQLStorageConfiguration.Timeout
+ }
if configuration.SSLMode == "" {
configuration.SSLMode = testModeDisabled
diff --git a/internal/storage/mysql_provider.go b/internal/storage/mysql_provider.go
index 83aaffd79..a34f74333 100644
--- a/internal/storage/mysql_provider.go
+++ b/internal/storage/mysql_provider.go
@@ -3,6 +3,7 @@ package storage
import (
"database/sql"
"fmt"
+ "time"
_ "github.com/go-sql-driver/mysql" // Load the MySQL Driver used in the connection string.
@@ -68,6 +69,9 @@ func NewMySQLProvider(configuration schema.MySQLStorageConfiguration) *MySQLProv
connectionString += fmt.Sprintf("/%s", configuration.Database)
}
+ connectionString += "?"
+ connectionString += fmt.Sprintf("timeout=%ds", int32(configuration.Timeout/time.Second))
+
db, err := sql.Open("mysql", connectionString)
if err != nil {
provider.log.Fatalf("Unable to connect to SQL database: %v", err)
diff --git a/internal/storage/postgres_provider.go b/internal/storage/postgres_provider.go
index ce85678ed..ac59dcd3c 100644
--- a/internal/storage/postgres_provider.go
+++ b/internal/storage/postgres_provider.go
@@ -4,6 +4,7 @@ import (
"database/sql"
"fmt"
"strings"
+ "time"
_ "github.com/jackc/pgx/v4/stdlib" // Load the PostgreSQL Driver used in the connection string.
@@ -73,6 +74,7 @@ func NewPostgreSQLProvider(configuration schema.PostgreSQLStorageConfiguration)
args = append(args, fmt.Sprintf("sslmode=%s", configuration.SSLMode))
}
+ args = append(args, fmt.Sprintf("connect_timeout=%d", int32(configuration.Timeout/time.Second)))
connectionString := strings.Join(args, " ")
db, err := sql.Open("pgx", connectionString)