1{ lib, pkgs, config, ... }:
2
3with lib;
4
5let
6 cfg = config.services.wiki-js;
7
8 format = pkgs.formats.json { };
9
10 configFile = format.generate "wiki-js.yml" cfg.settings;
11in {
12 options.services.wiki-js = {
13 enable = mkEnableOption "wiki-js";
14
15 environmentFile = mkOption {
16 type = types.nullOr types.path;
17 default = null;
18 example = "/root/wiki-js.env";
19 description = ''
20 Environment fiel to inject e.g. secrets into the configuration.
21 '';
22 };
23
24 stateDirectoryName = mkOption {
25 default = "wiki-js";
26 type = types.str;
27 description = ''
28 Name of the directory in <filename>/var/lib</filename>.
29 '';
30 };
31
32 settings = mkOption {
33 default = {};
34 type = types.submodule {
35 freeformType = format.type;
36 options = {
37 port = mkOption {
38 type = types.port;
39 default = 3000;
40 description = ''
41 TCP port the process should listen to.
42 '';
43 };
44
45 bindIP = mkOption {
46 default = "0.0.0.0";
47 type = types.str;
48 description = ''
49 IPs the service should listen to.
50 '';
51 };
52
53 db = {
54 type = mkOption {
55 default = "postgres";
56 type = types.enum [ "postgres" "mysql" "mariadb" "mssql" ];
57 description = ''
58 Database driver to use for persistence. Please note that <literal>sqlite</literal>
59 is currently not supported as the build process for it is currently not implemented
60 in <package>pkgs.wiki-js</package> and it's not recommended by upstream for
61 production use.
62 '';
63 };
64 host = mkOption {
65 type = types.str;
66 example = "/run/postgresql";
67 description = ''
68 Hostname or socket-path to connect to.
69 '';
70 };
71 db = mkOption {
72 default = "wiki";
73 type = types.str;
74 description = ''
75 Name of the database to use.
76 '';
77 };
78 };
79
80 logLevel = mkOption {
81 default = "info";
82 type = types.enum [ "error" "warn" "info" "verbose" "debug" "silly" ];
83 description = ''
84 Define how much detail is supposed to be logged at runtime.
85 '';
86 };
87
88 offline = mkEnableOption "offline mode" // {
89 description = ''
90 Disable latest file updates and enable
91 <link xlink:href="https://docs.requarks.io/install/sideload">sideloading</link>.
92 '';
93 };
94 };
95 };
96 description = ''
97 Settings to configure <package>wiki-js</package>. This directly
98 corresponds to <link xlink:href="https://docs.requarks.io/install/config">the upstream
99 configuration options</link>.
100
101 Secrets can be injected via the environment by
102 <itemizedlist>
103 <listitem><para>specifying <xref linkend="opt-services.wiki-js.environmentFile" />
104 to contain secrets</para></listitem>
105 <listitem><para>and setting sensitive values to <literal>$(ENVIRONMENT_VAR)</literal>
106 with this value defined in the environment-file.</para></listitem>
107 </itemizedlist>
108 '';
109 };
110 };
111
112 config = mkIf cfg.enable {
113 services.wiki-js.settings.dataPath = "/var/lib/${cfg.stateDirectoryName}";
114 systemd.services.wiki-js = {
115 description = "A modern and powerful wiki app built on Node.js";
116 documentation = [ "https://docs.requarks.io/" ];
117 wantedBy = [ "multi-user.target" ];
118
119 path = with pkgs; [ coreutils ];
120 preStart = ''
121 ln -sf ${configFile} /var/lib/${cfg.stateDirectoryName}/config.yml
122 ln -sf ${pkgs.wiki-js}/server /var/lib/${cfg.stateDirectoryName}
123 ln -sf ${pkgs.wiki-js}/assets /var/lib/${cfg.stateDirectoryName}
124 ln -sf ${pkgs.wiki-js}/package.json /var/lib/${cfg.stateDirectoryName}/package.json
125 '';
126
127 serviceConfig = {
128 EnvironmentFile = mkIf (cfg.environmentFile != null) cfg.environmentFile;
129 StateDirectory = cfg.stateDirectoryName;
130 WorkingDirectory = "/var/lib/${cfg.stateDirectoryName}";
131 DynamicUser = true;
132 PrivateTmp = true;
133 ExecStart = "${pkgs.nodejs}/bin/node ${pkgs.wiki-js}/server";
134 };
135 };
136 };
137
138 meta.maintainers = with maintainers; [ ma27 ];
139}