diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 8e373550bb3..93415408e71 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -797,6 +797,7 @@
./services/web-apps/codimd.nix
./services/web-apps/cryptpad.nix
./services/web-apps/documize.nix
+ ./services/web-apps/dokuwiki.nix
./services/web-apps/frab.nix
./services/web-apps/gotify-server.nix
./services/web-apps/icingaweb2/icingaweb2.nix
diff --git a/nixos/modules/services/web-apps/dokuwiki.nix b/nixos/modules/services/web-apps/dokuwiki.nix
new file mode 100644
index 00000000000..07af7aa0dfe
--- /dev/null
+++ b/nixos/modules/services/web-apps/dokuwiki.nix
@@ -0,0 +1,272 @@
+{ config, lib, pkgs, ... }:
+
+let
+
+ inherit (lib) mkEnableOption mkForce mkIf mkMerge mkOption optionalAttrs recursiveUpdate types;
+
+ cfg = config.services.dokuwiki;
+
+ user = config.services.nginx.user;
+ group = config.services.nginx.group;
+
+ dokuwikiAclAuthConfig = pkgs.writeText "acl.auth.php" ''
+ # acl.auth.php
+ #
+ #
+ # Access Control Lists
+ #
+ ${toString cfg.acl}
+ '';
+
+ dokuwikiLocalConfig = pkgs.writeText "local.php" ''
+
+ Mutually exclusive with services.dokuwiki.aclFile
+ Set this to a value other than null to take precedence over aclFile option.
+ '';
+ };
+
+ aclFile = mkOption {
+ type = types.nullOr types.path;
+ default = 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 for further instructions.
+ Example:
+ '';
+ };
+
+ 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.
+ '';
+ };
+
+ 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.
+ '';
+ };
+
+ 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 for further instructions.
+ '';
+ };
+
+ usersFile = mkOption {
+ type = types.nullOr types.path;
+ default = 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:
+ '';
+ };
+
+ extraConfig = mkOption {
+ type = types.nullOr types.lines;
+ default = null;
+ example = ''
+ $conf['title'] = 'My Wiki';
+ $conf['userewrite'] = 1;
+ '';
+ description = ''
+ DokuWiki configuration. Refer to
+
+ for details on supported values.
+ '';
+ };
+
+ 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 php-fpm.conf
+ for details on configuration directives.
+ '';
+ };
+
+ nginx = mkOption {
+ type = types.submodule (
+ recursiveUpdate
+ (import ../web-servers/nginx/vhost-options.nix { inherit config lib; })
+ {
+ # Enable encryption by default,
+ options.forceSSL.default = true;
+ options.enableACME.default = true;
+ }
+ );
+ default = {forceSSL = true; enableACME = true;};
+ example = {
+ serverAliases = [
+ "wiki.\${config.networking.domain}"
+ ];
+ enableACME = false;
+ };
+ description = ''
+ With this option, you can customize the nginx virtualHost which already has sensible defaults for DokuWiki.
+ '';
+ };
+ };
+
+ # implementation
+
+ config = mkIf cfg.enable {
+
+ warnings = mkIf (cfg.superUser == null) ["Not setting services.dokuwiki.superUser will impair your ability to administer DokuWiki"];
+
+ assertions = [
+ {
+ assertion = cfg.aclUse -> (cfg.acl != null || cfg.aclFile != null);
+ message = "Either services.dokuwiki.acl or services.dokuwiki.aclFile is mandatory when aclUse is true";
+ }
+ {
+ assertion = cfg.usersFile != null -> cfg.aclUse != false;
+ message = "services.dokuwiki.aclUse must be true when usersFile is not null";
+ }
+ ];
+
+ services.phpfpm.pools.dokuwiki = {
+ inherit user;
+ inherit group;
+ phpEnv = {
+ DOKUWIKI_LOCAL_CONFIG = "${dokuwikiLocalConfig}";
+ DOKUWIKI_PLUGINS_LOCAL_CONFIG = "${dokuwikiPluginsLocalConfig}";
+ } //optionalAttrs (cfg.usersFile != null) {
+ DOKUWIKI_USERS_AUTH_CONFIG = "${cfg.usersFile}";
+ } //optionalAttrs (cfg.aclUse) {
+ DOKUWIKI_ACL_AUTH_CONFIG = if (cfg.acl != null) then "${dokuwikiAclAuthConfig}" else "${toString cfg.aclFile}";
+ };
+
+ settings = {
+ "listen.mode" = "0660";
+ "listen.owner" = user;
+ "listen.group" = group;
+ } // cfg.poolConfig;
+ };
+
+ services.nginx = {
+ enable = true;
+
+ virtualHosts = {
+ ${cfg.hostName} = mkMerge [ cfg.nginx {
+ root = mkForce "${pkgs.dokuwiki}/share/dokuwiki/";
+ extraConfig = "fastcgi_param HTTPS on;";
+
+ locations."~ /(conf/|bin/|inc/|install.php)" = {
+ extraConfig = "deny all;";
+ };
+
+ locations."~ ^/data/" = {
+ root = "${cfg.stateDir}";
+ extraConfig = "internal;";
+ };
+
+ locations."~ ^/lib.*\.(js|css|gif|png|ico|jpg|jpeg)$" = {
+ extraConfig = "expires 365d;";
+ };
+
+ locations."/" = {
+ priority = 1;
+ index = "doku.php";
+ extraConfig = ''try_files $uri $uri/ @dokuwiki;'';
+ };
+
+ locations."@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 = ''
+ 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.socket};
+ fastcgi_param HTTPS on;
+ '';
+ };
+ }];
+ };
+
+ };
+
+ systemd.tmpfiles.rules = [
+ "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} - -"
+ ];
+
+ };
+}
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 35a02d2e283..542d5c61d27 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -71,6 +71,7 @@ in
docker-tools = handleTestOn ["x86_64-linux"] ./docker-tools.nix {};
docker-tools-overlay = handleTestOn ["x86_64-linux"] ./docker-tools-overlay.nix {};
documize = handleTest ./documize.nix {};
+ dokuwiki = handleTest ./dokuwiki.nix {};
dovecot = handleTest ./dovecot.nix {};
# ec2-config doesn't work in a sandbox as the simulated ec2 instance needs network access
#ec2-config = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-config or {};
diff --git a/nixos/tests/dokuwiki.nix b/nixos/tests/dokuwiki.nix
new file mode 100644
index 00000000000..38bde10f47e
--- /dev/null
+++ b/nixos/tests/dokuwiki.nix
@@ -0,0 +1,29 @@
+import ./make-test-python.nix ({ lib, ... }:
+
+with lib;
+
+{
+ name = "dokuwiki";
+ meta.maintainers = with maintainers; [ maintainers."1000101" ];
+
+ nodes.machine =
+ { pkgs, ... }:
+ { services.dokuwiki = {
+ enable = true;
+ acl = " ";
+ superUser = null;
+ nginx = {
+ forceSSL = false;
+ enableACME = false;
+ };
+ };
+ };
+
+ testScript = ''
+ machine.start()
+ machine.wait_for_unit("phpfpm-dokuwiki.service")
+ machine.wait_for_unit("nginx.service")
+ machine.wait_for_open_port(80)
+ machine.succeed("curl -sSfL http://localhost/ | grep 'DokuWiki'")
+ '';
+})
diff --git a/pkgs/servers/web-apps/dokuwiki/default.nix b/pkgs/servers/web-apps/dokuwiki/default.nix
index ff6fa982228..f12a75c8e18 100644
--- a/pkgs/servers/web-apps/dokuwiki/default.nix
+++ b/pkgs/servers/web-apps/dokuwiki/default.nix
@@ -1,4 +1,4 @@
-{ stdenv, fetchFromGitHub }:
+{ stdenv, fetchFromGitHub, writeText }:
stdenv.mkDerivation rec {
pname = "dokuwiki";
@@ -11,9 +11,38 @@ stdenv.mkDerivation rec {
sha256 = "1na5pn4j4mi2la80ywzg1krwqdxz57mjkw0id6ga9rws809gkdjp";
};
+ preload = writeText "preload.php" ''
+ array(
+ 'default' => getenv('DOKUWIKI_ACL_AUTH_CONFIG'),
+ ),
+ 'plainauth.users' => array(
+ 'default' => getenv('DOKUWIKI_USERS_AUTH_CONFIG'),
+ 'protected' => "" // not used by default
+ ),
+ );
+ '';
+
+ phpLocalConfig = writeText "local.php" ''
+
+ '';
+
+ phpPluginsLocalConfig = writeText "plugins.local.php" ''
+
+ '';
+
installPhase = ''
mkdir -p $out/share/dokuwiki
cp -r * $out/share/dokuwiki
+ cp ${preload} $out/share/dokuwiki/inc/preload.php
+ cp ${phpLocalConfig} $out/share/dokuwiki/conf/local.php
+ cp ${phpPluginsLocalConfig} $out/share/dokuwiki/conf/plugins.local.php
'';
meta = with stdenv.lib; {