nixos/dokuwiki: Add support for Caddy web server

Changed files
+401 -287
nixos
doc
manual
from_md
release-notes
release-notes
modules
services
web-apps
tests
+16
nixos/doc/manual/from_md/release-notes/rl-2111.section.xml
···
</listitem>
<listitem>
<para>
+
The dokuwiki module provides a new interface which allows to
+
use different webservers with the new option
+
<link xlink:href="options.html#opt-services.dokuwiki.webserver"><literal>services.dokuwiki.webserver</literal></link>.
+
Currently <literal>caddy</literal> and
+
<literal>nginx</literal> are supported. The definitions of
+
dokuwiki sites should now be set in
+
<link xlink:href="options.html#opt-services.dokuwiki.sites"><literal>services.dokuwiki.sites</literal></link>.
+
</para>
+
<para>
+
Sites definitions that use the old interface are automatically
+
migrated in the new option. This backward compatibility will
+
be removed in 22.05.
+
</para>
+
</listitem>
+
<listitem>
+
<para>
The order of NSS (host) modules has been brought in line with
upstream recommendations:
</para>
+4
nixos/doc/manual/release-notes/rl-2111.section.md
···
Sites definitions that use the old interface are automatically migrated in the new option. This backward compatibility will be removed in 22.05.
+
- The dokuwiki module provides a new interface which allows to use different webservers with the new option [`services.dokuwiki.webserver`](options.html#opt-services.dokuwiki.webserver). Currently `caddy` and `nginx` are supported. The definitions of dokuwiki sites should now be set in [`services.dokuwiki.sites`](options.html#opt-services.dokuwiki.sites).
+
+
Sites definitions that use the old interface are automatically migrated in the new option. This backward compatibility will be removed in 22.05.
+
- The order of NSS (host) modules has been brought in line with upstream
recommendations:
+321 -262
nixos/modules/services/web-apps/dokuwiki.nix
···
-
{ config, lib, pkgs, ... }:
+
{ config, pkgs, lib, ... }:
let
+
inherit (lib) mkDefault mkEnableOption mkForce mkIf mkMerge mkOption types maintainers recursiveUpdate;
+
inherit (lib) any attrValues concatMapStrings concatMapStringsSep flatten literalExample;
+
inherit (lib) filterAttrs mapAttrs mapAttrs' mapAttrsToList nameValuePair optional optionalAttrs optionalString;
-
inherit (lib) mkEnableOption mkForce mkIf mkMerge mkOption optionalAttrs recursiveUpdate types maintainers;
-
inherit (lib) concatMapStringsSep flatten mapAttrs mapAttrs' mapAttrsToList nameValuePair concatMapStringSep;
+
cfg = migrateOldAttrs config.services.dokuwiki;
+
eachSite = cfg.sites;
+
user = "dokuwiki";
+
webserver = config.services.${cfg.webserver};
+
stateDir = hostName: "/var/lib/dokuwiki/${hostName}/data";
-
eachSite = config.services.dokuwiki;
+
# Migrate config.services.dokuwiki.<hostName> to config.services.dokuwiki.sites.<hostName>
+
oldSites = filterAttrs (o: _: o != "sites" && o != "webserver");
+
migrateOldAttrs = cfg: cfg // { sites = cfg.sites // oldSites cfg; };
-
user = "dokuwiki";
-
group = config.services.nginx.group;
-
-
dokuwikiAclAuthConfig = cfg: pkgs.writeText "acl.auth.php" ''
+
dokuwikiAclAuthConfig = hostName: cfg: pkgs.writeText "acl.auth-${hostName}.php" ''
# acl.auth.php
# <?php exit()?>
#
···
${toString cfg.acl}
'';
-
dokuwikiLocalConfig = cfg: pkgs.writeText "local.php" ''
+
dokuwikiLocalConfig = hostName: cfg: pkgs.writeText "local-${hostName}.php" ''
<?php
$conf['savedir'] = '${cfg.stateDir}';
$conf['superuser'] = '${toString cfg.superUser}';
···
${toString cfg.extraConfig}
'';
-
dokuwikiPluginsLocalConfig = cfg: pkgs.writeText "plugins.local.php" ''
+
dokuwikiPluginsLocalConfig = hostName: cfg: pkgs.writeText "plugins.local-${hostName}.php" ''
<?php
${cfg.pluginsConfig}
'';
+
pkg = hostName: cfg: pkgs.stdenv.mkDerivation rec {
pname = "dokuwiki-${hostName}";
···
cp -r * $out/
# symlink the dokuwiki config
-
ln -s ${dokuwikiLocalConfig cfg} $out/share/dokuwiki/local.php
+
ln -s ${dokuwikiLocalConfig hostName cfg} $out/share/dokuwiki/local.php
# symlink plugins config
-
ln -s ${dokuwikiPluginsLocalConfig cfg} $out/share/dokuwiki/plugins.local.php
+
ln -s ${dokuwikiPluginsLocalConfig hostName cfg} $out/share/dokuwiki/plugins.local.php
# symlink acl
-
ln -s ${dokuwikiAclAuthConfig cfg} $out/share/dokuwiki/acl.auth.php
+
ln -s ${dokuwikiAclAuthConfig hostName cfg} $out/share/dokuwiki/acl.auth.php
# symlink additional plugin(s) and templates(s)
${concatMapStringsSep "\n" (template: "ln -s ${template} $out/share/dokuwiki/lib/tpl/${template.name}") cfg.templates}
···
'';
};
-
siteOpts = { config, lib, name, ...}: {
-
options = {
-
enable = mkEnableOption "DokuWiki web application.";
-
-
package = mkOption {
-
type = types.package;
-
default = pkgs.dokuwiki;
-
description = "Which dokuwiki package to use.";
-
};
-
-
hostName = mkOption {
-
type = types.str;
-
default = "localhost";
-
description = "FQDN for the instance.";
-
};
-
-
stateDir = mkOption {
-
type = types.path;
-
default = "/var/lib/dokuwiki/${name}/data";
-
description = "Location of the dokuwiki state directory.";
-
};
+
siteOpts = { config, lib, name, ... }:
+
{
+
options = {
+
package = mkOption {
+
type = types.package;
+
default = pkgs.dokuwiki;
+
description = "Which DokuWiki package to use.";
+
};
-
acl = mkOption {
-
type = types.nullOr types.lines;
-
default = null;
-
example = "* @ALL 8";
-
description = ''
-
Access Control Lists: see <link xlink:href="https://www.dokuwiki.org/acl"/>
-
Mutually exclusive with services.dokuwiki.aclFile
-
Set this to a value other than null to take precedence over aclFile option.
+
stateDir = mkOption {
+
type = types.path;
+
default = "/var/lib/dokuwiki/${name}/data";
+
description = "Location of the DokuWiki state directory.";
+
};
-
Warning: Consider using aclFile instead if you do not
-
want to store the ACL in the world-readable Nix store.
-
'';
-
};
+
acl = mkOption {
+
type = types.nullOr types.lines;
+
default = null;
+
example = "* @ALL 8";
+
description = ''
+
Access Control Lists: see <link xlink:href="https://www.dokuwiki.org/acl"/>
+
Mutually exclusive with services.dokuwiki.aclFile
+
Set this to a value other than null to take precedence over aclFile option.
-
aclFile = mkOption {
-
type = with types; nullOr str;
-
default = if (config.aclUse && config.acl == null) then "/var/lib/dokuwiki/${name}/acl.auth.php" else null;
-
description = ''
-
Location of the dokuwiki acl rules. Mutually exclusive with services.dokuwiki.acl
-
Mutually exclusive with services.dokuwiki.acl which is preferred.
-
Consult documentation <link xlink:href="https://www.dokuwiki.org/acl"/> for further instructions.
-
Example: <link xlink:href="https://github.com/splitbrain/dokuwiki/blob/master/conf/acl.auth.php.dist"/>
-
'';
-
example = "/var/lib/dokuwiki/${name}/acl.auth.php";
-
};
+
Warning: Consider using aclFile instead if you do not
+
want to store the ACL in the world-readable Nix store.
+
'';
+
};
-
aclUse = mkOption {
-
type = types.bool;
-
default = true;
-
description = ''
-
Necessary for users to log in into the system.
-
Also limits anonymous users. When disabled,
-
everyone is able to create and edit content.
-
'';
-
};
+
aclFile = mkOption {
+
type = with types; nullOr str;
+
default = if (config.aclUse && config.acl == null) then "/var/lib/dokuwiki/${name}/acl.auth.php" else null;
+
description = ''
+
Location of the dokuwiki acl rules. Mutually exclusive with services.dokuwiki.acl
+
Mutually exclusive with services.dokuwiki.acl which is preferred.
+
Consult documentation <link xlink:href="https://www.dokuwiki.org/acl"/> for further instructions.
+
Example: <link xlink:href="https://github.com/splitbrain/dokuwiki/blob/master/conf/acl.auth.php.dist"/>
+
'';
+
example = "/var/lib/dokuwiki/${name}/acl.auth.php";
+
};
-
pluginsConfig = mkOption {
-
type = types.lines;
-
default = ''
-
$plugins['authad'] = 0;
-
$plugins['authldap'] = 0;
-
$plugins['authmysql'] = 0;
-
$plugins['authpgsql'] = 0;
-
'';
-
description = ''
-
List of the dokuwiki (un)loaded plugins.
-
'';
-
};
+
aclUse = mkOption {
+
type = types.bool;
+
default = true;
+
description = ''
+
Necessary for users to log in into the system.
+
Also limits anonymous users. When disabled,
+
everyone is able to create and edit content.
+
'';
+
};
-
superUser = mkOption {
-
type = types.nullOr types.str;
-
default = "@admin";
-
description = ''
-
You can set either a username, a list of usernames (“admin1,admin2”),
-
or the name of a group by prepending an @ char to the groupname
-
Consult documentation <link xlink:href="https://www.dokuwiki.org/config:superuser"/> for further instructions.
-
'';
-
};
+
pluginsConfig = mkOption {
+
type = types.lines;
+
default = ''
+
$plugins['authad'] = 0;
+
$plugins['authldap'] = 0;
+
$plugins['authmysql'] = 0;
+
$plugins['authpgsql'] = 0;
+
'';
+
description = ''
+
List of the dokuwiki (un)loaded plugins.
+
'';
+
};
-
usersFile = mkOption {
-
type = with types; nullOr str;
-
default = if config.aclUse then "/var/lib/dokuwiki/${name}/users.auth.php" else null;
-
description = ''
-
Location of the dokuwiki users file. List of users. Format:
-
login:passwordhash:Real Name:email:groups,comma,separated
-
Create passwordHash easily by using:$ mkpasswd -5 password `pwgen 8 1`
-
Example: <link xlink:href="https://github.com/splitbrain/dokuwiki/blob/master/conf/users.auth.php.dist"/>
+
superUser = mkOption {
+
type = types.nullOr types.str;
+
default = "@admin";
+
description = ''
+
You can set either a username, a list of usernames (“admin1,admin2”),
+
or the name of a group by prepending an @ char to the groupname
+
Consult documentation <link xlink:href="https://www.dokuwiki.org/config:superuser"/> for further instructions.
'';
-
example = "/var/lib/dokuwiki/${name}/users.auth.php";
-
};
+
};
-
disableActions = mkOption {
-
type = types.nullOr types.str;
-
default = "";
-
example = "search,register";
-
description = ''
-
Disable individual action modes. Refer to
-
<link xlink:href="https://www.dokuwiki.org/config:action_modes"/>
-
for details on supported values.
-
'';
-
};
+
usersFile = mkOption {
+
type = with types; nullOr str;
+
default = if config.aclUse then "/var/lib/dokuwiki/${name}/users.auth.php" else null;
+
description = ''
+
Location of the dokuwiki users file. List of users. Format:
+
login:passwordhash:Real Name:email:groups,comma,separated
+
Create passwordHash easily by using:$ mkpasswd -5 password `pwgen 8 1`
+
Example: <link xlink:href="https://github.com/splitbrain/dokuwiki/blob/master/conf/users.auth.php.dist"/>
+
'';
+
example = "/var/lib/dokuwiki/${name}/users.auth.php";
+
};
-
extraConfig = mkOption {
-
type = types.nullOr types.lines;
-
default = null;
-
example = ''
-
$conf['title'] = 'My Wiki';
-
$conf['userewrite'] = 1;
-
'';
-
description = ''
-
DokuWiki configuration. Refer to
-
<link xlink:href="https://www.dokuwiki.org/config"/>
-
for details on supported values.
-
'';
-
};
+
disableActions = mkOption {
+
type = types.nullOr types.str;
+
default = "";
+
example = "search,register";
+
description = ''
+
Disable individual action modes. Refer to
+
<link xlink:href="https://www.dokuwiki.org/config:action_modes"/>
+
for details on supported values.
+
'';
+
};
-
plugins = mkOption {
-
type = types.listOf types.path;
-
default = [];
-
description = ''
-
List of path(s) to respective plugin(s) which are copied from the 'plugin' directory.
-
<note><para>These plugins need to be packaged before use, see example.</para></note>
-
'';
-
example = ''
-
# Let's package the icalevents plugin
-
plugin-icalevents = pkgs.stdenv.mkDerivation {
-
name = "icalevents";
-
# Download the plugin from the dokuwiki site
-
src = pkgs.fetchurl {
-
url = "https://github.com/real-or-random/dokuwiki-plugin-icalevents/releases/download/2017-06-16/dokuwiki-plugin-icalevents-2017-06-16.zip";
-
sha256 = "e40ed7dd6bbe7fe3363bbbecb4de481d5e42385b5a0f62f6a6ce6bf3a1f9dfa8";
+
plugins = mkOption {
+
type = types.listOf types.path;
+
default = [];
+
description = ''
+
List of path(s) to respective plugin(s) which are copied from the 'plugin' directory.
+
<note><para>These plugins need to be packaged before use, see example.</para></note>
+
'';
+
example = ''
+
# Let's package the icalevents plugin
+
plugin-icalevents = pkgs.stdenv.mkDerivation {
+
name = "icalevents";
+
# Download the plugin from the dokuwiki site
+
src = pkgs.fetchurl {
+
url = "https://github.com/real-or-random/dokuwiki-plugin-icalevents/releases/download/2017-06-16/dokuwiki-plugin-icalevents-2017-06-16.zip";
+
sha256 = "e40ed7dd6bbe7fe3363bbbecb4de481d5e42385b5a0f62f6a6ce6bf3a1f9dfa8";
+
};
+
sourceRoot = ".";
+
# We need unzip to build this package
+
buildInputs = [ pkgs.unzip ];
+
# Installing simply means copying all files to the output directory
+
installPhase = "mkdir -p $out; cp -R * $out/";
};
-
sourceRoot = ".";
-
# We need unzip to build this package
-
nativeBuildInputs = [ pkgs.unzip ];
-
# Installing simply means copying all files to the output directory
-
installPhase = "mkdir -p $out; cp -R * $out/";
-
};
-
# And then pass this theme to the plugin list like this:
-
plugins = [ plugin-icalevents ];
-
'';
-
};
+
# And then pass this theme to the plugin list like this:
+
plugins = [ plugin-icalevents ];
+
'';
+
};
-
templates = mkOption {
-
type = types.listOf types.path;
-
default = [];
-
description = ''
-
List of path(s) to respective template(s) which are copied from the 'tpl' directory.
-
<note><para>These templates need to be packaged before use, see example.</para></note>
-
'';
-
example = ''
-
# Let's package the bootstrap3 theme
-
template-bootstrap3 = pkgs.stdenv.mkDerivation {
-
name = "bootstrap3";
-
# Download the theme from the dokuwiki site
-
src = pkgs.fetchurl {
-
url = "https://github.com/giterlizzi/dokuwiki-template-bootstrap3/archive/v2019-05-22.zip";
-
sha256 = "4de5ff31d54dd61bbccaf092c9e74c1af3a4c53e07aa59f60457a8f00cfb23a6";
+
templates = mkOption {
+
type = types.listOf types.path;
+
default = [];
+
description = ''
+
List of path(s) to respective template(s) which are copied from the 'tpl' directory.
+
<note><para>These templates need to be packaged before use, see example.</para></note>
+
'';
+
example = ''
+
# Let's package the bootstrap3 theme
+
template-bootstrap3 = pkgs.stdenv.mkDerivation {
+
name = "bootstrap3";
+
# Download the theme from the dokuwiki site
+
src = pkgs.fetchurl {
+
url = "https://github.com/giterlizzi/dokuwiki-template-bootstrap3/archive/v2019-05-22.zip";
+
sha256 = "4de5ff31d54dd61bbccaf092c9e74c1af3a4c53e07aa59f60457a8f00cfb23a6";
+
};
+
# We need unzip to build this package
+
buildInputs = [ pkgs.unzip ];
+
# Installing simply means copying all files to the output directory
+
installPhase = "mkdir -p $out; cp -R * $out/";
};
-
# We need unzip to build this package
-
nativeBuildInputs = [ pkgs.unzip ];
-
# Installing simply means copying all files to the output directory
-
installPhase = "mkdir -p $out; cp -R * $out/";
-
};
-
# And then pass this theme to the template list like this:
-
templates = [ template-bootstrap3 ];
-
'';
-
};
+
# And then pass this theme to the template list like this:
+
templates = [ template-bootstrap3 ];
+
'';
+
};
-
poolConfig = mkOption {
-
type = with types; attrsOf (oneOf [ str int bool ]);
-
default = {
-
"pm" = "dynamic";
-
"pm.max_children" = 32;
-
"pm.start_servers" = 2;
-
"pm.min_spare_servers" = 2;
-
"pm.max_spare_servers" = 4;
-
"pm.max_requests" = 500;
+
poolConfig = mkOption {
+
type = with types; attrsOf (oneOf [ str int bool ]);
+
default = {
+
"pm" = "dynamic";
+
"pm.max_children" = 32;
+
"pm.start_servers" = 2;
+
"pm.min_spare_servers" = 2;
+
"pm.max_spare_servers" = 4;
+
"pm.max_requests" = 500;
+
};
+
description = ''
+
Options for the DokuWiki PHP pool. See the documentation on <literal>php-fpm.conf</literal>
+
for details on configuration directives.
+
'';
};
-
description = ''
-
Options for the dokuwiki PHP pool. See the documentation on <literal>php-fpm.conf</literal>
-
for details on configuration directives.
-
'';
-
};
-
nginx = mkOption {
-
type = types.submodule (
-
recursiveUpdate
-
(import ../web-servers/nginx/vhost-options.nix { inherit config lib; }) {}
-
);
-
default = {};
-
example = {
-
serverAliases = [
-
"wiki.\${config.networking.domain}"
-
];
-
# To enable encryption and let let's encrypt take care of certificate
-
forceSSL = true;
-
enableACME = true;
+
extraConfig = mkOption {
+
type = types.nullOr types.lines;
+
default = null;
+
example = ''
+
$conf['title'] = 'My Wiki';
+
$conf['userewrite'] = 1;
+
'';
+
description = ''
+
DokuWiki configuration. Refer to
+
<link xlink:href="https://www.dokuwiki.org/config"/>
+
for details on supported values.
+
'';
};
-
description = ''
-
With this option, you can customize the nginx virtualHost settings.
-
'';
+
};
+
};
-
};
in
{
# interface
options = {
services.dokuwiki = mkOption {
-
type = types.attrsOf (types.submodule siteOpts);
+
type = types.submodule {
+
# Used to support old interface
+
freeformType = types.attrsOf (types.submodule siteOpts);
+
+
# New interface
+
options.sites = mkOption {
+
type = types.attrsOf (types.submodule siteOpts);
+
default = {};
+
description = "Specification of one or more DokuWiki sites to serve";
+
};
+
+
options.webserver = mkOption {
+
type = types.enum [ "nginx" "caddy" ];
+
default = "nginx";
+
description = ''
+
Whether to use nginx or caddy for virtual host management.
+
+
Further nginx configuration can be done by adapting <literal>services.nginx.virtualHosts.&lt;name&gt;</literal>.
+
See <xref linkend="opt-services.nginx.virtualHosts"/> for further information.
+
+
Further apache2 configuration can be done by adapting <literal>services.httpd.virtualHosts.&lt;name&gt;</literal>.
+
See <xref linkend="opt-services.httpd.virtualHosts"/> for further information.
+
'';
+
};
+
};
default = {};
-
description = "Sepcification of one or more dokuwiki sites to serve.";
+
description = "DokuWiki configuration";
};
+
};
# implementation
-
-
config = mkIf (eachSite != {}) {
-
-
warnings = mapAttrsToList (hostName: cfg: mkIf (cfg.superUser == null) "Not setting services.dokuwiki.${hostName} superUser will impair your ability to administer DokuWiki") eachSite;
+
config = mkIf (eachSite != {}) (mkMerge [{
assertions = flatten (mapAttrsToList (hostName: cfg:
[{
assertion = cfg.aclUse -> (cfg.acl != null || cfg.aclFile != null);
-
message = "Either services.dokuwiki.${hostName}.acl or services.dokuwiki.${hostName}.aclFile is mandatory if aclUse true";
+
message = "Either services.dokuwiki.sites.${hostName}.acl or services.dokuwiki.sites.${hostName}.aclFile is mandatory if aclUse true";
}
{
assertion = cfg.usersFile != null -> cfg.aclUse != false;
-
message = "services.dokuwiki.${hostName}.aclUse must must be true if usersFile is not null";
+
message = "services.dokuwiki.sites.${hostName}.aclUse must must be true if usersFile is not null";
}
]) eachSite);
+
warnings = mapAttrsToList (hostName: _: ''services.dokuwiki."${hostName}" is deprecated use services.dokuwiki.sites."${hostName}"'') (oldSites cfg);
+
services.phpfpm.pools = mapAttrs' (hostName: cfg: (
nameValuePair "dokuwiki-${hostName}" {
inherit user;
-
inherit group;
+
group = webserver.group;
+
phpEnv = {
-
DOKUWIKI_LOCAL_CONFIG = "${dokuwikiLocalConfig cfg}";
-
DOKUWIKI_PLUGINS_LOCAL_CONFIG = "${dokuwikiPluginsLocalConfig cfg}";
+
DOKUWIKI_LOCAL_CONFIG = "${dokuwikiLocalConfig hostName cfg}";
+
DOKUWIKI_PLUGINS_LOCAL_CONFIG = "${dokuwikiPluginsLocalConfig hostName cfg}";
} // optionalAttrs (cfg.usersFile != null) {
DOKUWIKI_USERS_AUTH_CONFIG = "${cfg.usersFile}";
} //optionalAttrs (cfg.aclUse) {
-
DOKUWIKI_ACL_AUTH_CONFIG = if (cfg.acl != null) then "${dokuwikiAclAuthConfig cfg}" else "${toString cfg.aclFile}";
+
DOKUWIKI_ACL_AUTH_CONFIG = if (cfg.acl != null) then "${dokuwikiAclAuthConfig hostName cfg}" else "${toString cfg.aclFile}";
};
settings = {
-
"listen.mode" = "0660";
-
"listen.owner" = user;
-
"listen.group" = group;
+
"listen.owner" = webserver.user;
+
"listen.group" = webserver.group;
} // cfg.poolConfig;
-
})) eachSite;
+
}
+
)) eachSite;
+
+
}
+
+
{
+
systemd.tmpfiles.rules = flatten (mapAttrsToList (hostName: cfg: [
+
"d ${stateDir hostName}/attic 0750 ${user} ${webserver.group} - -"
+
"d ${stateDir hostName}/cache 0750 ${user} ${webserver.group} - -"
+
"d ${stateDir hostName}/index 0750 ${user} ${webserver.group} - -"
+
"d ${stateDir hostName}/locks 0750 ${user} ${webserver.group} - -"
+
"d ${stateDir hostName}/media 0750 ${user} ${webserver.group} - -"
+
"d ${stateDir hostName}/media_attic 0750 ${user} ${webserver.group} - -"
+
"d ${stateDir hostName}/media_meta 0750 ${user} ${webserver.group} - -"
+
"d ${stateDir hostName}/meta 0750 ${user} ${webserver.group} - -"
+
"d ${stateDir hostName}/pages 0750 ${user} ${webserver.group} - -"
+
"d ${stateDir hostName}/tmp 0750 ${user} ${webserver.group} - -"
+
] ++ lib.optional (cfg.aclFile != null) "C ${cfg.aclFile} 0640 ${user} ${webserver.group} - ${pkg hostName cfg}/share/dokuwiki/conf/acl.auth.php.dist"
+
++ lib.optional (cfg.usersFile != null) "C ${cfg.usersFile} 0640 ${user} ${webserver.group} - ${pkg hostName cfg}/share/dokuwiki/conf/users.auth.php.dist"
+
) eachSite);
+
+
users.users.${user} = {
+
group = webserver.group;
+
isSystemUser = true;
+
};
+
}
+
(mkIf (cfg.webserver == "nginx") {
services.nginx = {
enable = true;
-
virtualHosts = mapAttrs (hostName: cfg: mkMerge [ cfg.nginx {
-
root = mkForce "${pkg hostName cfg}/share/dokuwiki";
-
extraConfig = lib.optionalString (cfg.nginx.addSSL || cfg.nginx.forceSSL || cfg.nginx.onlySSL || cfg.nginx.enableACME) "fastcgi_param HTTPS on;";
+
virtualHosts = mapAttrs (hostName: cfg: {
+
serverName = mkDefault hostName;
+
root = "${pkg hostName cfg}/share/dokuwiki";
-
locations."~ /(conf/|bin/|inc/|install.php)" = {
-
extraConfig = "deny all;";
-
};
+
locations = {
+
"~ /(conf/|bin/|inc/|install.php)" = {
+
extraConfig = "deny all;";
+
};
-
locations."~ ^/data/" = {
-
root = "${cfg.stateDir}";
-
extraConfig = "internal;";
-
};
+
"~ ^/data/" = {
+
root = "${stateDir hostName}";
+
extraConfig = "internal;";
+
};
-
locations."~ ^/lib.*\\.(js|css|gif|png|ico|jpg|jpeg)$" = {
-
extraConfig = "expires 365d;";
-
};
+
"~ ^/lib.*\.(js|css|gif|png|ico|jpg|jpeg)$" = {
+
extraConfig = "expires 365d;";
+
};
-
locations."/" = {
-
priority = 1;
-
index = "doku.php";
-
extraConfig = "try_files $uri $uri/ @dokuwiki;";
-
};
+
"/" = {
+
priority = 1;
+
index = "doku.php";
+
extraConfig = ''try_files $uri $uri/ @dokuwiki;'';
+
};
-
locations."@dokuwiki" = {
-
extraConfig = ''
+
"@dokuwiki" = {
+
extraConfig = ''
# rewrites "doku.php/" out of the URLs if you set the userwrite setting to .htaccess in dokuwiki config page
rewrite ^/_media/(.*) /lib/exe/fetch.php?media=$1 last;
rewrite ^/_detail/(.*) /lib/exe/detail.php?media=$1 last;
rewrite ^/_export/([^/]+)/(.*) /doku.php?do=export_$1&id=$2 last;
rewrite ^/(.*) /doku.php?id=$1&$args last;
-
'';
-
};
+
'';
+
};
-
locations."~ \\.php$" = {
-
extraConfig = ''
+
"~ \\.php$" = {
+
extraConfig = ''
try_files $uri $uri/ /doku.php;
include ${pkgs.nginx}/conf/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param REDIRECT_STATUS 200;
fastcgi_pass unix:${config.services.phpfpm.pools."dokuwiki-${hostName}".socket};
-
${lib.optionalString (cfg.nginx.addSSL || cfg.nginx.forceSSL || cfg.nginx.onlySSL || cfg.nginx.enableACME) "fastcgi_param HTTPS on;"}
-
'';
+
'';
+
};
+
};
-
}]) eachSite;
+
}) eachSite;
};
+
})
-
systemd.tmpfiles.rules = flatten (mapAttrsToList (hostName: cfg: [
-
"d ${cfg.stateDir}/attic 0750 ${user} ${group} - -"
-
"d ${cfg.stateDir}/cache 0750 ${user} ${group} - -"
-
"d ${cfg.stateDir}/index 0750 ${user} ${group} - -"
-
"d ${cfg.stateDir}/locks 0750 ${user} ${group} - -"
-
"d ${cfg.stateDir}/media 0750 ${user} ${group} - -"
-
"d ${cfg.stateDir}/media_attic 0750 ${user} ${group} - -"
-
"d ${cfg.stateDir}/media_meta 0750 ${user} ${group} - -"
-
"d ${cfg.stateDir}/meta 0750 ${user} ${group} - -"
-
"d ${cfg.stateDir}/pages 0750 ${user} ${group} - -"
-
"d ${cfg.stateDir}/tmp 0750 ${user} ${group} - -"
-
] ++ lib.optional (cfg.aclFile != null) "C ${cfg.aclFile} 0640 ${user} ${group} - ${pkg hostName cfg}/share/dokuwiki/conf/acl.auth.php.dist"
-
++ lib.optional (cfg.usersFile != null) "C ${cfg.usersFile} 0640 ${user} ${group} - ${pkg hostName cfg}/share/dokuwiki/conf/users.auth.php.dist"
-
) eachSite);
+
(mkIf (cfg.webserver == "caddy") {
+
services.caddy = {
+
enable = true;
+
virtualHosts = mapAttrs' (hostName: cfg: (
+
nameValuePair "http://${hostName}" {
+
extraConfig = ''
+
root * ${pkg hostName cfg}/share/dokuwiki
+
file_server
-
users.users.${user} = {
-
group = group;
-
isSystemUser = true;
+
encode zstd gzip
+
php_fastcgi unix/${config.services.phpfpm.pools."dokuwiki-${hostName}".socket}
+
+
@restrict_files {
+
path /data/* /conf/* /bin/* /inc/* /vendor/* /install.php
+
}
+
+
respond @restrict_files 404
+
+
@allow_media {
+
path_regexp path ^/_media/(.*)$
+
}
+
rewrite @allow_media /lib/exe/fetch.php?media=/{http.regexp.path.1}
+
+
@allow_detail {
+
path /_detail*
+
}
+
rewrite @allow_detail /lib/exe/detail.php?media={path}
+
+
@allow_export {
+
path /_export*
+
path_regexp export /([^/]+)/(.*)
+
}
+
rewrite @allow_export /doku.php?do=export_{http.regexp.export.1}&id={http.regexp.export.2}
+
+
try_files {path} {path}/ /doku.php?id={path}&{query}
+
'';
+
}
+
)) eachSite;
};
-
};
+
})
-
meta.maintainers = with maintainers; [ _1000101 ];
+
]);
+
meta.maintainers = with maintainers; [
+
_1000101
+
onny
+
];
}
+60 -25
nixos/tests/dokuwiki.nix
···
in {
name = "dokuwiki";
meta = with pkgs.lib; {
-
maintainers = with maintainers; [ _1000101 ];
+
maintainers = with maintainers; [
+
_1000101
+
onny
+
];
};
-
machine = { ... }: {
-
services.dokuwiki."site1.local" = {
-
aclUse = false;
-
superUser = "admin";
+
+
nodes = {
+
dokuwiki_nginx = {...}: {
+
services.dokuwiki = {
+
sites = {
+
"site1.local" = {
+
aclUse = false;
+
superUser = "admin";
+
};
+
"site2.local" = {
+
usersFile = "/var/lib/dokuwiki/site2.local/users.auth.php";
+
superUser = "admin";
+
templates = [ template-bootstrap3 ];
+
plugins = [ plugin-icalevents ];
+
};
+
};
+
};
+
+
networking.firewall.allowedTCPPorts = [ 80 ];
+
networking.hosts."127.0.0.1" = [ "site1.local" "site2.local" ];
};
-
services.dokuwiki."site2.local" = {
-
usersFile = "/var/lib/dokuwiki/site2.local/users.auth.php";
-
superUser = "admin";
-
templates = [ template-bootstrap3 ];
-
plugins = [ plugin-icalevents ];
+
+
dokuwiki_caddy = {...}: {
+
services.dokuwiki = {
+
webserver = "caddy";
+
sites = {
+
"site1.local" = {
+
aclUse = false;
+
superUser = "admin";
+
};
+
"site2.local" = {
+
usersFile = "/var/lib/dokuwiki/site2.local/users.auth.php";
+
superUser = "admin";
+
templates = [ template-bootstrap3 ];
+
plugins = [ plugin-icalevents ];
+
};
+
};
+
};
+
+
networking.firewall.allowedTCPPorts = [ 80 ];
+
networking.hosts."127.0.0.1" = [ "site1.local" "site2.local" ];
};
-
networking.hosts."127.0.0.1" = [ "site1.local" "site2.local" ];
+
};
testScript = ''
-
site_names = ["site1.local", "site2.local"]
start_all()
-
machine.wait_for_unit("phpfpm-dokuwiki-site1.local.service")
-
machine.wait_for_unit("phpfpm-dokuwiki-site2.local.service")
+
dokuwiki_nginx.wait_for_unit("nginx")
+
dokuwiki_caddy.wait_for_unit("caddy")
-
machine.wait_for_unit("nginx.service")
+
site_names = ["site1.local", "site2.local"]
-
machine.wait_for_open_port(80)
+
for machine in (dokuwiki_nginx, dokuwiki_caddy):
+
for site_name in site_names:
+
machine.wait_for_unit(f"phpfpm-dokuwiki-{site_name}")
-
machine.succeed("curl -sSfL http://site1.local/ | grep 'DokuWiki'")
-
machine.fail("curl -sSfL 'http://site1.local/doku.php?do=login' | grep 'Login'")
+
machine.succeed("curl -sSfL http://site1.local/ | grep 'DokuWiki'")
+
machine.fail("curl -sSfL 'http://site1.local/doku.php?do=login' | grep 'Login'")
-
machine.succeed("curl -sSfL http://site2.local/ | grep 'DokuWiki'")
-
machine.succeed("curl -sSfL 'http://site2.local/doku.php?do=login' | grep 'Login'")
+
machine.succeed("curl -sSfL http://site2.local/ | grep 'DokuWiki'")
+
machine.succeed("curl -sSfL 'http://site2.local/doku.php?do=login' | grep 'Login'")
-
machine.succeed(
-
"echo 'admin:$2y$10$ijdBQMzSVV20SrKtCna8gue36vnsbVm2wItAXvdm876sshI4uwy6S:Admin:admin@example.test:user' >> /var/lib/dokuwiki/site2.local/users.auth.php",
-
"curl -sSfL -d 'u=admin&p=password' --cookie-jar cjar 'http://site2.local/doku.php?do=login'",
-
"curl -sSfL --cookie cjar --cookie-jar cjar 'http://site2.local/doku.php?do=login' | grep 'Logged in as: <bdi>Admin</bdi>'",
-
)
+
machine.succeed(
+
"echo 'admin:$2y$10$ijdBQMzSVV20SrKtCna8gue36vnsbVm2wItAXvdm876sshI4uwy6S:Admin:admin@example.test:user' >> /var/lib/dokuwiki/site2.local/users.auth.php",
+
"curl -sSfL -d 'u=admin&p=password' --cookie-jar cjar 'http://site2.local/doku.php?do=login'",
+
"curl -sSfL --cookie cjar --cookie-jar cjar 'http://site2.local/doku.php?do=login' | grep 'Logged in as: <bdi>Admin</bdi>'",
+
)
'';
})