add(acme,nginx): add certificate generation and nginx for the services
This replaces caddy and the port exposure, this is more efficent and easier to manage in the future.
This commit is contained in:
parent
7dd87536aa
commit
5792e478af
9 changed files with 244 additions and 74 deletions
|
@ -21,3 +21,7 @@ creation_rules:
|
|||
key_groups:
|
||||
- age:
|
||||
- *primary
|
||||
- path_regex: secrets/blarm-acme.env
|
||||
key_groups:
|
||||
- age:
|
||||
- *primary
|
||||
|
|
38
modules/nixos/services/acme/default.nix
Normal file
38
modules/nixos/services/acme/default.nix
Normal file
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
with lib.${namespace};
|
||||
let
|
||||
cfg = config.${namespace}.services.acme;
|
||||
in
|
||||
{
|
||||
options.${namespace}.services.acme = {
|
||||
enable = mkBoolOpt false "ACME";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults.email = "admin+acme@stahl.sh";
|
||||
certs."stahl.sh" = {
|
||||
domain = "stahl.sh";
|
||||
extraDomainNames = [ "*.stahl.sh" ];
|
||||
dnsProvider = "infomaniak";
|
||||
dnsPropagationCheck = true;
|
||||
environmentFile = "/run/secrets/acme";
|
||||
};
|
||||
};
|
||||
|
||||
users.users.nginx.extraGroups = [ "acme" ];
|
||||
|
||||
sops.secrets.acme = {
|
||||
format = "dotenv";
|
||||
sopsFile = ../../../../secrets/blarm-acme.env;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
|
@ -13,6 +13,13 @@ in
|
|||
{
|
||||
options.${namespace}.services.cinny = {
|
||||
enable = mkEnableOption "Cinny";
|
||||
nginx = {
|
||||
enable = mkEnableOption {
|
||||
description = "Enable nginx for this service.";
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
description = "The package of Cinny to use.";
|
||||
|
@ -20,45 +27,44 @@ in
|
|||
default = pkgs.cinny-unwrapped;
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
description = "The port to serve Cinny on.";
|
||||
type = types.nullOr types.int;
|
||||
default = 8686;
|
||||
domain = mkOption {
|
||||
description = "The domain to serve Cinny on.";
|
||||
type = types.nullOr types.str;
|
||||
default = "cinny.stahl.sh";
|
||||
};
|
||||
|
||||
};
|
||||
config = mkIf cfg.enable {
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
cfg.port
|
||||
80
|
||||
443
|
||||
];
|
||||
|
||||
services.caddy = {
|
||||
awesome-flake.services.acme.enable = mkIf cfg.nginx.enable true;
|
||||
|
||||
services.nginx = mkIf cfg.nginx.enable {
|
||||
enable = true;
|
||||
virtualHosts.":${builtins.toString cfg.port}" = {
|
||||
extraConfig = ''
|
||||
root * ${cfg.package}
|
||||
file_server
|
||||
|
||||
@index {
|
||||
not path /index.html
|
||||
not path /public/*
|
||||
not path /assets/*
|
||||
virtualHosts."${cfg.domain}" = {
|
||||
forceSSL = true;
|
||||
useACMEHost = "stahl.sh";
|
||||
locations."/" = {
|
||||
root = "${cfg.package}";
|
||||
extraConfig = ''
|
||||
rewrite ^/config.json$ /config.json break;
|
||||
rewrite ^/manifest.json$ /manifest.json break;
|
||||
|
||||
not path /config.json
|
||||
rewrite ^/sw.js$ /sw.js break;
|
||||
rewrite ^/pdf.worker.min.js$ /pdf.worker.min.js break;
|
||||
|
||||
not path /manifest.json
|
||||
not path /sw.js
|
||||
rewrite ^/public/(.*)$ /public/$1 break;
|
||||
rewrite ^/assets/(.*)$ /assets/$1 break;
|
||||
|
||||
not path /pdf.worker.min.js
|
||||
not path /olm.wasm
|
||||
|
||||
path /*
|
||||
}
|
||||
|
||||
rewrite /*/olm.wasm /olm.wasm
|
||||
rewrite @index /index.html
|
||||
'';
|
||||
rewrite ^(.+)$ /index.html break;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -20,28 +20,41 @@ in
|
|||
default = pkgs.awesome-flake.ente-web-auth;
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
description = "The port to serve Ente-Auth on.";
|
||||
type = types.nullOr types.int;
|
||||
default = 1338;
|
||||
domain = mkOption {
|
||||
description = "The domain to serve ente-auth on.";
|
||||
type = types.nullOr types.str;
|
||||
default = "ente.stahl.sh";
|
||||
};
|
||||
|
||||
nginx = {
|
||||
enable = mkEnableOption {
|
||||
description = "Enable nginx for this service.";
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
cfg.port
|
||||
networking.firewall.allowedTCPPorts = mkIf cfg.nginx.enable [
|
||||
80
|
||||
443
|
||||
];
|
||||
|
||||
services.caddy = {
|
||||
awesome-flake.services.acme.enable = mkIf cfg.nginx.enable true;
|
||||
|
||||
services.nginx = mkIf cfg.nginx.enable {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
":${builtins.toString cfg.port}" = {
|
||||
extraConfig = ''
|
||||
root * ${cfg.package}
|
||||
file_server
|
||||
'';
|
||||
|
||||
virtualHosts."${cfg.domain}" = {
|
||||
forceSSL = true;
|
||||
useACMEHost = "stahl.sh";
|
||||
locations."/" = {
|
||||
root = "${cfg.package}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,13 @@ in
|
|||
{
|
||||
options.${namespace}.services.forgejo = {
|
||||
enable = mkEnableOption "Forgejo";
|
||||
nginx = {
|
||||
enable = mkEnableOption {
|
||||
description = "Enable nginx for this service.";
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
description = "The package of Forgejo to use.";
|
||||
|
@ -29,13 +36,13 @@ in
|
|||
domain = mkOption {
|
||||
description = "The domain to serve Forgejo on.";
|
||||
type = types.nullOr types.str;
|
||||
default = "git.monapona.dev";
|
||||
default = "git.stahl.sh";
|
||||
};
|
||||
|
||||
ssh_domain = mkOption {
|
||||
description = "The domain to serve Forgejo on.";
|
||||
type = types.nullOr types.str;
|
||||
default = "monapona.dev";
|
||||
default = "stahl.sh";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
|
@ -47,7 +54,8 @@ in
|
|||
};
|
||||
config = mkIf cfg.enable {
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
cfg.port
|
||||
80
|
||||
443
|
||||
];
|
||||
|
||||
systemd.services.codeberg-themes = {
|
||||
|
@ -78,7 +86,7 @@ in
|
|||
server = {
|
||||
DOMAIN = cfg.domain;
|
||||
HTTP_PORT = cfg.port;
|
||||
ROOT_URL = "https://git.monapona.dev";
|
||||
ROOT_URL = "https://" + cfg.domain;
|
||||
SSH_DOMAIN = cfg.ssh_domain;
|
||||
};
|
||||
ui = {
|
||||
|
@ -87,5 +95,17 @@ in
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
awesome-flake.services.acme.enable = mkIf cfg.nginx.enable true;
|
||||
|
||||
services.nginx = mkIf cfg.nginx.enable {
|
||||
enable = true;
|
||||
|
||||
virtualHosts."${cfg.domain}" = {
|
||||
forceSSL = true;
|
||||
useACMEHost = "stahl.sh";
|
||||
locations."/".proxyPass = "http://127.0.0.1:${builtins.toString cfg.port}";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -21,6 +21,19 @@ in
|
|||
options.${namespace}.services.linkwarden = {
|
||||
enable = mkEnableOption "Linkwarden";
|
||||
package = lib.mkPackageOption pkgs.awesome-flake "linkwarden" { };
|
||||
nginx = {
|
||||
enable = mkEnableOption {
|
||||
description = "Enable nginx for this service.";
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
|
||||
domain = mkOption {
|
||||
description = "The domain to serve linkwarden on.";
|
||||
type = types.nullOr types.str;
|
||||
default = "link.stahl.sh";
|
||||
};
|
||||
|
||||
storageLocation = mkOption {
|
||||
type = types.path;
|
||||
|
@ -69,24 +82,22 @@ in
|
|||
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = "0.0.0.0";
|
||||
default = "127.0.0.1";
|
||||
description = "The host that Linkwarden will listen on.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 3000;
|
||||
description = "The port that Linkwarden will listen on.";
|
||||
};
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to open the Linkwarden port in the firewall";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "linkwarden";
|
||||
description = "The user Linkwarden should run as.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "linkwarden";
|
||||
|
@ -99,25 +110,30 @@ in
|
|||
// {
|
||||
default = true;
|
||||
};
|
||||
|
||||
createDB = mkEnableOption "the automatic creation of the database for Linkwarden." // {
|
||||
default = true;
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
default = "linkwarden";
|
||||
description = "The name of the Linkwarden database.";
|
||||
};
|
||||
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = "/run/postgresql";
|
||||
example = "127.0.0.1";
|
||||
description = "Hostname or address of the postgresql server. If an absolute path is given here, it will be interpreted as a unix socket path.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 5432;
|
||||
description = "Port of the postgresql server.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "linkwarden";
|
||||
|
@ -146,19 +162,25 @@ in
|
|||
];
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
80
|
||||
443
|
||||
];
|
||||
|
||||
${namespace}.services.linkwarden.environment = {
|
||||
LINKWARDEN_HOST = cfg.host;
|
||||
LINKWARDEN_PORT = toString cfg.port;
|
||||
LINKWARDEN_CACHE_DIR = cfg.cacheLocation;
|
||||
STORAGE_FOLDER = cfg.storageLocation;
|
||||
NEXT_PUBLIC_DISABLE_REGISTRATION = mkIf (!cfg.enableRegistration) "true";
|
||||
DATABASE_URL = mkIf isPostgresUnixSocket "postgresql://${lib.strings.escapeURL cfg.database.user}@localhost/${lib.strings.escapeURL cfg.database.name}?host=${cfg.database.host}";
|
||||
DATABASE_PORT = toString cfg.database.port;
|
||||
DATABASE_HOST = mkIf (!isPostgresUnixSocket) cfg.database.host;
|
||||
DATABASE_NAME = cfg.database.name;
|
||||
DATABASE_USER = cfg.database.user;
|
||||
${namespace}.services = {
|
||||
acme.enable = mkIf cfg.nginx.enable true;
|
||||
linkwarden.environment = {
|
||||
LINKWARDEN_HOST = cfg.host;
|
||||
LINKWARDEN_PORT = toString cfg.port;
|
||||
LINKWARDEN_CACHE_DIR = cfg.cacheLocation;
|
||||
STORAGE_FOLDER = cfg.storageLocation;
|
||||
NEXT_PUBLIC_DISABLE_REGISTRATION = mkIf (!cfg.enableRegistration) "true";
|
||||
DATABASE_URL = mkIf isPostgresUnixSocket "postgresql://${lib.strings.escapeURL cfg.database.user}@localhost/${lib.strings.escapeURL cfg.database.name}?host=${cfg.database.host}";
|
||||
DATABASE_PORT = toString cfg.database.port;
|
||||
DATABASE_HOST = mkIf (!isPostgresUnixSocket) cfg.database.host;
|
||||
DATABASE_NAME = cfg.database.name;
|
||||
DATABASE_USER = cfg.database.user;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.linkwarden = {
|
||||
|
@ -221,6 +243,16 @@ in
|
|||
};
|
||||
users.groups = mkIf (cfg.group == "linkwarden") { linkwarden = { }; };
|
||||
|
||||
services.nginx = mkIf cfg.nginx.enable {
|
||||
enable = true;
|
||||
|
||||
virtualHosts."${cfg.domain}" = {
|
||||
forceSSL = true;
|
||||
useACMEHost = "stahl.sh";
|
||||
locations."/".proxyPass = "http://:${cfg.host}" + builtins.toString cfg.port;
|
||||
};
|
||||
};
|
||||
|
||||
sops.secrets.linkwarden = {
|
||||
format = "dotenv";
|
||||
sopsFile = ../../../../secrets/blarm-linkwarden.env;
|
||||
|
|
|
@ -12,37 +12,86 @@ in
|
|||
{
|
||||
options.${namespace}.services.searxng = with types; {
|
||||
enable = mkBoolOpt false "SearXNG";
|
||||
redlib = mkBoolOpt true "Whether or not to enable redlib.";
|
||||
|
||||
domain = mkOption {
|
||||
description = "The domain to serve searxng on.";
|
||||
type = types.nullOr types.str;
|
||||
default = "search.stahl.sh";
|
||||
};
|
||||
|
||||
nginx = {
|
||||
enable = mkEnableOption {
|
||||
description = "Enable nginx for this service.";
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
|
||||
redlib = {
|
||||
enable = mkEnableOption {
|
||||
description = "Whether or not to enable redlib.";
|
||||
type = type.bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
domain = mkOption {
|
||||
description = "The domain to serve reddit on.";
|
||||
type = types.nullOr types.str;
|
||||
default = "reddit.stahl.sh";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
networking.firewall.allowedTCPPorts = [ 1340 ];
|
||||
networking.firewall.allowedTCPPorts = mkIf cfg.nginx.enable [
|
||||
80
|
||||
443
|
||||
];
|
||||
|
||||
services.searx = {
|
||||
enable = true;
|
||||
environmentFile = "/run/secrets/searxng";
|
||||
settings.server = {
|
||||
port = "1340";
|
||||
bind_address = "0.0.0.0";
|
||||
bind_address = "127.0.0.1";
|
||||
use_default_settings = true;
|
||||
secret_key = "@secret_key@";
|
||||
};
|
||||
};
|
||||
|
||||
services.redlib = mkIf cfg.redlib {
|
||||
services.redlib = mkIf cfg.redlib.enable {
|
||||
enable = true;
|
||||
address = "0.0.0.0";
|
||||
address = "127.0.0.1";
|
||||
port = 1341;
|
||||
openFirewall = true;
|
||||
};
|
||||
|
||||
services.searx.settings.searx = mkIf cfg.redlib {
|
||||
services.searx.settings.searx = mkIf cfg.redlib.enable {
|
||||
plugins.hostnames.SXNGPlugin.active = true;
|
||||
};
|
||||
|
||||
services.searx.settings.hostnames.replace = mkIf cfg.redlib {
|
||||
"(.*\.)?reddit\.com$" = "reddit.monapona.dev";
|
||||
"(.*\.)?redd\.it$" = "reddit.monapona.dev";
|
||||
services.searx.settings.hostnames.replace = mkIf cfg.redlib.enable {
|
||||
"(.*\.)?reddit\.com$" = cfg.redlib.domain;
|
||||
"(.*\.)?redd\.it$" = cfg.redlib.domain;
|
||||
};
|
||||
|
||||
awesome-flake.services.acme.enable = mkIf cfg.nginx.enable true;
|
||||
|
||||
services.nginx = mkIf cfg.nginx.enable {
|
||||
enable = true;
|
||||
|
||||
virtualHosts = {
|
||||
"${cfg.domain}" = {
|
||||
forceSSL = true;
|
||||
useACMEHost = "stahl.sh";
|
||||
locations."/".proxyPass = "http://127.0.01:1340";
|
||||
};
|
||||
"${cfg.redlib.domain}" = mkIf cfg.redlib.enable {
|
||||
forceSSL = true;
|
||||
useACMEHost = "stahl.sh";
|
||||
locations."/".proxyPass = "http://127.0.01:1341";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
sops.secrets.searxng = {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
monolith,
|
||||
nodejs,
|
||||
openssl,
|
||||
playwright-driver,
|
||||
#playwright-driver,
|
||||
prisma,
|
||||
prisma-engines,
|
||||
}:
|
||||
|
@ -41,7 +41,7 @@ let
|
|||
in
|
||||
stdenvNoCC.mkDerivation rec {
|
||||
pname = "linkwarden";
|
||||
version = "2.10.0";
|
||||
version = "2.10.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "linkwarden";
|
||||
|
@ -120,7 +120,6 @@ stdenvNoCC.mkDerivation rec {
|
|||
--set-default PRISMA_QUERY_ENGINE_LIBRARY "${prisma-engines}/lib/libquery_engine.node" \
|
||||
--set-default PRISMA_QUERY_ENGINE_BINARY "${prisma-engines}/bin/query-engine" \
|
||||
--set-default PRISMA_SCHEMA_ENGINE_BINARY "${prisma-engines}/bin/schema-engine" \
|
||||
--set-default PLAYWRIGHT_LAUNCH_OPTIONS_EXECUTABLE_PATH ${playwright-driver.browsers-chromium}/chromium-*/chrome-linux/chrome \
|
||||
--set-default LINKWARDEN_CACHE_DIR /var/cache/linkwarden \
|
||||
--set-default LINKWARDEN_HOST localhost \
|
||||
--set-default LINKWARDEN_PORT 3000 \
|
||||
|
@ -129,6 +128,8 @@ stdenvNoCC.mkDerivation rec {
|
|||
runHook postInstall
|
||||
'';
|
||||
|
||||
#--set-default PLAYWRIGHT_LAUNCH_OPTIONS_EXECUTABLE_PATH ${playwright-driver.browsers-chromium}/chromium-*/chrome-linux/chrome \
|
||||
|
||||
passthru.tests = {
|
||||
inherit (nixosTests) linkwarden;
|
||||
};
|
||||
|
|
7
secrets/blarm-acme.env
Normal file
7
secrets/blarm-acme.env
Normal file
|
@ -0,0 +1,7 @@
|
|||
INFOMANIAK_ACCESS_TOKEN=ENC[AES256_GCM,data:xwYJQZkiPktUcPaWEG2oNiBMCzL8jQm1HnjdO756LjFkqJzLKvmaJA6DvR7GbI3YFCYBXTDhwiy++2U5juvWTeVnQWlEE48IhSeKKVtnDfg=,iv:h/JPjTfypSwXV2mhZ5k9fkXWjvvH5+SsjlikSh8S3uU=,tag:QTSuvsp8Yteq4LroRZVE5g==,type:str]
|
||||
sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSMUhBNFJVSklOWDYycjZx\nR3ZJSVpVZ3VoR3RJZmNwZVlZOWQ4SHRVTXdZCml6TXVpZU4zYVNlY295ejZJYU5m\ndG1JaTQxVnBncnVXSHRPYThvM1FMckkKLS0tIEQxaEI2R0JYTmNrbko0SXFEOGdK\nMkFQRVJ5WlB3a2FwMnBsdlNiTWE1a1EKMagGidGhLXp3XJAoY9TBcOjx+h7T06yQ\nC7wGzRtrYcVkUx6aEmcIg78MvgcD67QtjOMLDani9gC2DWTxlLmH1A==\n-----END AGE ENCRYPTED FILE-----\n
|
||||
sops_age__list_0__map_recipient=age132m0pg4utk3cjve2lgcjffvz7cevl0fq5krufu9sgud7wu2wgurqk49kgl
|
||||
sops_lastmodified=2025-05-24T12:52:22Z
|
||||
sops_mac=ENC[AES256_GCM,data:452ZNGwzol6doKb1uG1KExqojiEv0yixGkxxB6x1Rn9S6RKEiaPu79MskN2MaSdyxNdvd8R5YiDE2AG1eE6FEO4nHWOhB014EG5HIqSHxkLvGyq521SxkyAsVxS+qwWUWBPzPDUMU3sgCLxOsMOzrPV+RDYyr01IRAvexXAdvZg=,iv:AQy1vG1jKZJ2kXd0sdZW6TWDsYZcyFwVO1rOosZi3KU=,tag:XScja+Z0yxny62vbpRtSjA==,type:str]
|
||||
sops_unencrypted_suffix=_unencrypted
|
||||
sops_version=3.10.2
|
Loading…
Add table
Add a link
Reference in a new issue