[Focalboard] Sets up Focalboard with storage, database and secrets. [OpenProject] Removes the container

This commit is contained in:
2025-04-21 16:42:56 -07:00
parent 089541916a
commit c88845ea2a
5 changed files with 168 additions and 63 deletions

View File

@@ -4,6 +4,8 @@ bookstack_db: ENC[AES256_GCM,data:m8fGgAfmJu1rEaxmTVH4FfBhyiU=,iv:OnBT/6sp9zmcJ1
mariadb_root_password: ENC[AES256_GCM,data:p965ZhFQqqX+Ub1yhgklVYlBH6A=,iv:qC5WwTvZGvlbAkYiv35xHizMYAnP0V0Vw79EkvL32wQ=,tag:gOJQvHeOC9turFKOMQ9DNg==,type:str]
openproject:
secret-key-base: ENC[AES256_GCM,data:luTuUtxL/SGx6O10y9cRiAzJHw==,iv:8qVJm+obsHr9eV0h+jdpsreeFGxEM+UFZHHiIUUPs6w=,tag:+zpjhKoIiNNSSYxe1QkQ7Q==,type:str]
focalboard:
database: ENC[AES256_GCM,data:GDxYdkVV+tl3qHxWMMoetmMnLnY=,iv:JujgNPyUEHCmD/yW3UKCTj9GTk9a7EkvUiyFLF4sF8A=,tag:46YZ7AthpiiaX69aN9a3Bg==,type:str]
sops:
kms: []
gcp_kms: []
@@ -28,8 +30,8 @@ sops:
by9aNFY4dXNxaWxnTXFTQS9reHhuQWMKh5rZ93nFtBV9EpFVRp+E+GXZ6xzVy2Jw
vFh4deGcAb60q4odSaeWfk1Dr7L9Ua69oK9omjbCNUt+P7Kwlfca7Q==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-04-03T19:04:17Z"
mac: ENC[AES256_GCM,data:DEUuXrCl3OXJ9NbfLoxHIND5+m7enHNDbuLE2jS8nvZCpKm83YoXwp0RhIFA725wJnBej26HLkovCi7V/4s5NrrfT9sPHGNBMSHB0AAcwu3Dmo6G2PBKvAWZTxXmiIXGx8vSvWNbLrp3vTV8jjTpfbuMvOiuxayKfn6esKI9T2o=,iv:zUfbL753Uvzg6WW4kwI8swmpWHIQ/IpCyYSsLptVDG4=,tag:XZy8jNZYYcqspd6zptH3pQ==,type:str]
lastmodified: "2025-04-21T19:34:54Z"
mac: ENC[AES256_GCM,data:D44YsnrRpYQmJxAjXdap+Ya6iqPrhdEmiaTgUOM53JYmkihIvmMxm3b09xMxucv3B7tvi5vCfcllgij+RZ2RPnQDFg8ZzYQu7AQSG8rgwoh3E9Zijx2gQm59hhvJlca2cB710hUL87Tkdbvz26LZevIf5gP83u2JCkXLzr9O/Ew=,iv:lMthECFXzbao4bVVK9eJgK5ubu1NUg97BI2T9OqlICw=,tag:8t+2kPoqKeSKF8e+x5dtmg==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.9.4

View File

@@ -4,12 +4,12 @@
# Additional configuration
imports = [
./containers/bookstack.nix
./containers/focalboard.nix
./containers/gitea.nix
./containers/grafana.nix
./containers/jobhunt.nix
./containers/mariadb.nix
./containers/nextcloud.nix
./containers/openproject.nix
./containers/prometheus.nix
./containers/pocket-id.nix
./containers/public-homepage.nix

View File

@@ -0,0 +1,74 @@
{ config, ... }:
let
inherit (import ./lib.nix config) mkContainer mkPostgresContainer terakoda;
userIds = import ./user-ids.nix;
in {
imports = [
(mkPostgresContainer {
name = "focalboard";
directory = "/tank/focalboard/db";
uid = userIds.focalboard.uid;
gid = userIds.focalboard.gid;
passwordSecret = "focalboard/database";
})
];
users.groups.focalboard = {
gid = userIds.focalboard.gid;
};
users.users.focalboard = {
uid = userIds.focalboard.uid;
isSystemUser = true;
description = "System User for Focalboard";
group = "focalboard";
};
sops.secrets = {
"focalboard/database" = {
restartUnits = [ "podman-focalboard.service" "podman-focalboard-postgres.service" ];
mode = "0400";
owner = config.users.users.focalboard.name;
};
};
sops.templates."focalboard-config.json" = {
restartUnits = [ "podman-focalboard.service" ];
owner = config.users.users.focalboard.name;
content = builtins.toJSON {
# Defaults from https://github.com/mattermost-community/focalboard/blob/main/config.json
"serverRoot" = "https://focalboard.terakoda.com";
"port" = 8000;
"dbtype" = "postgres";
"dbconfig" = "postgres://focalboard:${config.sops.placeholder."focalboard/database"}@focalboard-postgres/focalboard?sslmode=disable&connect_timeout=10";
"useSSL" = true;
"prometheus_address" = ":9092";
"session_expire_time" = 2592000;
"session_refresh_time" = 18000;
"postgres_dbconfig" = "dbname=focalboard sslmode=disable";
"webpath" = "./pack";
"filespath" = "./data/files";
"telemetry" = true;
"prometheusaddress" = ":9092";
"enableLocalMode" = true;
"localModeSocketLocation" = "/var/tmp/focalboard_local.socket";
};
};
virtualisation.oci-containers.containers = {
focalboard = mkContainer {
image = "mattermost/focalboard";
hostName = "focalboard";
domain = terakoda;
dependsOn = [ "focalboard-postgres" ];
port = 8000;
user = "${toString userIds.focalboard.uid}:${toString userIds.focalboard.gid}";
volumes = [
"/tank/focalboard/data/files:/opt/focalboard/data/files"
"${config.sops.templates."focalboard-config.json".path}:/opt/focalboard/config.json:ro"
];
};
};
}

View File

@@ -2,6 +2,8 @@ config:
let
havenisms = "havenisms.com";
blazestar = "blazestar.net";
terakoda = "terakoda.com";
terakoda_net = "terakoda.net";
hostRule = host: domain: "Host(`${host}.${domain}`)";
hostRuleHavenisms = host: hostRule host havenisms;
localNet = "192.168.0.0/16";
@@ -18,14 +20,14 @@ in
localHostRuleHavenisms
havenisms
blazestar
;
terakoda
terakoda_net;
mkContainer =
{
mkContainer = {
image,
hostName,
port,
homepageOpts,
homepageOpts ? {},
dependsOn ? [],
domain ? havenisms,
ports ? [],
@@ -33,31 +35,27 @@ in
environment ? {},
environmentFiles ? [],
public ? false,
user ? null,
}:
let
routerRule = if public then hostRule hostName domain else localHostRule hostName domain;
homepageLabels = if homepageOpts == {} then {} else {
"homepage.group" = "${homepageOpts.group}";
"homepage.name" = "${homepageOpts.name}";
"homepage.icon" = "${homepageOpts.icon}";
"homepage.href" = "https://${hostName}.${domain}";
"homepage.description" = "${homepageOpts.description}";
};
in
{
inherit
image
dependsOn
volumes
environment
environmentFiles
ports
;
inherit image dependsOn volumes environment environmentFiles ports user;
hostname = "${hostName}.${domain}";
autoStart = true;
extraOptions = [
"-l=traefik.enable=true"
"-l=traefik.http.routers.${hostName}.rule=${routerRule}"
"-l=traefik.http.services.${hostName}.loadbalancer.server.port=${toString port}"
"-l=homepage.group=${homepageOpts.group}"
"-l=homepage.name=${homepageOpts.name}"
"-l=homepage.icon=${homepageOpts.icon}"
"-l=homepage.href=https://${hostName}.${domain}"
"-l=homepage.description=${homepageOpts.description}"
];
labels = {
"traefik.enable" = "true";
"traefik.http.routers.${hostName}.rule" = "${routerRule}";
"traefik.http.services.${hostName}.loadbalancer.server.port" = "${toString port}";
} // homepageLabels;
};
# Creates a MariaDB container for a specific app. It should be safe to give
@@ -66,8 +64,7 @@ in
# user.
#
# Note that this returns a _module_ so that it can be imported and provide many different config values.
mkMariaDbContainer =
{
mkMariaDbContainer = {
name,
uid,
gid,
@@ -95,4 +92,32 @@ in
};
};
};
mkPostgresContainer = {
name,
uid,
gid,
passwordSecret,
directory,
containerName ? "${name}-postgres",
databaseName ? name,
username ? name,
}: { config, ... }: {
virtualisation.oci-containers.containers."${containerName}" = {
image = "postgres";
autoStart = true;
volumes = [
# Note that data must be mounted at this location to persist.
# See https://github.com/docker-library/docs/blob/master/postgres/README.md#pgdata
"${directory}:/var/lib/postgresql/data"
"${config.sops.secrets."${passwordSecret}".path}:/run/secrets/postgres_password"
];
user = "${toString uid}:${toString gid}";
environment = {
POSTGRES_USER = username;
POSTGRES_DB = databaseName;
POSTGRES_PASSWORD_FILE = "/run/secrets/postgres_password";
};
};
};
}

View File

@@ -13,4 +13,8 @@
uid = 2005;
gid = 2005;
};
focalboard = {
uid = 2006;
gid = 2006;
};
}