working merges with master #2

Merged
awkawb merged 10 commits from working into master 2024-10-14 16:30:46 -04:00
3 changed files with 132 additions and 44 deletions
Showing only changes of commit 1abeb7dc5a - Show all commits

View File

@ -7,9 +7,6 @@
, runtimeDir ? "/run/invoice-ninja" , runtimeDir ? "/run/invoice-ninja"
}: }:
let
configFilesystemsPatch = "./config-filesystems.patch";
in
php.buildComposerProject (finalAttrs: { php.buildComposerProject (finalAttrs: {
pname = "invoice-ninja"; pname = "invoice-ninja";
version = "5.10.29"; version = "5.10.29";
@ -24,7 +21,7 @@ php.buildComposerProject (finalAttrs: {
vendorHash = "sha256-NVvx1aKhbC5XuXt2+gS2c3ulNWoCKrYNnEleBuAcftQ="; vendorHash = "sha256-NVvx1aKhbC5XuXt2+gS2c3ulNWoCKrYNnEleBuAcftQ=";
# Patch sources to allow more restrictive permissions # Patch sources to allow more restrictive permissions
patches = [ ./config-filesystems.patch ]; # patches = [ ./config-filesystems.patch ];
# Upstream composer.json has invalid license, webpatser/laravel-countries package is pointing # Upstream composer.json has invalid license, webpatser/laravel-countries package is pointing
# to commit-ref, and php required in require and require-dev # to commit-ref, and php required in require and require-dev

View File

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }: { config
, lib
, pkgs
, modulesPath
, ... }:
let let
cfg = config.services.invoice-ninja; cfg = config.services.invoice-ninja;
@ -90,7 +95,7 @@ in
description = "How often the Invoice Ninja cron task should run."; description = "How often the Invoice Ninja cron task should run.";
}; };
domain = lib.mkOption { hostName = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = "localhost"; default = "localhost";
description = '' description = ''
@ -157,7 +162,7 @@ in
createLocally = lib.mkOption { createLocally = lib.mkOption {
type = lib.types.bool; type = lib.types.bool;
default = true; default = true;
description = "a local database using UNIX socket authentication"; description = "A local database using UNIX socket authentication";
}; };
name = lib.mkOption { name = lib.mkOption {
@ -167,17 +172,66 @@ in
}; };
}; };
caddy = lib.mkOption { maxUploadSize = lib.mkOption {
type = lib.types.bool; type = lib.types.str;
default = true; default = "8M";
description = '' description = "Maximum allowed upload size to Invoice Ninja.";
Whether to enable a preconfigured Caddy server to serve };
Invoice Ninja.
''; webserver = {
caddy = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to enable the Caddy server to serve Invoice Ninja.";
};
config = lib.mkOption {
type = lib.types.submodule (
(import (modulesPath + "/services/web-servers/caddy/vhost-options.nix") { cfg = config.services.caddy; }) {
inherit lib; config = cfg; name = (if (cfg.hostName == "localhost") then ":80" else cfg.hostName);
}
);
default = { };
description = ''
Extra configuration for the Caddy virtual host of Invoice Ninja.
Set to `{ }` to use the default configuration
'';
};
};
nginx = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to enable Nginx server to serve Invoice Ninja.
'';
};
config = lib.mkOption {
type = lib.types.submodule (
(import (modulesPath + "/services/web-servers/nginx/vhost-options.nix") { inherit config lib; })
);
default = { };
description = ''
Extra configuration for the Nginx virtual host of Invoice Ninja.
Set to `{ }` to use the default configuration
'';
};
};
}; };
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
# FIXME Caddy and Nginx should be mutually exclusive
assertions = [
{
assertion = (cfg.webserver.nginx.enable || cfg.webserver.caddy.enable);
message = "Either the Caddy or Nginx webserver needs to be enabled.";
}
];
users.users.invoiceninja = lib.mkIf (cfg.user == "invoiceninja") { users.users.invoiceninja = lib.mkIf (cfg.user == "invoiceninja") {
isSystemUser = true; isSystemUser = true;
home = cfg.dataDir; home = cfg.dataDir;
@ -191,10 +245,10 @@ in
services.invoice-ninja.settings = services.invoice-ninja.settings =
let let
app_http_url = "http://${cfg.domain}"; app_http_url = "http://${cfg.hostName}";
app_https_url = "https://${cfg.domain}"; app_https_url = "https://${cfg.hostName}";
react_http_url = "http://${cfg.domain}:3001"; react_http_url = "http://${cfg.hostName}:3001";
react_https_url = "https://${cfg.domain}:3001"; react_https_url = "https://${cfg.hostName}:3001";
chromium = lib.lists.findSingle (x: x == pkgs.chromium) "none" "multiple" extraPrograms; chromium = lib.lists.findSingle (x: x == pkgs.chromium) "none" "multiple" extraPrograms;
in in
lib.mkMerge [ lib.mkMerge [
@ -202,8 +256,8 @@ in
APP_NAME = lib.mkDefault "\"Invoice Ninja\""; APP_NAME = lib.mkDefault "\"Invoice Ninja\"";
APP_ENV = lib.mkDefault "production"; APP_ENV = lib.mkDefault "production";
APP_DEBUG = lib.mkDefault false; APP_DEBUG = lib.mkDefault false;
APP_URL = lib.mkDefault (if (cfg.domain != "localhost") then "${app_https_url}" else "${app_http_url}"); APP_URL = lib.mkDefault (if (cfg.hostName != "localhost") then "${app_https_url}" else "${app_http_url}");
REACT_URL = lib.mkDefault (if (cfg.domain != "localhost") then "${react_https_url}" else "${react_http_url}"); REACT_URL = lib.mkDefault (if (cfg.hostName != "localhost") then "${react_https_url}" else "${react_http_url}");
DB_CONNECTION = lib.mkDefault "mysql"; DB_CONNECTION = lib.mkDefault "mysql";
MULTI_DB_ENABLED = lib.mkDefault false; MULTI_DB_ENABLED = lib.mkDefault false;
DEMO_MODE = lib.mkDefault false; DEMO_MODE = lib.mkDefault false;
@ -213,7 +267,7 @@ in
QUEUE_CONNECTION = lib.mkDefault "database"; QUEUE_CONNECTION = lib.mkDefault "database";
SESSION_DRIVER = lib.mkDefault "file"; SESSION_DRIVER = lib.mkDefault "file";
SESSION_LIFETIME = lib.mkDefault "120"; SESSION_LIFETIME = lib.mkDefault "120";
REQUIRE_HTTPS = lib.mkDefault (if (cfg.domain != "localhost") then true else false); REQUIRE_HTTPS = lib.mkDefault (if (cfg.hostName != "localhost") then true else false);
TRUSTED_PROXIES = lib.mkDefault "127.0.0.1"; TRUSTED_PROXIES = lib.mkDefault "127.0.0.1";
NINJA_ENVIRONMENT = lib.mkDefault "selfhost"; NINJA_ENVIRONMENT = lib.mkDefault "selfhost";
PDF_GENERATOR = lib.mkDefault "snappdf"; PDF_GENERATOR = lib.mkDefault "snappdf";
@ -232,27 +286,72 @@ in
services.phpfpm.pools.invoice-ninja = { services.phpfpm.pools.invoice-ninja = {
inherit user group phpPackage; inherit user group phpPackage;
inherit (cfg.phpfpm) settings; inherit (cfg.phpfpm) settings;
phpOptions = ''
post_max_size = ${cfg.maxUploadSize}
upload_max_filesize = ${cfg.maxUploadSize}
max_execution_time = 600;
'';
}; };
users.users."${config.services.caddy.user}" = lib.mkIf (cfg.caddy != false) { extraGroups = [ cfg.group ]; }; users.users."${config.services.nginx.user}" = lib.mkIf (cfg.webserver.nginx.enable == true) { extraGroups = [ cfg.group ]; };
services.caddy = services.nginx = lib.mkIf ((cfg.webserver.nginx.enable == true) && (cfg.webserver.caddy.enable == false)) {
let inherit (cfg.webserver.nginx) enable;
caddyDomain = if (cfg.domain == "localhost") then ":80" else cfg.domain;
in
lib.mkIf (cfg.caddy != false) {
enable = true;
globalConfig = lib.mkIf (cfg.domain == "localhost") '' recommendedTlsSettings = true;
recommendedGzipSettings = true;
recommendedProxySettings = true;
recommendedOptimisation = true;
clientMaxBodySize = cfg.maxUploadSize;
virtualHosts."${cfg.hostName}" = lib.mkMerge [
cfg.webserver.nginx.config
{
root = lib.mkForce "${invoice-ninja}/public";
locations = {
"/" = {
tryFiles = "$uri $uri/ /index.php?$query_string";
extraConfig = ''
if (!-e $request_filename) {
rewrite ^(.+)$ /index.php?q=$1 last;
}
'';
};
"~ \\.php$".extraConfig = ''
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:${config.services.phpfpm.pools.invoice-ninja.socket};
fastcgi_index index.php;
'';
"~ /\\.ht".extraConfig = "deny all;";
};
extraConfig = ''
index index.html index.htm index.php;
error_page 404 /index.php;
'';
}
];
};
users.users."${config.services.caddy.user}" = lib.mkIf (cfg.webserver.caddy.enable == true) { extraGroups = [ cfg.group ]; };
services.caddy = lib.mkIf ((cfg.webserver.caddy.enable == true) && (cfg.webserver.nginx.enable == false)) {
inherit (cfg.webserver.caddy) enable;
globalConfig = lib.mkIf (cfg.hostName == "localhost") ''
auto_https disable_redirects auto_https disable_redirects
''; '';
virtualHosts."${caddyDomain}".extraConfig = '' virtualHosts."${cfg.hostName}" = lib.mkMerge [
encode zstd gzip cfg.webserver.caddy.config
root * ${invoice-ninja}/public/ {
php_fastcgi unix/${config.services.phpfpm.pools.invoice-ninja.socket} extraConfig = ''
try_files {path} {path}/ /public/{path} /index.php?{query} encode zstd gzip
file_server root * ${invoice-ninja}/public
''; php_fastcgi unix/${config.services.phpfpm.pools.invoice-ninja.socket}
file_server
'';
}
];
}; };
services.mysql = lib.mkIf (cfg.database.createLocally) { services.mysql = lib.mkIf (cfg.database.createLocally) {
@ -363,13 +462,6 @@ in
"${cfg.dataDir}/storage/framework/sessions" "${cfg.dataDir}/storage/framework/sessions"
"${cfg.dataDir}/storage/framework/views" "${cfg.dataDir}/storage/framework/views"
"${cfg.dataDir}/storage/logs" "${cfg.dataDir}/storage/logs"
] (n: {
d = {
user = user;
group = group;
mode = "0770";
};
}) // lib.attrsets.genAttrs [
cfg.runtimeDir cfg.runtimeDir
"${cfg.runtimeDir}/cache" "${cfg.runtimeDir}/cache"
] (n: { ] (n: {

View File

@ -19,7 +19,6 @@
services.invoice-ninja = { services.invoice-ninja = {
enable = true; enable = true;
database.createLocally = true; database.createLocally = true;
caddy = true;
secretFile = ./test-secrets.env; secretFile = ./test-secrets.env;
}; };