Module pour lychee #4

Merged
sinavir merged 5 commits from photos-nuit into main 2022-12-13 21:56:50 +01:00
3 changed files with 72 additions and 106 deletions
Showing only changes of commit cdfc2b380e - Show all commits

View file

@ -3,5 +3,5 @@
drone-server = ./servers/drone.nix; drone-server = ./servers/drone.nix;
drone-exec-runner = ./servers/drone-exec-runner.nix; drone-exec-runner = ./servers/drone-exec-runner.nix;
wordpress = ./web-apps/wordpress; wordpress = ./web-apps/wordpress;
lychee = ./web-apps/lychee.nix; lychee = ./web-apps/lychee;
} }

View file

@ -17,12 +17,12 @@ in
}; };
forceSSL = lib.mkOption { forceSSL = lib.mkOption {
type = lib.types.bool; type = lib.types.bool;
default = true; default = false;
description = "Whether to force SSL for the nginx virtual host"; description = "Whether to force SSL for the nginx virtual host";
}; };
enableACME = lib.mkOption { enableACME = lib.mkOption {
type = lib.types.bool; type = lib.types.bool;
default = true; default = false;
description = "Whether to enableACME for the nginx virtual host"; description = "Whether to enableACME for the nginx virtual host";
}; };
upload_max_filesize = lib.mkOption { upload_max_filesize = lib.mkOption {
@ -40,38 +40,14 @@ in
default = "lychee"; default = "lychee";
description = "The user that will operate on mutable files"; description = "The user that will operate on mutable files";
}; };
stateDirectory = lib.mkOption {
type = lib.types.path;
default = "/var/lib/lychee";
};
settings = lib.mkOption { settings = lib.mkOption {
default = {}; default = {};
type = lib.types.submodule { type = lib.types.submodule {
freeformType = with lib.types; attrsOf str; freeformType = with lib.types; attrsOf str;
options = { options = {
DB_DATABASE= lib.mkOption {
type = lib.types.str;
default = "${cfg.stateDirectory}/db.sqlite";
};
APP_NAME= lib.mkOption {
type = lib.types.str;
default = "Lychee";
};
APP_ENV = lib.mkOption {
type = lib.types.str;
default = "production";
};
APP_DEBUG = lib.mkOption {
type = lib.types.str;
default = "\"false\"";
};
APP_URL = lib.mkOption { APP_URL = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = "https://${cfg.website}"; default = "http://${cfg.website}";
};
DEBUGBAR_ENABLED = lib.mkOption {
type = lib.types.str;
default = "\"false\"";
}; };
DB_CONNECTION = lib.mkOption { DB_CONNECTION = lib.mkOption {
type = lib.types.str; type = lib.types.str;
@ -81,10 +57,6 @@ in
type = lib.types.str; type = lib.types.str;
default = "\"false\""; default = "\"false\"";
}; };
LYCHEE_UPLOADS = lib.mkOption {
type = lib.types.path;
default = "${cfg.stateDirectory}/www/public/uploads";
};
CACHE_DRIVER = lib.mkOption { CACHE_DRIVER = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = "file"; default = "file";
@ -117,28 +89,15 @@ in
type = lib.types.str; type = lib.types.str;
default = "smtp"; default = "smtp";
}; };
TRUSTED_PROXIES = lib.mkOption {
type = lib.types.str;
default = "\"null\"";
}; };
}; };
}; };
}; };
}; config = lib.mkIf cfg.enable {
config = let srcDirsToBindMount = [
"app"
"bootstrap"
"config"
"resources"
"routes"
"scripts"
"vendor"
];
in lib.mkIf cfg.enable {
services.nginx = { services.nginx = {
enable = true; enable = true;
virtualHosts.${cfg.website} = { virtualHosts.${cfg.website} = {
root = cfg.stateDirectory + "/www/public/"; root = "/var/lib/lychee/public/";
forceSSL = lib.mkDefault cfg.forceSSL; forceSSL = lib.mkDefault cfg.forceSSL;
enableACME = lib.mkDefault cfg.enableACME; enableACME = lib.mkDefault cfg.enableACME;
locations = { locations = {
@ -156,9 +115,6 @@ in
"~ [^/]\.php(/|$)" = { "~ [^/]\.php(/|$)" = {
return = "403"; return = "403";
}; };
"/uploads/" = {
alias = cfg.settings.LYCHEE_UPLOADS;
};
}; };
extraConfig = '' extraConfig = ''
index index.php; index index.php;
@ -170,61 +126,40 @@ in
''; '';
}; };
}; };
systemd.tmpfiles.rules = let srcDirToTmpFile = dir: "d ${cfg.stateDirectory}/www/${dir} 0750 ${cfg.user} ${config.services.nginx.group}"; systemd.services."lychee-install" = {
in [
"d ${cfg.stateDirectory} 0750 ${cfg.user} ${config.services.nginx.group}"
"d ${cfg.stateDirectory}/www 0750 ${cfg.user} ${config.services.nginx.group}"
"C ${cfg.stateDirectory}/public - ${cfg.user} ${config.services.nginx.group} - ${src}/public"
"Z ${cfg.stateDirectory}/public 0750 ${cfg.user} ${config.services.nginx.group} - -"
"C ${cfg.stateDirectory}/database - ${cfg.user} ${config.services.nginx.group} - ${src}/database"
"Z ${cfg.stateDirectory}/database 0750 ${cfg.user} ${config.services.nginx.group} - -"
"C ${cfg.stateDirectory}/bootstrap-cache - ${cfg.user} ${config.services.nginx.group} - ${src}/bootstrap/cache"
"Z ${cfg.stateDirectory}/bootstrap-cache 0750 ${cfg.user} ${config.services.nginx.group} - -"
"C ${cfg.stateDirectory}/storage - ${cfg.user} ${config.services.nginx.group} - ${src}/storage"
"Z ${cfg.stateDirectory}/storage 0750 ${cfg.user} ${config.services.nginx.group} - -"
"C ${cfg.settings.LYCHEE_UPLOADS} - ${cfg.user} ${config.services.nginx.group} - ${src}/public/uploads"
"Z ${cfg.settings.LYCHEE_UPLOADS} 0750 ${cfg.user} ${config.services.nginx.group} - -"
"f ${cfg.settings.DB_DATABASE} 0750 ${cfg.user} ${cfg.user}"
"L ${cfg.stateDirectory}/www/artisan - - - - ${src}/artisan"
"L ${cfg.stateDirectory}/www/composer.json - - - - ${src}/composer.json"
"L ${cfg.stateDirectory}/www/composer.lock - - - - ${src}/composer.lock"
"L ${cfg.stateDirectory}/www/version.md - - - - ${src}/version.md"
"L ${cfg.stateDirectory}/www/simple_error_template.html - - - - ${src}/simple_error_template.html"
] ++ (builtins.map srcDirToTmpFile srcDirsToBindMount);
systemd.mounts = let sourceDirToSystemdMount = dir: {
before = [ "phpfpm-${cfg.website}.service" ];
wantedBy = [ "phpfpm-${cfg.website}.service" ]; wantedBy = [ "phpfpm-${cfg.website}.service" ];
what = "${src}/${dir}"; script = let rsync = pkgs.rsync; in ''
where = cfg.stateDirectory + "/www/${dir}"; ${rsync}/bin/rsync -a --ignore-existing ${src}/ $STATE_DIRECTORY
options = "bind"; chmod u+w $STATE_DIRECTORY/
chmod u+w $STATE_DIRECTORY/.env
chmod u+w $STATE_DIRECTORY/database/
chmod u+w $STATE_DIRECTORY/database/database.sqlite
chmod -R u+w $STATE_DIRECTORY/storage/
chmod -R u+w $STATE_DIRECTORY/public/
chmod -R u+w $STATE_DIRECTORY/bootstrap/cache/
'';
serviceConfig = {
Type = "oneshot";
StateDirectory = "lychee";
User = cfg.user;
Restart = "on-failure";
ProtectHome = true;
ProtectSystem = "strict";
PrivateTmp = true;
PrivateDevices = true;
ProtectHostname = true;
ProtectClock = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectKernelLogs = true;
ProtectControlGroups = true;
NoNewPrivileges = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
RemoveIPC = true;
PrivateMounts = true;
};
}; };
in [{
before = [ "phpfpm-${cfg.website}.service" ];
wantedBy = [ "phpfpm-${cfg.website}.service" ];
what = cfg.stateDirectory + "/storage";
where = cfg.stateDirectory + "/www/storage";
options = "bind";
}] ++ (builtins.map sourceDirToSystemdMount srcDirsToBindMount) ++ [{
before = [ "phpfpm-${cfg.website}.service" ];
wantedBy = [ "phpfpm-${cfg.website}.service" ];
what = cfg.stateDirectory + "/bootstrap-cache";
where = cfg.stateDirectory + "/www/bootstrap/cache";
options = "bind";
}
{
before = [ "phpfpm-${cfg.website}.service" ];
wantedBy = [ "phpfpm-${cfg.website}.service" ];
what = cfg.stateDirectory + "/database";
where = cfg.stateDirectory + "/www/database";
options = "bind";
}
{
before = [ "phpfpm-${cfg.website}.service" ];
wantedBy = [ "phpfpm-${cfg.website}.service" ];
what = cfg.stateDirectory + "/public";
where = cfg.stateDirectory + "/www/public";
options = "bind";
}];
services.phpfpm.pools.${cfg.website} = { services.phpfpm.pools.${cfg.website} = {
user = cfg.user; user = cfg.user;
phpPackage = pkgs.php81.withExtensions ({ enabled, all }: phpPackage = pkgs.php81.withExtensions ({ enabled, all }:
@ -248,9 +183,9 @@ in
} // envConf; } // envConf;
}; };
users.users.${cfg.user} = { users.users.${cfg.user} = {
isSystemUser = true; isSystemUser = lib.mkDefault true;
home = src; home = lib.mkDefault src;
group = cfg.user; group = lib.mkDefault cfg.user;
}; };
users.groups.${cfg.user} = { }; users.groups.${cfg.user} = { };
networking.firewall.allowedTCPPorts = [ 80 443 ]; networking.firewall.allowedTCPPorts = [ 80 443 ];

View file

@ -0,0 +1,31 @@
{ pkgs ? import <nixpkgs> {}, myPkgs ? import ../.. {}}:
pkgs.nixosTest ({
# NixOS tests are run inside a virtual machine, and here we specify system of the machine.
nodes = {
server = { config, pkgs, ... }: {
imports = [ myPkgs.modules.lychee ];
security.acme.acceptTerms = true;
security.acme.defaults.email = "test@test.fr";
services.lychee = {
enable = true;
package = myPkgs.lychee-gallery;
forceSSL = true;
enableACME = true;
};
environment.systemPackages = [ pkgs.w3m ];
users = {
mutableUsers = false;
users = {
# For ease of debugging the VM as the `root` user
root.password = "";
};
};
};
};
testScript = ''
start_all()
server.wait_for_unit("default.target")
'';
})