Add shlink

Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
2025-06-29 12:56:19 +01:00
parent d617183438
commit ea2ab2101a
11 changed files with 17579 additions and 0 deletions

View File

@@ -139,6 +139,7 @@ in
"outline"
"vaultwarden"
"nextcloud"
"shlink"
];
};
}

View File

@@ -15,6 +15,7 @@ in
(import ./ntfy { inherit user home; })
(import ./outline { inherit user home; })
(import ./prometheus { inherit user home; })
(import ./shlink { inherit user home; })
(import ./sish { inherit user home; })
(import ./traefik { inherit user home; })
(import ./vaultwarden { inherit user home; })

View File

@@ -0,0 +1,157 @@
{
user ? throw "user argument is required",
home ? throw "home argument is required",
}:
{
config,
inputs,
pkgs,
system,
...
}:
let
selfPkgs = inputs.self.packages.${system};
hmConfig = config.home-manager.users.${user};
inherit (hmConfig.virtualisation.quadlet) containers volumes networks;
in
{
home-manager.users.${user} = {
sops = {
secrets = {
"shlink/postgresql".sopsFile = ../../../../../../secrets/secrets.yaml;
"shlink/apiKey".sopsFile = ../../../../../../secrets/secrets.yaml;
"maxmind/licenseKey".sopsFile = ../../../../../../../../secrets/personal/secrets.yaml;
};
templates = {
shlink-postgresql-env.content = ''
POSTGRES_PASSWORD=${hmConfig.sops.placeholder."shlink/postgresql"}
'';
shlink-env.content = ''
GEOLITE_LICENSE_KEY=${hmConfig.sops.placeholder."maxmind/licenseKey"}
DB_PASSWORD=${hmConfig.sops.placeholder."shlink/postgresql"}
INITIAL_API_KEY=${hmConfig.sops.placeholder."shlink/apiKey"}
'';
shlink-web-client-env.content = ''
SHLINK_SERVER_API_KEY=${hmConfig.sops.placeholder."shlink/apiKey"}
'';
};
};
virtualisation.quadlet = {
networks.shlink.networkConfig.internal = true;
volumes = {
shlink-postgresql = { };
shlink = { };
};
containers = {
shlink = {
containerConfig = {
image = "docker-archive:${selfPkgs.docker-shlink}";
networks = [
networks.shlink.ref
networks.traefik.ref
];
volumes = [ "${volumes.shlink.ref}:/var/lib/shlink/data" ];
environments = {
DEFAULT_DOMAIN = "url.karaolidis.com";
IS_HTTPS_ENABLED = "true";
MULTI_SEGMENT_SLUGS_ENABLED = "true";
SHORT_URL_TRAILING_SLASH = "true";
SHORT_URL_MODE = "loose";
DB_DRIVER = "postgres";
DB_NAME = "shlink";
DB_USER = "shlink";
DB_HOST = "shlink-postgresql";
DB_PORT = "5432";
DEFAULT_BASE_URL_REDIRECT = "https://url.karaolidis.com/web/server/shlink-url.karaolidis.com/overview";
DEFAULT_QR_CODE_SIZE = "300";
DEFAULT_QR_CODE_MARGIN = "25";
};
environmentFiles = [ hmConfig.sops.templates.shlink-env.path ];
labels = [
"traefik.enable=true"
"traefik.http.routers.shlink.rule=Host(`url.karaolidis.com`)"
"traefik.http.routers.shlink.middlewares=authelia@docker"
];
};
unitConfig.After = [
"${containers.shlink-postgresql._serviceName}.service"
"sops-nix.service"
];
};
shlink-web-client = {
containerConfig = {
image = "docker-archive:${selfPkgs.docker-shlink-web-client}";
networks = [
networks.shlink.ref
networks.traefik.ref
];
environments = {
SHLINK_SERVER_URL = "https://url.karaolidis.com";
};
environmentFiles = [ hmConfig.sops.templates.shlink-web-client-env.path ];
labels = [
"traefik.enable=true"
"traefik.http.routers.shlink-web.rule=Host(`url.karaolidis.com`) && PathPrefix(`/web`)"
"traefik.http.routers.shlink-web.middlewares=authelia@docker"
];
};
unitConfig.After = [ "sops-nix.service" ];
};
shlink-postgresql = {
containerConfig = {
image = "docker-archive:${selfPkgs.docker-postgresql}";
networks = [ networks.shlink.ref ];
volumes = [ "${volumes.shlink-postgresql.ref}:/var/lib/postgresql/data" ];
environments = {
POSTGRES_DB = "shlink";
POSTGRES_USER = "shlink";
};
environmentFiles = [ hmConfig.sops.templates.shlink-postgresql-env.path ];
};
unitConfig.After = [ "sops-nix.service" ];
};
authelia-init.containerConfig.volumes =
let
config = (pkgs.formats.yaml { }).generate "shlink.yaml" {
access_control.rules = [
{
domain = "url.karaolidis.com";
policy = "one_factor";
resources = [
"^/(rest|web)([/?].*)?$"
"^$"
];
subject = [ "group:shlink" ];
}
{
domain = "url.karaolidis.com";
policy = "deny";
resources = [
"^/(rest|web)([/?].*)?$"
"^$"
];
}
{
domain = "url.karaolidis.com";
policy = "bypass";
}
];
};
in
[ "${config}:/etc/authelia/conf.d/shlink.yaml:ro" ];
};
};
};
}