From 83ed3a480962ce8c2463381b756db09d2dc4da71 Mon Sep 17 00:00:00 2001 From: Drew Haven Date: Tue, 25 Mar 2025 14:37:12 -0700 Subject: [PATCH] [bookstack] Adds bookstack and cleans up a bunch of other files. Rewrites how mariadb instances are provisioned. --- secrets/mcp.yaml | 7 ++- system/hosts/mcp/containers.nix | 2 + system/hosts/mcp/containers/baserow.nix | 4 +- system/hosts/mcp/containers/bookstack.nix | 67 +++++++++++++++++++++++ system/hosts/mcp/containers/lib.nix | 41 ++++++++++++-- system/hosts/mcp/containers/mariadb.nix | 35 +++++------- system/hosts/mcp/containers/user-ids.nix | 8 +++ 7 files changed, 133 insertions(+), 31 deletions(-) create mode 100644 system/hosts/mcp/containers/bookstack.nix diff --git a/secrets/mcp.yaml b/secrets/mcp.yaml index bcc268a..70c966f 100644 --- a/secrets/mcp.yaml +++ b/secrets/mcp.yaml @@ -1,4 +1,7 @@ gitea_db_password: ENC[AES256_GCM,data:G2YqiDk0msBRjUJkoPxWmayQ9dI=,iv:FsojIJIi61K7rD2VULDgIx6uSYX3iDiA6W744HlgHl0=,tag:BlmsM7LZHnBCKtfuqlhoKA==,type:str] +bookstack_app_key: ENC[AES256_GCM,data:N79JVlQSoVCXOsIHCxd19HFm6LkrYyXQu/xWenEdUlQWqwZEi3PuHXG7fQgvzQY4KI7S,iv:cd2l2eOv+wAJ5sih3YhHgQTdy1qrvaIsoHcywOnHuYM=,tag:5QvCHlQX8wUz3tI2NXl+8A==,type:str] +bookstack_db: ENC[AES256_GCM,data:m8fGgAfmJu1rEaxmTVH4FfBhyiU=,iv:OnBT/6sp9zmcJ1+kBmdmvaE630hifxBpvKnu3XrVXcE=,tag:SSVQcYkAymlbFOnf0MB6KA==,type:str] +mariadb_root_password: ENC[AES256_GCM,data:p965ZhFQqqX+Ub1yhgklVYlBH6A=,iv:qC5WwTvZGvlbAkYiv35xHizMYAnP0V0Vw79EkvL32wQ=,tag:gOJQvHeOC9turFKOMQ9DNg==,type:str] sops: kms: [] gcp_kms: [] @@ -23,8 +26,8 @@ sops: by9aNFY4dXNxaWxnTXFTQS9reHhuQWMKh5rZ93nFtBV9EpFVRp+E+GXZ6xzVy2Jw vFh4deGcAb60q4odSaeWfk1Dr7L9Ua69oK9omjbCNUt+P7Kwlfca7Q== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-03-18T22:35:18Z" - mac: ENC[AES256_GCM,data:ZmCWMW7NIjBzAxPgoUZp2BpP0q5cnelSVsQ0ccJYHRja1WXfO1d6CuNixcHyVSl02+Cn9eGt/z8dObZafOgGxYq1HwYr7VfIpv2CUb/rg/8/Lu3eB6N1+QQGZUWbm6q9s4v7NomHYd7M4GOd2ZhgSDc23zKCzMkkA7t9hyJbhKw=,iv:XWhYxBsbkTeBlZFum2CkpGpqModabgqrSCouwOh2/Gc=,tag:dBLzSTLTzSQeg820J+fk5A==,type:str] + lastmodified: "2025-03-25T21:23:10Z" + mac: ENC[AES256_GCM,data:BTmAMxauVjQaMoQhDCCAloniVfEaxB5vUhI6Cvu1YFMesLv3yhnZ9lgRB4SXsyd7Kf3xefY7Wg+PtMnl2aX6BR4Tdss5H+UTHzsa3M888TI3EAEykXbPFUfOapAiboP71aibiDj8L0lbcKimGJpg3llzeNtK370fjAp7hsnh7aE=,iv:YTMrTtqDkq9L2y42X2nmEKruSKp7v70GStMw/JjPrL8=,tag:x1LclBpygFZQBWPYkE9chw==,type:str] pgp: [] unencrypted_suffix: _unencrypted version: 3.9.4 diff --git a/system/hosts/mcp/containers.nix b/system/hosts/mcp/containers.nix index f40a6db..4b922e1 100644 --- a/system/hosts/mcp/containers.nix +++ b/system/hosts/mcp/containers.nix @@ -3,9 +3,11 @@ { # Additional configuration imports = [ + ./containers/bookstack.nix ./containers/gitea.nix ./containers/grafana.nix ./containers/jobhunt.nix + ./containers/mariadb.nix ./containers/nextcloud.nix ./containers/prometheus.nix ./containers/pocket-id.nix diff --git a/system/hosts/mcp/containers/baserow.nix b/system/hosts/mcp/containers/baserow.nix index 753c676..fbabf9b 100644 --- a/system/hosts/mcp/containers/baserow.nix +++ b/system/hosts/mcp/containers/baserow.nix @@ -1,5 +1,5 @@ # Not in use, just reference. -{ config, pkgs, ... }: +{ config, ... }: let inherit (import ./lib.nix config) mkContainer; in { virtualisation.oci-containers.containers.baserow = mkContainer { @@ -19,4 +19,4 @@ let inherit (import ./lib.nix config) mkContainer; in description = "No-Code Databases"; }; }; -} \ No newline at end of file +} diff --git a/system/hosts/mcp/containers/bookstack.nix b/system/hosts/mcp/containers/bookstack.nix new file mode 100644 index 0000000..172d345 --- /dev/null +++ b/system/hosts/mcp/containers/bookstack.nix @@ -0,0 +1,67 @@ +{ config, ... }: +let + inherit (import ./lib.nix config) mkContainer mkMariaDbContainer havenisms; + userIds = import ./user-ids.nix; +in { + imports = [ + (mkMariaDbContainer { + name = "bookstack"; + uid = userIds.bookstack.uid; + gid = userIds.bookstack.gid; + directory = "/tank/bookstack/db"; + passwordSecret = "bookstack_db"; + }) + ]; + + users.groups.bookstack = { + gid = userIds.bookstack.gid; + }; + + users.users.bookstack = { + uid = userIds.bookstack.uid; + isSystemUser = true; + description = "System User for Bookstack"; + group = "bookstack"; + }; + + sops.secrets = { + bookstack_app_key = { + restartUnits = [ "podman-bookstack.service" ]; + mode = "0400"; + owner = config.users.users.bookstack.name; + }; + bookstack_db = { + restartUnits = [ "podman-bookstack-mariadb.service" ]; + mode = "0400"; + owner = config.users.users.bookstack.name; + }; + }; + + virtualisation.oci-containers.containers.bookstack = mkContainer { + image = "lscr.io/linuxserver/bookstack:latest"; + hostName = "bookstack"; + port = "80"; + dependsOn = [ "bookstack-mariadb" ]; + homepageOpts = { + group = "Apps"; + name = "Bookstack"; + icon = "bookstack.svg"; + description = "Wiki and Knowledgebase"; + }; + volumes = [ + "/tank/bookstack/app:/config" + "${config.sops.secrets.bookstack_app_key.path}:/run/secrets/bookstack_app_key" + "${config.sops.secrets.bookstack_db.path}:/run/secrets/bookstack_db" + ]; + environment = { + APP_URL = "https://bookstack.${havenisms}"; + PID = toString userIds.bookstack.uid; + GID = toString userIds.bookstack.gid; + DB_HOST = "bookstack-mariadb"; + DB_USERNAME = "bookstack"; + DB_DATABASE = "bookstack"; + FILE__DB_PASSWORD = "/run/secrets/bookstack_db"; + FILE__APP_KEY = "/run/secrets/bookstack_app_key"; + }; + }; +} diff --git a/system/hosts/mcp/containers/lib.nix b/system/hosts/mcp/containers/lib.nix index 49fb510..ee88934 100644 --- a/system/hosts/mcp/containers/lib.nix +++ b/system/hosts/mcp/containers/lib.nix @@ -28,15 +28,15 @@ in dependsOn ? [], domain ? havenisms, volumes ? [], - environment ? [], + environment ? {}, + environmentFiles ? [], public ? false }: let routerRule = if public then hostRule hostName domain else localHostRule hostName domain; in { - image = image; + inherit image dependsOn volumes environment environmentFiles; autoStart = true; - dependsOn = dependsOn; extraOptions = [ "-l=traefik.enable=true" "-l=traefik.http.routers.${hostName}.rule=${routerRule}" @@ -47,7 +47,38 @@ in "-l=homepage.href=https://${hostName}.${domain}" "-l=homepage.description=${homepageOpts.description}" ]; - volumes = volumes; - environment = environment; }; + + # Creates a MariaDB container for a specific app. It should be safe to give + # it the same UID and GID as the app it is made for. The contaner will be + # named `${name}-mariadb`. The database name is the same as the database + # user. + # + # Note that this returns a _module_ so that it can be imported and provide many different config values. + mkMariaDbContainer = { + name, + uid, + gid, + passwordSecret, + directory, + }: { config, ... }: { + virtualisation.oci-containers.containers."${name}-mariadb" = { + image = "lscr.io/linuxserver/mariadb:latest"; + autoStart = true; + ports = [ "3306:3306" ]; + volumes = [ + "${directory}:/config" + "${config.sops.secrets.mariadb_root_password.path}:/run/secrets/mariadb_root_password" + "${config.sops.secrets."${passwordSecret}".path}:/run/secrets/mariadb_password" + ]; + environment = { + PUID = "${toString uid}"; + PGID = "${toString gid}"; + MYSQL_USER = name; + MYSQL_DATABASE = name; + FILE__MYSQL_ROOT_PASSWORD = "/run/secrets/mariadb_root_password"; + FILE__MYSQL_PASSWORD = "/run/secrets/mariadb_password"; + }; + }; + }; } diff --git a/system/hosts/mcp/containers/mariadb.nix b/system/hosts/mcp/containers/mariadb.nix index ed63115..89f4e1e 100644 --- a/system/hosts/mcp/containers/mariadb.nix +++ b/system/hosts/mcp/containers/mariadb.nix @@ -1,26 +1,17 @@ +# Common config for all mariadb containers { ... }: -{ - virtualisation.oci-containers.containers.mariadb = { - image = "mariadb:11"; - autoStart = true; - extraOptions = [ - ]; - volumes = [ - "/tank/mariadb:/var/lib/mysql" - ]; - cmd = [ - "--innodb-buffer-pool-size=512M" - "--transaction-isolation=READ-COMMITTED" - "--character-set-server=utf8mb4" - "--collation-server=utf8mb4_unicode_ci" - "--max-connections=512" - "--innodb-rollback-on-timeout=OFF" - "--innodb-lock-wait-timeout=120" - ]; - environment = { - MARIADB_DATABASE = "mariadb"; - # TODO: Secrets - MARIADB_ROOT_PASSWORD = "root123"; +let + userIds = import ./user-ids.nix; +in { + users = { + groups."mariadb" = { + gid = userIds.mariadb.gid; }; }; + + sops.secrets."mariadb_root_password" = { + restartUnits = [ "podman-mariadb.service" ]; + mode = "0440"; + group = "mariadb"; + }; } diff --git a/system/hosts/mcp/containers/user-ids.nix b/system/hosts/mcp/containers/user-ids.nix index a93dc3f..3c50f15 100644 --- a/system/hosts/mcp/containers/user-ids.nix +++ b/system/hosts/mcp/containers/user-ids.nix @@ -5,4 +5,12 @@ uid = 2003; gid = 2003; }; + bookstack = { + uid = 2004; + gid = 2004; + }; + mariadb = { + uid = 2005; + gid = 2005; + }; }