karakeep: configure meilisearch with master key and auto update
This commit is contained in:
parent
3f1aeaa64a
commit
62213a6b82
4 changed files with 117 additions and 61 deletions
|
|
@ -2978,6 +2978,54 @@
|
||||||
"services-karakeep-options-shb.karakeep.ldap.userGroup": [
|
"services-karakeep-options-shb.karakeep.ldap.userGroup": [
|
||||||
"services-karakeep.html#services-karakeep-options-shb.karakeep.ldap.userGroup"
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.ldap.userGroup"
|
||||||
],
|
],
|
||||||
|
"services-karakeep-options-shb.karakeep.meilisearchMasterKey": [
|
||||||
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.meilisearchMasterKey"
|
||||||
|
],
|
||||||
|
"services-karakeep-options-shb.karakeep.meilisearchMasterKey.request": [
|
||||||
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.meilisearchMasterKey.request"
|
||||||
|
],
|
||||||
|
"services-karakeep-options-shb.karakeep.meilisearchMasterKey.request.group": [
|
||||||
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.meilisearchMasterKey.request.group"
|
||||||
|
],
|
||||||
|
"services-karakeep-options-shb.karakeep.meilisearchMasterKey.request.mode": [
|
||||||
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.meilisearchMasterKey.request.mode"
|
||||||
|
],
|
||||||
|
"services-karakeep-options-shb.karakeep.meilisearchMasterKey.request.owner": [
|
||||||
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.meilisearchMasterKey.request.owner"
|
||||||
|
],
|
||||||
|
"services-karakeep-options-shb.karakeep.meilisearchMasterKey.request.restartUnits": [
|
||||||
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.meilisearchMasterKey.request.restartUnits"
|
||||||
|
],
|
||||||
|
"services-karakeep-options-shb.karakeep.meilisearchMasterKey.result": [
|
||||||
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.meilisearchMasterKey.result"
|
||||||
|
],
|
||||||
|
"services-karakeep-options-shb.karakeep.meilisearchMasterKey.result.path": [
|
||||||
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.meilisearchMasterKey.result.path"
|
||||||
|
],
|
||||||
|
"services-karakeep-options-shb.karakeep.nextauthSecret": [
|
||||||
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.nextauthSecret"
|
||||||
|
],
|
||||||
|
"services-karakeep-options-shb.karakeep.nextauthSecret.request": [
|
||||||
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.nextauthSecret.request"
|
||||||
|
],
|
||||||
|
"services-karakeep-options-shb.karakeep.nextauthSecret.request.group": [
|
||||||
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.nextauthSecret.request.group"
|
||||||
|
],
|
||||||
|
"services-karakeep-options-shb.karakeep.nextauthSecret.request.mode": [
|
||||||
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.nextauthSecret.request.mode"
|
||||||
|
],
|
||||||
|
"services-karakeep-options-shb.karakeep.nextauthSecret.request.owner": [
|
||||||
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.nextauthSecret.request.owner"
|
||||||
|
],
|
||||||
|
"services-karakeep-options-shb.karakeep.nextauthSecret.request.restartUnits": [
|
||||||
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.nextauthSecret.request.restartUnits"
|
||||||
|
],
|
||||||
|
"services-karakeep-options-shb.karakeep.nextauthSecret.result": [
|
||||||
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.nextauthSecret.result"
|
||||||
|
],
|
||||||
|
"services-karakeep-options-shb.karakeep.nextauthSecret.result.path": [
|
||||||
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.nextauthSecret.result.path"
|
||||||
|
],
|
||||||
"services-karakeep-options-shb.karakeep.port": [
|
"services-karakeep-options-shb.karakeep.port": [
|
||||||
"services-karakeep.html#services-karakeep-options-shb.karakeep.port"
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.port"
|
||||||
],
|
],
|
||||||
|
|
@ -3011,30 +3059,6 @@
|
||||||
"services-karakeep-options-shb.karakeep.sso.enable": [
|
"services-karakeep-options-shb.karakeep.sso.enable": [
|
||||||
"services-karakeep.html#services-karakeep-options-shb.karakeep.sso.enable"
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.sso.enable"
|
||||||
],
|
],
|
||||||
"services-karakeep-options-shb.karakeep.sso.nextauthSecret": [
|
|
||||||
"services-karakeep.html#services-karakeep-options-shb.karakeep.sso.nextauthSecret"
|
|
||||||
],
|
|
||||||
"services-karakeep-options-shb.karakeep.sso.nextauthSecret.request": [
|
|
||||||
"services-karakeep.html#services-karakeep-options-shb.karakeep.sso.nextauthSecret.request"
|
|
||||||
],
|
|
||||||
"services-karakeep-options-shb.karakeep.sso.nextauthSecret.request.group": [
|
|
||||||
"services-karakeep.html#services-karakeep-options-shb.karakeep.sso.nextauthSecret.request.group"
|
|
||||||
],
|
|
||||||
"services-karakeep-options-shb.karakeep.sso.nextauthSecret.request.mode": [
|
|
||||||
"services-karakeep.html#services-karakeep-options-shb.karakeep.sso.nextauthSecret.request.mode"
|
|
||||||
],
|
|
||||||
"services-karakeep-options-shb.karakeep.sso.nextauthSecret.request.owner": [
|
|
||||||
"services-karakeep.html#services-karakeep-options-shb.karakeep.sso.nextauthSecret.request.owner"
|
|
||||||
],
|
|
||||||
"services-karakeep-options-shb.karakeep.sso.nextauthSecret.request.restartUnits": [
|
|
||||||
"services-karakeep.html#services-karakeep-options-shb.karakeep.sso.nextauthSecret.request.restartUnits"
|
|
||||||
],
|
|
||||||
"services-karakeep-options-shb.karakeep.sso.nextauthSecret.result": [
|
|
||||||
"services-karakeep.html#services-karakeep-options-shb.karakeep.sso.nextauthSecret.result"
|
|
||||||
],
|
|
||||||
"services-karakeep-options-shb.karakeep.sso.nextauthSecret.result.path": [
|
|
||||||
"services-karakeep.html#services-karakeep-options-shb.karakeep.sso.nextauthSecret.result.path"
|
|
||||||
],
|
|
||||||
"services-karakeep-options-shb.karakeep.sso.sharedSecret": [
|
"services-karakeep-options-shb.karakeep.sso.sharedSecret": [
|
||||||
"services-karakeep.html#services-karakeep-options-shb.karakeep.sso.sharedSecret"
|
"services-karakeep.html#services-karakeep-options-shb.karakeep.sso.sharedSecret"
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -96,22 +96,13 @@ in
|
||||||
default = "one_factor";
|
default = "one_factor";
|
||||||
};
|
};
|
||||||
|
|
||||||
nextauthSecret = lib.mkOption {
|
|
||||||
description = "NextAuth secret.";
|
|
||||||
type = lib.types.submodule {
|
|
||||||
options = contracts.secret.mkRequester {
|
|
||||||
owner = "karakeep";
|
|
||||||
restartUnits = [ "karakeep.service" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sharedSecret = lib.mkOption {
|
sharedSecret = lib.mkOption {
|
||||||
description = "OIDC shared secret for Karakeep.";
|
description = "OIDC shared secret for Karakeep.";
|
||||||
type = lib.types.submodule {
|
type = lib.types.submodule {
|
||||||
options = contracts.secret.mkRequester {
|
options = contracts.secret.mkRequester {
|
||||||
owner = "karakeep";
|
owner = "karakeep";
|
||||||
restartUnits = [ "karakeep.service" ];
|
# These services are the ones relying on the environment file containing the secrets.
|
||||||
|
restartUnits = [ "karakeep-init.service" "karakeep-workers.service" "karakeep-workers.service" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -144,12 +135,35 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nextauthSecret = lib.mkOption {
|
||||||
|
description = "NextAuth secret.";
|
||||||
|
type = lib.types.submodule {
|
||||||
|
options = contracts.secret.mkRequester {
|
||||||
|
owner = "karakeep";
|
||||||
|
# These services are the ones relying on the environment file containing the secrets.
|
||||||
|
restartUnits = [ "karakeep-init.service" "karakeep-workers.service" "karakeep-workers.service" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
meilisearchMasterKey = lib.mkOption {
|
||||||
|
description = "Master key used to secure communication with Meilisearch.";
|
||||||
|
type = lib.types.submodule {
|
||||||
|
options = contracts.secret.mkRequester {
|
||||||
|
owner = "karakeep";
|
||||||
|
# These services are the ones relying on the environment file containing the secrets.
|
||||||
|
restartUnits = [ "karakeep-init.service" "karakeep-workers.service" "karakeep-workers.service" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = (lib.mkMerge [
|
config = (lib.mkMerge [
|
||||||
(lib.mkIf cfg.enable {
|
(lib.mkIf cfg.enable {
|
||||||
services.karakeep = {
|
services.karakeep = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
meilisearch.enable = true;
|
||||||
|
|
||||||
extraEnvironment = {
|
extraEnvironment = {
|
||||||
PORT = toString cfg.port;
|
PORT = toString cfg.port;
|
||||||
|
|
@ -163,6 +177,32 @@ in
|
||||||
upstream = "http://127.0.0.1:${toString cfg.port}/";
|
upstream = "http://127.0.0.1:${toString cfg.port}/";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# Piggybacking onto the upstream karakeep-init and replacing its script by ours.
|
||||||
|
# This is needed otherwise the MEILI_MASTER_KEY is generated randomly on first start
|
||||||
|
# instead of using the value from the cfg.meilisearchMasterKey option.
|
||||||
|
systemd.services.karakeep-init = {
|
||||||
|
script = lib.mkForce ((lib.shb.replaceSecrets {
|
||||||
|
userConfig = {
|
||||||
|
MEILI_MASTER_KEY = cfg.meilisearchMasterKey.result.path;
|
||||||
|
NEXTAUTH_SECRET.source = cfg.nextauthSecret.result.path;
|
||||||
|
} // lib.optionalAttrs cfg.sso.enable {
|
||||||
|
OAUTH_CLIENT_SECRET.source = cfg.sso.sharedSecret.result.path;
|
||||||
|
};
|
||||||
|
resultPath = "/var/lib/karakeep/settings.env";
|
||||||
|
generator = lib.shb.toEnvVar;
|
||||||
|
}) + ''
|
||||||
|
export DATA_DIR="$STATE_DIRECTORY"
|
||||||
|
exec ${config.services.karakeep.package}/lib/karakeep/migrate
|
||||||
|
'');
|
||||||
|
};
|
||||||
|
})
|
||||||
|
(lib.mkIf cfg.enable {
|
||||||
|
services.meilisearch = {
|
||||||
|
dumplessUpgrade = true;
|
||||||
|
environment = "production";
|
||||||
|
masterKeyFile = cfg.meilisearchMasterKey.result.path;
|
||||||
|
};
|
||||||
})
|
})
|
||||||
(lib.mkIf (cfg.enable && cfg.sso.enable) {
|
(lib.mkIf (cfg.enable && cfg.sso.enable) {
|
||||||
shb.lldap.ensureGroups = {
|
shb.lldap.ensureGroups = {
|
||||||
|
|
@ -199,25 +239,6 @@ in
|
||||||
OAUTH_CLIENT_ID = cfg.sso.clientID;
|
OAUTH_CLIENT_ID = cfg.sso.clientID;
|
||||||
OAUTH_SCOPE = "openid email profile";
|
OAUTH_SCOPE = "openid email profile";
|
||||||
};
|
};
|
||||||
environmentFile = "/run/karakeep/secrets.env";
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d '/run/karakeep' 0750 root root - -"
|
|
||||||
];
|
|
||||||
systemd.services.karakeep-pre = {
|
|
||||||
script = lib.shb.replaceSecrets {
|
|
||||||
userConfig = {
|
|
||||||
NEXTAUTH_SECRET.source = cfg.sso.nextauthSecret.result.path;
|
|
||||||
OAUTH_CLIENT_SECRET.source = cfg.sso.sharedSecret.result.path;
|
|
||||||
};
|
|
||||||
resultPath = "/run/karakeep/secrets.env";
|
|
||||||
generator = lib.shb.toEnvVar;
|
|
||||||
};
|
|
||||||
serviceConfig.Type = "oneshot";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
before = [ "karakeep-web.service" "karakeep-workers.service" ];
|
|
||||||
requiredBy = [ "karakeep-web.service" "karakeep-workers.service" ];
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ It integrates well with [Ollama][].
|
||||||
- Declarative [SSO](#services-karakeep-options-shb.karakeep.sso) Configuration.
|
- Declarative [SSO](#services-karakeep-options-shb.karakeep.sso) Configuration.
|
||||||
- When SSO is enabled, login with user and password is disabled.
|
- When SSO is enabled, login with user and password is disabled.
|
||||||
- Registration is enabled through SSO.
|
- Registration is enabled through SSO.
|
||||||
|
- Meilisearch configured with production environment and master key.
|
||||||
- Access through [subdomain](#services-karakeep-options-shb.karakeep.subdomain) using reverse proxy.
|
- Access through [subdomain](#services-karakeep-options-shb.karakeep.subdomain) using reverse proxy.
|
||||||
- Access through [HTTPS](#services-karakeep-options-shb.karakeep.ssl) using reverse proxy.
|
- Access through [HTTPS](#services-karakeep-options-shb.karakeep.ssl) using reverse proxy.
|
||||||
- [Backup](#services-karakeep-options-shb.karakeep.sso) through the [backup block](./blocks-backup.html).
|
- [Backup](#services-karakeep-options-shb.karakeep.sso) through the [backup block](./blocks-backup.html).
|
||||||
|
|
@ -39,17 +40,18 @@ The following snippet assumes a few blocks have been setup already:
|
||||||
|
|
||||||
ssl = config.shb.certs.certs.letsencrypt.${domain};
|
ssl = config.shb.certs.certs.letsencrypt.${domain};
|
||||||
|
|
||||||
|
nextauthSecret.result = config.shb.sops.secret.nextauthSecret.result;
|
||||||
|
|
||||||
sso = {
|
sso = {
|
||||||
enable = true;
|
enable = true;
|
||||||
authEndpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}";
|
authEndpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}";
|
||||||
|
|
||||||
nextauthSecret.result = config.shb.sops.secret.nextauthSecret.result;
|
|
||||||
sharedSecret.result = config.shb.sops.secret.oidcSecret.result;
|
sharedSecret.result = config.shb.sops.secret.oidcSecret.result;
|
||||||
sharedSecretForAuthelia.result = config.shb.sops.secret.oidcAutheliaSecret.result;
|
sharedSecretForAuthelia.result = config.shb.sops.secret.oidcAutheliaSecret.result;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
shb.sops.secret.nextauthSecret.request = config.shb.karakeep.sso.sharedSecret.request;
|
shb.sops.secret.nextauthSecret.request = config.shb.karakeep.nextauthSecret.request;
|
||||||
shb.sops.secret.oidcSecret.request = config.shb.karakeep.sso.sharedSecret.request;
|
shb.sops.secret.oidcSecret.request = config.shb.karakeep.sso.sharedSecret.request;
|
||||||
shb.sops.secret.oidcAutheliaSecret = {
|
shb.sops.secret.oidcAutheliaSecret = {
|
||||||
request = config.shb.karakeep.sso.sharedSecretForAuthelia.request;
|
request = config.shb.karakeep.sso.sharedSecretForAuthelia.request;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ let
|
||||||
commonTestScript = testLib.mkScripts {
|
commonTestScript = testLib.mkScripts {
|
||||||
hasSSL = { node, ... }: !(isNull node.config.shb.karakeep.ssl);
|
hasSSL = { node, ... }: !(isNull node.config.shb.karakeep.ssl);
|
||||||
waitForServices = { ... }: [
|
waitForServices = { ... }: [
|
||||||
|
"karakeep-init.service"
|
||||||
|
"karakeep-browser.service"
|
||||||
"karakeep-web.service"
|
"karakeep-web.service"
|
||||||
"karakeep-workers.service"
|
"karakeep-workers.service"
|
||||||
"nginx.service"
|
"nginx.service"
|
||||||
|
|
@ -32,6 +34,18 @@ let
|
||||||
shb.karakeep = {
|
shb.karakeep = {
|
||||||
enable = true;
|
enable = true;
|
||||||
inherit (config.test) subdomain domain;
|
inherit (config.test) subdomain domain;
|
||||||
|
|
||||||
|
nextauthSecret.result = config.shb.hardcodedsecret.nextauthSecret.result;
|
||||||
|
meilisearchMasterKey.result = config.shb.hardcodedsecret.meilisearchMasterKey.result;
|
||||||
|
};
|
||||||
|
|
||||||
|
shb.hardcodedsecret.nextauthSecret = {
|
||||||
|
request = config.shb.karakeep.nextauthSecret.request;
|
||||||
|
settings.content = nextauthSecret;
|
||||||
|
};
|
||||||
|
shb.hardcodedsecret.meilisearchMasterKey = {
|
||||||
|
request = config.shb.karakeep.meilisearchMasterKey.request;
|
||||||
|
settings.content = "meilisearch-master-key";
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.hosts = {
|
networking.hosts = {
|
||||||
|
|
@ -107,16 +121,11 @@ let
|
||||||
authEndpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}";
|
authEndpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}";
|
||||||
clientID = "karakeep";
|
clientID = "karakeep";
|
||||||
|
|
||||||
nextauthSecret.result = config.shb.hardcodedsecret.nextauthSecret.result;
|
|
||||||
sharedSecret.result = config.shb.hardcodedsecret.oidcSecret.result;
|
sharedSecret.result = config.shb.hardcodedsecret.oidcSecret.result;
|
||||||
sharedSecretForAuthelia.result = config.shb.hardcodedsecret.oidcAutheliaSecret.result;
|
sharedSecretForAuthelia.result = config.shb.hardcodedsecret.oidcAutheliaSecret.result;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
shb.hardcodedsecret.nextauthSecret = {
|
|
||||||
request = config.shb.karakeep.sso.nextauthSecret.request;
|
|
||||||
settings.content = nextauthSecret;
|
|
||||||
};
|
|
||||||
shb.hardcodedsecret.oidcSecret = {
|
shb.hardcodedsecret.oidcSecret = {
|
||||||
request = config.shb.karakeep.sso.sharedSecret.request;
|
request = config.shb.karakeep.sso.sharedSecret.request;
|
||||||
settings.content = oidcSecret;
|
settings.content = oidcSecret;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue