···17 if correct_tags then
18 -- docutils supports alphanumeric strings separated by [-._:]
19 -- We are slightly more liberal for simplicity.
20- local role = first.text:match('^{([-._+:%w]+)}$')
21- if role ~= nil then
22- inlines:remove(i)
000000023 second.attributes['role'] = role
24 second.classes:insert('interpreted-text')
25 end
···17 if correct_tags then
18 -- docutils supports alphanumeric strings separated by [-._:]
19 -- We are slightly more liberal for simplicity.
20+ -- Allow preceding punctuation (eg '('), otherwise '({file}`...`)'
21+ -- does not match. Also allow anything followed by a non-breaking space
22+ -- since pandoc emits those after certain abbreviations (e.g. e.g.).
23+ local prefix, role = first.text:match('^(.*){([-._+:%w]+)}$')
24+ if role ~= nil and (prefix == '' or prefix:match("^.*[%p ]$") ~= nil) then
25+ if prefix == '' then
26+ inlines:remove(i)
27+ else
28+ first.text = prefix
29+ end
30 second.attributes['role'] = role
31 second.classes:insert('interpreted-text')
32 end
···40 $ nix-build nixos/release.nix -A manual.x86_64-linux
41 ```
420000000000000000000043- `buildDocsInSandbox` indicates whether the option documentation for the
44 module can be built in a derivation sandbox. This option is currently only
45 honored for modules shipped by nixpkgs. User modules and modules taken from
···40 $ nix-build nixos/release.nix -A manual.x86_64-linux
41 ```
4243+ This file should *not* usually be written by hand. Instead it is preferred
44+ to write documentation using CommonMark and converting it to CommonMark
45+ using pandoc. The simplest documentation can be converted using just
46+47+ ```ShellSession
48+ $ pandoc doc.md -t docbook --top-level-division=chapter -f markdown+smart > doc.xml
49+ ```
50+51+ More elaborate documentation may wish to add one or more of the pandoc
52+ filters used to build the remainder of the manual, for example the GNOME
53+ desktop uses
54+55+ ```ShellSession
56+ $ pandoc gnome.md -t docbook --top-level-division=chapter \
57+ --extract-media=media -f markdown+smart \
58+ --lua-filter ../../../../../doc/build-aux/pandoc-filters/myst-reader/roles.lua \
59+ --lua-filter ../../../../../doc/build-aux/pandoc-filters/docbook-writer/rst-roles.lua \
60+ > gnome.xml
61+ ```
62+63- `buildDocsInSandbox` indicates whether the option documentation for the
64 module can be built in a derivation sandbox. This option is currently only
65 honored for modules shipped by nixpkgs. User modules and modules taken from
···51 <programlisting>
52$ nix-build nixos/release.nix -A manual.x86_64-linux
53</programlisting>
54+ <para>
55+ This file should <emphasis>not</emphasis> usually be written by
56+ hand. Instead it is preferred to write documentation using
57+ CommonMark and converting it to CommonMark using pandoc. The
58+ simplest documentation can be converted using just
59+ </para>
60+ <programlisting>
61+$ pandoc doc.md -t docbook --top-level-division=chapter -f markdown+smart > doc.xml
62+</programlisting>
63+ <para>
64+ More elaborate documentation may wish to add one or more of the
65+ pandoc filters used to build the remainder of the manual, for
66+ example the GNOME desktop uses
67+ </para>
68+ <programlisting>
69+$ pandoc gnome.md -t docbook --top-level-division=chapter \
70+ --extract-media=media -f markdown+smart \
71+ --lua-filter ../../../../../doc/build-aux/pandoc-filters/myst-reader/roles.lua \
72+ --lua-filter ../../../../../doc/build-aux/pandoc-filters/docbook-writer/rst-roles.lua \
73+ > gnome.xml
74+</programlisting>
75 </listitem>
76 <listitem>
77 <para>
···50done
5152popd
53+54+# now handle module chapters. we'll need extra checks to ensure that we don't process
55+# markdown files we're not interested in, so we'll require an x.nix file for ever x.md
56+# that we'll convert to xml.
57+pushd "$DIR/../../modules"
58+59+mapfile -t MD_FILES < <(find . -type f -regex '.*\.md$')
60+61+for mf in ${MD_FILES[*]}; do
62+ [ -f "${mf%.md}.nix" ] || continue
63+64+ pandoc --top-level-division=chapter "$mf" "${pandoc_flags[@]}" -o "${mf%.md}.xml"
65+ sed -i -e '1 i <!-- Do not edit this file directly, edit its companion .md instead\
66+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->' \
67+ "${mf%.md}.xml"
68+done
69+70+popd
···1+# Input Methods {#module-services-input-methods}
2+3+Input methods are an operating system component that allows any data, such as
4+keyboard strokes or mouse movements, to be received as input. In this way
5+users can enter characters and symbols not found on their input devices.
6+Using an input method is obligatory for any language that has more graphemes
7+than there are keys on the keyboard.
8+9+The following input methods are available in NixOS:
10+11+ - IBus: The intelligent input bus.
12+ - Fcitx: A customizable lightweight input method.
13+ - Nabi: A Korean input method based on XIM.
14+ - Uim: The universal input method, is a library with a XIM bridge.
15+ - Hime: An extremely easy-to-use input method framework.
16+ - Kime: Korean IME
17+18+## IBus {#module-services-input-methods-ibus}
19+20+IBus is an Intelligent Input Bus. It provides full featured and user
21+friendly input method user interface.
22+23+The following snippet can be used to configure IBus:
24+25+```
26+i18n.inputMethod = {
27+ enabled = "ibus";
28+ ibus.engines = with pkgs.ibus-engines; [ anthy hangul mozc ];
29+};
30+```
31+32+`i18n.inputMethod.ibus.engines` is optional and can be used
33+to add extra IBus engines.
34+35+Available extra IBus engines are:
36+37+ - Anthy (`ibus-engines.anthy`): Anthy is a system for
38+ Japanese input method. It converts Hiragana text to Kana Kanji mixed text.
39+ - Hangul (`ibus-engines.hangul`): Korean input method.
40+ - m17n (`ibus-engines.m17n`): m17n is an input method that
41+ uses input methods and corresponding icons in the m17n database.
42+ - mozc (`ibus-engines.mozc`): A Japanese input method from
43+ Google.
44+ - Table (`ibus-engines.table`): An input method that load
45+ tables of input methods.
46+ - table-others (`ibus-engines.table-others`): Various
47+ table-based input methods. To use this, and any other table-based input
48+ methods, it must appear in the list of engines along with
49+ `table`. For example:
50+51+ ```
52+ ibus.engines = with pkgs.ibus-engines; [ table table-others ];
53+ ```
54+55+To use any input method, the package must be added in the configuration, as
56+shown above, and also (after running `nixos-rebuild`) the
57+input method must be added from IBus' preference dialog.
58+59+### Troubleshooting {#module-services-input-methods-troubleshooting}
60+61+If IBus works in some applications but not others, a likely cause of this
62+is that IBus is depending on a different version of `glib`
63+to what the applications are depending on. This can be checked by running
64+`nix-store -q --requisites <path> | grep glib`,
65+where `<path>` is the path of either IBus or an
66+application in the Nix store. The `glib` packages must
67+match exactly. If they do not, uninstalling and reinstalling the
68+application is a likely fix.
69+70+## Fcitx {#module-services-input-methods-fcitx}
71+72+Fcitx is an input method framework with extension support. It has three
73+built-in Input Method Engine, Pinyin, QuWei and Table-based input methods.
74+75+The following snippet can be used to configure Fcitx:
76+77+```
78+i18n.inputMethod = {
79+ enabled = "fcitx";
80+ fcitx.engines = with pkgs.fcitx-engines; [ mozc hangul m17n ];
81+};
82+```
83+84+`i18n.inputMethod.fcitx.engines` is optional and can be
85+used to add extra Fcitx engines.
86+87+Available extra Fcitx engines are:
88+89+ - Anthy (`fcitx-engines.anthy`): Anthy is a system for
90+ Japanese input method. It converts Hiragana text to Kana Kanji mixed text.
91+ - Chewing (`fcitx-engines.chewing`): Chewing is an
92+ intelligent Zhuyin input method. It is one of the most popular input
93+ methods among Traditional Chinese Unix users.
94+ - Hangul (`fcitx-engines.hangul`): Korean input method.
95+ - Unikey (`fcitx-engines.unikey`): Vietnamese input method.
96+ - m17n (`fcitx-engines.m17n`): m17n is an input method that
97+ uses input methods and corresponding icons in the m17n database.
98+ - mozc (`fcitx-engines.mozc`): A Japanese input method from
99+ Google.
100+ - table-others (`fcitx-engines.table-others`): Various
101+ table-based input methods.
102+103+## Nabi {#module-services-input-methods-nabi}
104+105+Nabi is an easy to use Korean X input method. It allows you to enter
106+phonetic Korean characters (hangul) and pictographic Korean characters
107+(hanja).
108+109+The following snippet can be used to configure Nabi:
110+111+```
112+i18n.inputMethod = {
113+ enabled = "nabi";
114+};
115+```
116+117+## Uim {#module-services-input-methods-uim}
118+119+Uim (short for "universal input method") is a multilingual input method
120+framework. Applications can use it through so-called bridges.
121+122+The following snippet can be used to configure uim:
123+124+```
125+i18n.inputMethod = {
126+ enabled = "uim";
127+};
128+```
129+130+Note: The [](#opt-i18n.inputMethod.uim.toolbar) option can be
131+used to choose uim toolbar.
132+133+## Hime {#module-services-input-methods-hime}
134+135+Hime is an extremely easy-to-use input method framework. It is lightweight,
136+stable, powerful and supports many commonly used input methods, including
137+Cangjie, Zhuyin, Dayi, Rank, Shrimp, Greek, Korean Pinyin, Latin Alphabet,
138+etc...
139+140+The following snippet can be used to configure Hime:
141+142+```
143+i18n.inputMethod = {
144+ enabled = "hime";
145+};
146+```
147+148+## Kime {#module-services-input-methods-kime}
149+150+Kime is Korean IME. it's built with Rust language and let you get simple, safe, fast Korean typing
151+152+The following snippet can be used to configure Kime:
153+154+```
155+i18n.inputMethod = {
156+ enabled = "kime";
157+};
158+```
+233-249
nixos/modules/i18n/input-method/default.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-input-methods">
6- <title>Input Methods</title>
7- <para>
8- Input methods are an operating system component that allows any data, such as
9- keyboard strokes or mouse movements, to be received as input. In this way
10- users can enter characters and symbols not found on their input devices.
11- Using an input method is obligatory for any language that has more graphemes
12- than there are keys on the keyboard.
13- </para>
14- <para>
15- The following input methods are available in NixOS:
16- </para>
17- <itemizedlist>
18- <listitem>
19- <para>
20- IBus: The intelligent input bus.
21- </para>
22- </listitem>
23- <listitem>
24- <para>
25- Fcitx: A customizable lightweight input method.
26- </para>
27- </listitem>
28- <listitem>
29- <para>
30- Nabi: A Korean input method based on XIM.
31- </para>
32- </listitem>
33- <listitem>
34- <para>
35- Uim: The universal input method, is a library with a XIM bridge.
36- </para>
37- </listitem>
38- <listitem>
39- <para>
40- Hime: An extremely easy-to-use input method framework.
41- </para>
42- </listitem>
43- <listitem>
44- <para>
45- Kime: Korean IME
46- </para>
47- </listitem>
48- </itemizedlist>
49- <section xml:id="module-services-input-methods-ibus">
50- <title>IBus</title>
51-52 <para>
53- IBus is an Intelligent Input Bus. It provides full featured and user
54- friendly input method user interface.
000055 </para>
56-57 <para>
58- The following snippet can be used to configure IBus:
59 </para>
60-61-<programlisting>
000000000000000000000000000000000000000062i18n.inputMethod = {
63- <link linkend="opt-i18n.inputMethod.enabled">enabled</link> = "ibus";
64- <link linkend="opt-i18n.inputMethod.ibus.engines">ibus.engines</link> = with pkgs.ibus-engines; [ anthy hangul mozc ];
65};
66</programlisting>
67-68- <para>
69- <literal>i18n.inputMethod.ibus.engines</literal> is optional and can be used
70- to add extra IBus engines.
71- </para>
72-73- <para>
74- Available extra IBus engines are:
75- </para>
76-77- <itemizedlist>
78- <listitem>
79 <para>
80- Anthy (<literal>ibus-engines.anthy</literal>): Anthy is a system for
81- Japanese input method. It converts Hiragana text to Kana Kanji mixed text.
82 </para>
83- </listitem>
84- <listitem>
85 <para>
86- Hangul (<literal>ibus-engines.hangul</literal>): Korean input method.
87- </para>
88- </listitem>
89- <listitem>
90- <para>
91- m17n (<literal>ibus-engines.m17n</literal>): m17n is an input method that
92- uses input methods and corresponding icons in the m17n database.
93 </para>
94- </listitem>
95- <listitem>
000000000000000000000000000000000000000000096 <para>
97- mozc (<literal>ibus-engines.mozc</literal>): A Japanese input method from
98- Google.
0099 </para>
100- </listitem>
101- <listitem>
000000000000000102 <para>
103- Table (<literal>ibus-engines.table</literal>): An input method that load
104- tables of input methods.
0105 </para>
106- </listitem>
107- <listitem>
108 <para>
109- table-others (<literal>ibus-engines.table-others</literal>): Various
110- table-based input methods. To use this, and any other table-based input
111- methods, it must appear in the list of engines along with
112- <literal>table</literal>. For example:
113-<programlisting>
114-ibus.engines = with pkgs.ibus-engines; [ table table-others ];
115-</programlisting>
116 </para>
117- </listitem>
118- </itemizedlist>
119-120- <para>
121- To use any input method, the package must be added in the configuration, as
122- shown above, and also (after running <literal>nixos-rebuild</literal>) the
123- input method must be added from IBus' preference dialog.
124- </para>
125-126- <simplesect xml:id="module-services-input-methods-troubleshooting">
127- <title>Troubleshooting</title>
128- <para>
129- If IBus works in some applications but not others, a likely cause of this
130- is that IBus is depending on a different version of <literal>glib</literal>
131- to what the applications are depending on. This can be checked by running
132- <literal>nix-store -q --requisites <path> | grep glib</literal>,
133- where <literal><path></literal> is the path of either IBus or an
134- application in the Nix store. The <literal>glib</literal> packages must
135- match exactly. If they do not, uninstalling and reinstalling the
136- application is a likely fix.
137- </para>
138- </simplesect>
139- </section>
140- <section xml:id="module-services-input-methods-fcitx">
141- <title>Fcitx</title>
142-143- <para>
144- Fcitx is an input method framework with extension support. It has three
145- built-in Input Method Engine, Pinyin, QuWei and Table-based input methods.
146- </para>
147-148- <para>
149- The following snippet can be used to configure Fcitx:
150- </para>
151-152-<programlisting>
153i18n.inputMethod = {
154- <link linkend="opt-i18n.inputMethod.enabled">enabled</link> = "fcitx";
155- <link linkend="opt-i18n.inputMethod.fcitx.engines">fcitx.engines</link> = with pkgs.fcitx-engines; [ mozc hangul m17n ];
156};
157</programlisting>
158-159- <para>
160- <literal>i18n.inputMethod.fcitx.engines</literal> is optional and can be
161- used to add extra Fcitx engines.
162- </para>
163-164- <para>
165- Available extra Fcitx engines are:
166- </para>
167-168- <itemizedlist>
169- <listitem>
170 <para>
171- Anthy (<literal>fcitx-engines.anthy</literal>): Anthy is a system for
172- Japanese input method. It converts Hiragana text to Kana Kanji mixed text.
173 </para>
174- </listitem>
175- <listitem>
176 <para>
177- Chewing (<literal>fcitx-engines.chewing</literal>): Chewing is an
178- intelligent Zhuyin input method. It is one of the most popular input
179- methods among Traditional Chinese Unix users.
180 </para>
181- </listitem>
182- <listitem>
000000000000000000000000000000000000000000000000183 <para>
184- Hangul (<literal>fcitx-engines.hangul</literal>): Korean input method.
00185 </para>
186- </listitem>
187- <listitem>
188 <para>
189- Unikey (<literal>fcitx-engines.unikey</literal>): Vietnamese input method.
190 </para>
191- </listitem>
192- <listitem>
000000193 <para>
194- m17n (<literal>fcitx-engines.m17n</literal>): m17n is an input method that
195- uses input methods and corresponding icons in the m17n database.
0196 </para>
197- </listitem>
198- <listitem>
199 <para>
200- mozc (<literal>fcitx-engines.mozc</literal>): A Japanese input method from
201- Google.
202 </para>
203- </listitem>
204- <listitem>
205- <para>
206- table-others (<literal>fcitx-engines.table-others</literal>): Various
207- table-based input methods.
208- </para>
209- </listitem>
210- </itemizedlist>
211- </section>
212- <section xml:id="module-services-input-methods-nabi">
213- <title>Nabi</title>
214-215- <para>
216- Nabi is an easy to use Korean X input method. It allows you to enter
217- phonetic Korean characters (hangul) and pictographic Korean characters
218- (hanja).
219- </para>
220-221- <para>
222- The following snippet can be used to configure Nabi:
223- </para>
224-225-<programlisting>
226-i18n.inputMethod = {
227- <link linkend="opt-i18n.inputMethod.enabled">enabled</link> = "nabi";
228-};
229-</programlisting>
230- </section>
231- <section xml:id="module-services-input-methods-uim">
232- <title>Uim</title>
233-234- <para>
235- Uim (short for "universal input method") is a multilingual input method
236- framework. Applications can use it through so-called bridges.
237- </para>
238-239- <para>
240- The following snippet can be used to configure uim:
241- </para>
242-243-<programlisting>
244i18n.inputMethod = {
245- <link linkend="opt-i18n.inputMethod.enabled">enabled</link> = "uim";
246};
247</programlisting>
248-249- <para>
250- Note: The <xref linkend="opt-i18n.inputMethod.uim.toolbar"/> option can be
251- used to choose uim toolbar.
252- </para>
253- </section>
254- <section xml:id="module-services-input-methods-hime">
255- <title>Hime</title>
256-257- <para>
258- Hime is an extremely easy-to-use input method framework. It is lightweight,
259- stable, powerful and supports many commonly used input methods, including
260- Cangjie, Zhuyin, Dayi, Rank, Shrimp, Greek, Korean Pinyin, Latin Alphabet,
261- etc...
262- </para>
263-264- <para>
265- The following snippet can be used to configure Hime:
266- </para>
267-268-<programlisting>
269i18n.inputMethod = {
270- <link linkend="opt-i18n.inputMethod.enabled">enabled</link> = "hime";
271};
272</programlisting>
273- </section>
274- <section xml:id="module-services-input-methods-kime">
275- <title>Kime</title>
276-277- <para>
278- Kime is Korean IME. it's built with Rust language and let you get simple, safe, fast Korean typing
279- </para>
280-281- <para>
282- The following snippet can be used to configure Kime:
283- </para>
284-285-<programlisting>
286i18n.inputMethod = {
287- <link linkend="opt-i18n.inputMethod.enabled">enabled</link> = "kime";
288};
289</programlisting>
290- </section>
291</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-input-methods">
4+ <title>Input Methods</title>
000000000000000000000000000000000000000000000005 <para>
6+ Input methods are an operating system component that allows any
7+ data, such as keyboard strokes or mouse movements, to be received as
8+ input. In this way users can enter characters and symbols not found
9+ on their input devices. Using an input method is obligatory for any
10+ language that has more graphemes than there are keys on the
11+ keyboard.
12 </para>
013 <para>
14+ The following input methods are available in NixOS:
15 </para>
16+ <itemizedlist spacing="compact">
17+ <listitem>
18+ <para>
19+ IBus: The intelligent input bus.
20+ </para>
21+ </listitem>
22+ <listitem>
23+ <para>
24+ Fcitx: A customizable lightweight input method.
25+ </para>
26+ </listitem>
27+ <listitem>
28+ <para>
29+ Nabi: A Korean input method based on XIM.
30+ </para>
31+ </listitem>
32+ <listitem>
33+ <para>
34+ Uim: The universal input method, is a library with a XIM bridge.
35+ </para>
36+ </listitem>
37+ <listitem>
38+ <para>
39+ Hime: An extremely easy-to-use input method framework.
40+ </para>
41+ </listitem>
42+ <listitem>
43+ <para>
44+ Kime: Korean IME
45+ </para>
46+ </listitem>
47+ </itemizedlist>
48+ <section xml:id="module-services-input-methods-ibus">
49+ <title>IBus</title>
50+ <para>
51+ IBus is an Intelligent Input Bus. It provides full featured and
52+ user friendly input method user interface.
53+ </para>
54+ <para>
55+ The following snippet can be used to configure IBus:
56+ </para>
57+ <programlisting>
58i18n.inputMethod = {
59+ enabled = "ibus";
60+ ibus.engines = with pkgs.ibus-engines; [ anthy hangul mozc ];
61};
62</programlisting>
00000000000063 <para>
64+ <literal>i18n.inputMethod.ibus.engines</literal> is optional and
65+ can be used to add extra IBus engines.
66 </para>
0067 <para>
68+ Available extra IBus engines are:
00000069 </para>
70+ <itemizedlist>
71+ <listitem>
72+ <para>
73+ Anthy (<literal>ibus-engines.anthy</literal>): Anthy is a
74+ system for Japanese input method. It converts Hiragana text to
75+ Kana Kanji mixed text.
76+ </para>
77+ </listitem>
78+ <listitem>
79+ <para>
80+ Hangul (<literal>ibus-engines.hangul</literal>): Korean input
81+ method.
82+ </para>
83+ </listitem>
84+ <listitem>
85+ <para>
86+ m17n (<literal>ibus-engines.m17n</literal>): m17n is an input
87+ method that uses input methods and corresponding icons in the
88+ m17n database.
89+ </para>
90+ </listitem>
91+ <listitem>
92+ <para>
93+ mozc (<literal>ibus-engines.mozc</literal>): A Japanese input
94+ method from Google.
95+ </para>
96+ </listitem>
97+ <listitem>
98+ <para>
99+ Table (<literal>ibus-engines.table</literal>): An input method
100+ that load tables of input methods.
101+ </para>
102+ </listitem>
103+ <listitem>
104+ <para>
105+ table-others (<literal>ibus-engines.table-others</literal>):
106+ Various table-based input methods. To use this, and any other
107+ table-based input methods, it must appear in the list of
108+ engines along with <literal>table</literal>. For example:
109+ </para>
110+ <programlisting>
111+ibus.engines = with pkgs.ibus-engines; [ table table-others ];
112+</programlisting>
113+ </listitem>
114+ </itemizedlist>
115 <para>
116+ To use any input method, the package must be added in the
117+ configuration, as shown above, and also (after running
118+ <literal>nixos-rebuild</literal>) the input method must be added
119+ from IBus’ preference dialog.
120 </para>
121+ <section xml:id="module-services-input-methods-troubleshooting">
122+ <title>Troubleshooting</title>
123+ <para>
124+ If IBus works in some applications but not others, a likely
125+ cause of this is that IBus is depending on a different version
126+ of <literal>glib</literal> to what the applications are
127+ depending on. This can be checked by running
128+ <literal>nix-store -q --requisites <path> | grep glib</literal>,
129+ where <literal><path></literal> is the path of either IBus
130+ or an application in the Nix store. The <literal>glib</literal>
131+ packages must match exactly. If they do not, uninstalling and
132+ reinstalling the application is a likely fix.
133+ </para>
134+ </section>
135+ </section>
136+ <section xml:id="module-services-input-methods-fcitx">
137+ <title>Fcitx</title>
138 <para>
139+ Fcitx is an input method framework with extension support. It has
140+ three built-in Input Method Engine, Pinyin, QuWei and Table-based
141+ input methods.
142 </para>
00143 <para>
144+ The following snippet can be used to configure Fcitx:
000000145 </para>
146+ <programlisting>
00000000000000000000000000000000000147i18n.inputMethod = {
148+ enabled = "fcitx";
149+ fcitx.engines = with pkgs.fcitx-engines; [ mozc hangul m17n ];
150};
151</programlisting>
000000000000152 <para>
153+ <literal>i18n.inputMethod.fcitx.engines</literal> is optional and
154+ can be used to add extra Fcitx engines.
155 </para>
00156 <para>
157+ Available extra Fcitx engines are:
00158 </para>
159+ <itemizedlist spacing="compact">
160+ <listitem>
161+ <para>
162+ Anthy (<literal>fcitx-engines.anthy</literal>): Anthy is a
163+ system for Japanese input method. It converts Hiragana text to
164+ Kana Kanji mixed text.
165+ </para>
166+ </listitem>
167+ <listitem>
168+ <para>
169+ Chewing (<literal>fcitx-engines.chewing</literal>): Chewing is
170+ an intelligent Zhuyin input method. It is one of the most
171+ popular input methods among Traditional Chinese Unix users.
172+ </para>
173+ </listitem>
174+ <listitem>
175+ <para>
176+ Hangul (<literal>fcitx-engines.hangul</literal>): Korean input
177+ method.
178+ </para>
179+ </listitem>
180+ <listitem>
181+ <para>
182+ Unikey (<literal>fcitx-engines.unikey</literal>): Vietnamese
183+ input method.
184+ </para>
185+ </listitem>
186+ <listitem>
187+ <para>
188+ m17n (<literal>fcitx-engines.m17n</literal>): m17n is an input
189+ method that uses input methods and corresponding icons in the
190+ m17n database.
191+ </para>
192+ </listitem>
193+ <listitem>
194+ <para>
195+ mozc (<literal>fcitx-engines.mozc</literal>): A Japanese input
196+ method from Google.
197+ </para>
198+ </listitem>
199+ <listitem>
200+ <para>
201+ table-others (<literal>fcitx-engines.table-others</literal>):
202+ Various table-based input methods.
203+ </para>
204+ </listitem>
205+ </itemizedlist>
206+ </section>
207+ <section xml:id="module-services-input-methods-nabi">
208+ <title>Nabi</title>
209 <para>
210+ Nabi is an easy to use Korean X input method. It allows you to
211+ enter phonetic Korean characters (hangul) and pictographic Korean
212+ characters (hanja).
213 </para>
00214 <para>
215+ The following snippet can be used to configure Nabi:
216 </para>
217+ <programlisting>
218+i18n.inputMethod = {
219+ enabled = "nabi";
220+};
221+</programlisting>
222+ </section>
223+ <section xml:id="module-services-input-methods-uim">
224+ <title>Uim</title>
225 <para>
226+ Uim (short for <quote>universal input method</quote>) is a
227+ multilingual input method framework. Applications can use it
228+ through so-called bridges.
229 </para>
00230 <para>
231+ The following snippet can be used to configure uim:
0232 </para>
233+ <programlisting>
0000000000000000000000000000000000000000234i18n.inputMethod = {
235+ enabled = "uim";
236};
237</programlisting>
238+ <para>
239+ Note: The <xref linkend="opt-i18n.inputMethod.uim.toolbar" />
240+ option can be used to choose uim toolbar.
241+ </para>
242+ </section>
243+ <section xml:id="module-services-input-methods-hime">
244+ <title>Hime</title>
245+ <para>
246+ Hime is an extremely easy-to-use input method framework. It is
247+ lightweight, stable, powerful and supports many commonly used
248+ input methods, including Cangjie, Zhuyin, Dayi, Rank, Shrimp,
249+ Greek, Korean Pinyin, Latin Alphabet, etc…
250+ </para>
251+ <para>
252+ The following snippet can be used to configure Hime:
253+ </para>
254+ <programlisting>
0000255i18n.inputMethod = {
256+ enabled = "hime";
257};
258</programlisting>
259+ </section>
260+ <section xml:id="module-services-input-methods-kime">
261+ <title>Kime</title>
262+ <para>
263+ Kime is Korean IME. it’s built with Rust language and let you get
264+ simple, safe, fast Korean typing
265+ </para>
266+ <para>
267+ The following snippet can be used to configure Kime:
268+ </para>
269+ <programlisting>
00270i18n.inputMethod = {
271+ enabled = "kime";
272};
273</programlisting>
274+ </section>
275</chapter>
···1+# Digital Bitbox {#module-programs-digitalbitbox}
2+3+Digital Bitbox is a hardware wallet and second-factor authenticator.
4+5+The `digitalbitbox` programs module may be installed by setting
6+`programs.digitalbitbox` to `true` in a manner similar to
7+```
8+programs.digitalbitbox.enable = true;
9+```
10+and bundles the `digitalbitbox` package (see [](#sec-digitalbitbox-package)),
11+which contains the `dbb-app` and `dbb-cli` binaries, along with the hardware
12+module (see [](#sec-digitalbitbox-hardware-module)) which sets up the necessary
13+udev rules to access the device.
14+15+Enabling the digitalbitbox module is pretty much the easiest way to get a
16+Digital Bitbox device working on your system.
17+18+For more information, see <https://digitalbitbox.com/start_linux>.
19+20+## Package {#sec-digitalbitbox-package}
21+22+The binaries, `dbb-app` (a GUI tool) and `dbb-cli` (a CLI tool), are available
23+through the `digitalbitbox` package which could be installed as follows:
24+```
25+environment.systemPackages = [
26+ pkgs.digitalbitbox
27+];
28+```
29+30+## Hardware {#sec-digitalbitbox-hardware-module}
31+32+The digitalbitbox hardware package enables the udev rules for Digital Bitbox
33+devices and may be installed as follows:
34+```
35+hardware.digitalbitbox.enable = true;
36+```
37+38+In order to alter the udev rules, one may provide different values for the
39+`udevRule51` and `udevRule52` attributes by means of overriding as follows:
40+```
41+programs.digitalbitbox = {
42+ enable = true;
43+ package = pkgs.digitalbitbox.override {
44+ udevRule51 = "something else";
45+ };
46+};
47+```
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-programs-digitalbitbox">
4+ <title>Digital Bitbox</title>
5+ <para>
6+ Digital Bitbox is a hardware wallet and second-factor authenticator.
7+ </para>
8+ <para>
9+ The <literal>digitalbitbox</literal> programs module may be
10+ installed by setting <literal>programs.digitalbitbox</literal> to
11+ <literal>true</literal> in a manner similar to
12+ </para>
13+ <programlisting>
14+programs.digitalbitbox.enable = true;
15+</programlisting>
16+ <para>
17+ and bundles the <literal>digitalbitbox</literal> package (see
18+ <xref linkend="sec-digitalbitbox-package" />), which contains the
19+ <literal>dbb-app</literal> and <literal>dbb-cli</literal> binaries,
20+ along with the hardware module (see
21+ <xref linkend="sec-digitalbitbox-hardware-module" />) which sets up
22+ the necessary udev rules to access the device.
23+ </para>
24+ <para>
25+ Enabling the digitalbitbox module is pretty much the easiest way to
26+ get a Digital Bitbox device working on your system.
27+ </para>
28+ <para>
29+ For more information, see
30+ <link xlink:href="https://digitalbitbox.com/start_linux">https://digitalbitbox.com/start_linux</link>.
31+ </para>
32+ <section xml:id="sec-digitalbitbox-package">
33+ <title>Package</title>
34+ <para>
35+ The binaries, <literal>dbb-app</literal> (a GUI tool) and
36+ <literal>dbb-cli</literal> (a CLI tool), are available through the
37+ <literal>digitalbitbox</literal> package which could be installed
38+ as follows:
39+ </para>
40+ <programlisting>
41+environment.systemPackages = [
42+ pkgs.digitalbitbox
43+];
44+</programlisting>
45+ </section>
46+ <section xml:id="sec-digitalbitbox-hardware-module">
47+ <title>Hardware</title>
48+ <para>
49+ The digitalbitbox hardware package enables the udev rules for
50+ Digital Bitbox devices and may be installed as follows:
51+ </para>
52+ <programlisting>
53+hardware.digitalbitbox.enable = true;
54+</programlisting>
55+ <para>
56+ In order to alter the udev rules, one may provide different values
57+ for the <literal>udevRule51</literal> and
58+ <literal>udevRule52</literal> attributes by means of overriding as
59+ follows:
60+ </para>
61+ <programlisting>
62+programs.digitalbitbox = {
63+ enable = true;
64+ package = pkgs.digitalbitbox.override {
65+ udevRule51 = "something else";
66+ };
67+};
68+</programlisting>
69+ </section>
70+</chapter>
-74
nixos/modules/programs/digitalbitbox/doc.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-programs-digitalbitbox">
6- <title>Digital Bitbox</title>
7- <para>
8- Digital Bitbox is a hardware wallet and second-factor authenticator.
9- </para>
10- <para>
11- The <literal>digitalbitbox</literal> programs module may be installed by
12- setting <literal>programs.digitalbitbox</literal> to <literal>true</literal>
13- in a manner similar to
14-<programlisting>
15-<xref linkend="opt-programs.digitalbitbox.enable"/> = true;
16-</programlisting>
17- and bundles the <literal>digitalbitbox</literal> package (see
18- <xref
19- linkend="sec-digitalbitbox-package" />), which contains the
20- <literal>dbb-app</literal> and <literal>dbb-cli</literal> binaries, along
21- with the hardware module (see
22- <xref
23- linkend="sec-digitalbitbox-hardware-module" />) which sets up the
24- necessary udev rules to access the device.
25- </para>
26- <para>
27- Enabling the digitalbitbox module is pretty much the easiest way to get a
28- Digital Bitbox device working on your system.
29- </para>
30- <para>
31- For more information, see
32- <link xlink:href="https://digitalbitbox.com/start_linux" />.
33- </para>
34- <section xml:id="sec-digitalbitbox-package">
35- <title>Package</title>
36-37- <para>
38- The binaries, <literal>dbb-app</literal> (a GUI tool) and
39- <literal>dbb-cli</literal> (a CLI tool), are available through the
40- <literal>digitalbitbox</literal> package which could be installed as
41- follows:
42-<programlisting>
43-<xref linkend="opt-environment.systemPackages"/> = [
44- pkgs.digitalbitbox
45-];
46-</programlisting>
47- </para>
48- </section>
49- <section xml:id="sec-digitalbitbox-hardware-module">
50- <title>Hardware</title>
51-52- <para>
53- The digitalbitbox hardware package enables the udev rules for Digital Bitbox
54- devices and may be installed as follows:
55-<programlisting>
56-<xref linkend="opt-hardware.digitalbitbox.enable"/> = true;
57-</programlisting>
58- </para>
59-60- <para>
61- In order to alter the udev rules, one may provide different values for the
62- <literal>udevRule51</literal> and <literal>udevRule52</literal> attributes
63- by means of overriding as follows:
64-<programlisting>
65-programs.digitalbitbox = {
66- <link linkend="opt-programs.digitalbitbox.enable">enable</link> = true;
67- <link linkend="opt-programs.digitalbitbox.package">package</link> = pkgs.digitalbitbox.override {
68- udevRule51 = "something else";
69- };
70-};
71-</programlisting>
72- </para>
73- </section>
74-</chapter>
···1+# Plotinus {#module-program-plotinus}
2+3+*Source:* {file}`modules/programs/plotinus.nix`
4+5+*Upstream documentation:* <https://github.com/p-e-w/plotinus>
6+7+Plotinus is a searchable command palette in every modern GTK application.
8+9+When in a GTK 3 application and Plotinus is enabled, you can press
10+`Ctrl+Shift+P` to open the command palette. The command
11+palette provides a searchable list of of all menu items in the application.
12+13+To enable Plotinus, add the following to your
14+{file}`configuration.nix`:
15+```
16+programs.plotinus.enable = true;
17+```
+28-28
nixos/modules/programs/plotinus.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-program-plotinus">
6- <title>Plotinus</title>
7- <para>
8- <emphasis>Source:</emphasis>
9- <filename>modules/programs/plotinus.nix</filename>
10- </para>
11- <para>
12- <emphasis>Upstream documentation:</emphasis>
13- <link xlink:href="https://github.com/p-e-w/plotinus"/>
14- </para>
15- <para>
16- Plotinus is a searchable command palette in every modern GTK application.
17- </para>
18- <para>
19- When in a GTK 3 application and Plotinus is enabled, you can press
20- <literal>Ctrl+Shift+P</literal> to open the command palette. The command
21- palette provides a searchable list of of all menu items in the application.
22- </para>
23- <para>
24- To enable Plotinus, add the following to your
25- <filename>configuration.nix</filename>:
26-<programlisting>
27-<xref linkend="opt-programs.plotinus.enable"/> = true;
028</programlisting>
29- </para>
30</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-program-plotinus">
4+ <title>Plotinus</title>
5+ <para>
6+ <emphasis>Source:</emphasis>
7+ <filename>modules/programs/plotinus.nix</filename>
8+ </para>
9+ <para>
10+ <emphasis>Upstream documentation:</emphasis>
11+ <link xlink:href="https://github.com/p-e-w/plotinus">https://github.com/p-e-w/plotinus</link>
12+ </para>
13+ <para>
14+ Plotinus is a searchable command palette in every modern GTK
15+ application.
16+ </para>
17+ <para>
18+ When in a GTK 3 application and Plotinus is enabled, you can press
19+ <literal>Ctrl+Shift+P</literal> to open the command palette. The
20+ command palette provides a searchable list of of all menu items in
21+ the application.
22+ </para>
23+ <para>
24+ To enable Plotinus, add the following to your
25+ <filename>configuration.nix</filename>:
26+ </para>
27+ <programlisting>
28+programs.plotinus.enable = true;
29</programlisting>
030</chapter>
···1+# Oh my ZSH {#module-programs-zsh-ohmyzsh}
2+3+[`oh-my-zsh`](https://ohmyz.sh/) is a framework to manage your [ZSH](https://www.zsh.org/)
4+configuration including completion scripts for several CLI tools or custom
5+prompt themes.
6+7+## Basic usage {#module-programs-oh-my-zsh-usage}
8+9+The module uses the `oh-my-zsh` package with all available
10+features. The initial setup using Nix expressions is fairly similar to the
11+configuration format of `oh-my-zsh`.
12+```
13+{
14+ programs.zsh.ohMyZsh = {
15+ enable = true;
16+ plugins = [ "git" "python" "man" ];
17+ theme = "agnoster";
18+ };
19+}
20+```
21+For a detailed explanation of these arguments please refer to the
22+[`oh-my-zsh` docs](https://github.com/robbyrussell/oh-my-zsh/wiki).
23+24+The expression generates the needed configuration and writes it into your
25+`/etc/zshrc`.
26+27+## Custom additions {#module-programs-oh-my-zsh-additions}
28+29+Sometimes third-party or custom scripts such as a modified theme may be
30+needed. `oh-my-zsh` provides the
31+[`ZSH_CUSTOM`](https://github.com/robbyrussell/oh-my-zsh/wiki/Customization#overriding-internals)
32+environment variable for this which points to a directory with additional
33+scripts.
34+35+The module can do this as well:
36+```
37+{
38+ programs.zsh.ohMyZsh.custom = "~/path/to/custom/scripts";
39+}
40+```
41+42+## Custom environments {#module-programs-oh-my-zsh-environments}
43+44+There are several extensions for `oh-my-zsh` packaged in
45+`nixpkgs`. One of them is
46+[nix-zsh-completions](https://github.com/spwhitt/nix-zsh-completions)
47+which bundles completion scripts and a plugin for `oh-my-zsh`.
48+49+Rather than using a single mutable path for `ZSH_CUSTOM`,
50+it's also possible to generate this path from a list of Nix packages:
51+```
52+{ pkgs, ... }:
53+{
54+ programs.zsh.ohMyZsh.customPkgs = [
55+ pkgs.nix-zsh-completions
56+ # and even more...
57+ ];
58+}
59+```
60+Internally a single store path will be created using
61+`buildEnv`. Please refer to the docs of
62+[`buildEnv`](https://nixos.org/nixpkgs/manual/#sec-building-environment)
63+for further reference.
64+65+*Please keep in mind that this is not compatible with
66+`programs.zsh.ohMyZsh.custom` as it requires an immutable
67+store path while `custom` shall remain mutable! An
68+evaluation failure will be thrown if both `custom` and
69+`customPkgs` are set.*
70+71+## Package your own customizations {#module-programs-oh-my-zsh-packaging-customizations}
72+73+If third-party customizations (e.g. new themes) are supposed to be added to
74+`oh-my-zsh` there are several pitfalls to keep in mind:
75+76+ - To comply with the default structure of `ZSH` the entire
77+ output needs to be written to `$out/share/zsh.`
78+79+ - Completion scripts are supposed to be stored at
80+ `$out/share/zsh/site-functions`. This directory is part of the
81+ [`fpath`](http://zsh.sourceforge.net/Doc/Release/Functions.html)
82+ and the package should be compatible with pure `ZSH`
83+ setups. The module will automatically link the contents of
84+ `site-functions` to completions directory in the proper
85+ store path.
86+87+ - The `plugins` directory needs the structure
88+ `pluginname/pluginname.plugin.zsh` as structured in the
89+ [upstream repo.](https://github.com/robbyrussell/oh-my-zsh/tree/91b771914bc7c43dd7c7a43b586c5de2c225ceb7/plugins)
90+91+A derivation for `oh-my-zsh` may look like this:
92+```
93+{ stdenv, fetchFromGitHub }:
94+95+stdenv.mkDerivation rec {
96+ name = "exemplary-zsh-customization-${version}";
97+ version = "1.0.0";
98+ src = fetchFromGitHub {
99+ # path to the upstream repository
100+ };
101+102+ dontBuild = true;
103+ installPhase = ''
104+ mkdir -p $out/share/zsh/site-functions
105+ cp {themes,plugins} $out/share/zsh
106+ cp completions $out/share/zsh/site-functions
107+ '';
108+}
109+```
+114-115
nixos/modules/programs/zsh/oh-my-zsh.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-programs-zsh-ohmyzsh">
6- <title>Oh my ZSH</title>
7- <para>
8- <literal><link xlink:href="https://ohmyz.sh/">oh-my-zsh</link></literal> is a
9- framework to manage your <link xlink:href="https://www.zsh.org/">ZSH</link>
10- configuration including completion scripts for several CLI tools or custom
11- prompt themes.
12- </para>
13- <section xml:id="module-programs-oh-my-zsh-usage">
14- <title>Basic usage</title>
15-16 <para>
17- The module uses the <literal>oh-my-zsh</literal> package with all available
18- features. The initial setup using Nix expressions is fairly similar to the
19- configuration format of <literal>oh-my-zsh</literal>.
20-<programlisting>
0000000000021{
22 programs.zsh.ohMyZsh = {
23 enable = true;
24- plugins = [ "git" "python" "man" ];
25- theme = "agnoster";
26 };
27}
28</programlisting>
29- For a detailed explanation of these arguments please refer to the
30- <link xlink:href="https://github.com/robbyrussell/oh-my-zsh/wiki"><literal>oh-my-zsh</literal>
31- docs</link>.
32- </para>
33-34- <para>
35- The expression generates the needed configuration and writes it into your
36- <literal>/etc/zshrc</literal>.
37- </para>
38- </section>
39- <section xml:id="module-programs-oh-my-zsh-additions">
40- <title>Custom additions</title>
41-42- <para>
43- Sometimes third-party or custom scripts such as a modified theme may be
44- needed. <literal>oh-my-zsh</literal> provides the
45- <link xlink:href="https://github.com/robbyrussell/oh-my-zsh/wiki/Customization#overriding-internals"><literal>ZSH_CUSTOM</literal></link>
46- environment variable for this which points to a directory with additional
47- scripts.
48- </para>
49-50- <para>
51- The module can do this as well:
52-<programlisting>
53{
54- programs.zsh.ohMyZsh.custom = "~/path/to/custom/scripts";
55}
56</programlisting>
57- </para>
58- </section>
59- <section xml:id="module-programs-oh-my-zsh-environments">
60- <title>Custom environments</title>
61-62- <para>
63- There are several extensions for <literal>oh-my-zsh</literal> packaged in
64- <literal>nixpkgs</literal>. One of them is
65- <link xlink:href="https://github.com/spwhitt/nix-zsh-completions">nix-zsh-completions</link>
66- which bundles completion scripts and a plugin for
67- <literal>oh-my-zsh</literal>.
68- </para>
69-70- <para>
71- Rather than using a single mutable path for <literal>ZSH_CUSTOM</literal>,
72- it's also possible to generate this path from a list of Nix packages:
73-<programlisting>
74{ pkgs, ... }:
75{
76 programs.zsh.ohMyZsh.customPkgs = [
···79 ];
80}
81</programlisting>
82- Internally a single store path will be created using
83- <literal>buildEnv</literal>. Please refer to the docs of
84- <link xlink:href="https://nixos.org/nixpkgs/manual/#sec-building-environment"><literal>buildEnv</literal></link>
85- for further reference.
86- </para>
87-88- <para>
89- <emphasis>Please keep in mind that this is not compatible with
90- <literal>programs.zsh.ohMyZsh.custom</literal> as it requires an immutable
91- store path while <literal>custom</literal> shall remain mutable! An
92- evaluation failure will be thrown if both <literal>custom</literal> and
93- <literal>customPkgs</literal> are set.</emphasis>
94- </para>
95- </section>
96- <section xml:id="module-programs-oh-my-zsh-packaging-customizations">
97- <title>Package your own customizations</title>
98-99- <para>
100- If third-party customizations (e.g. new themes) are supposed to be added to
101- <literal>oh-my-zsh</literal> there are several pitfalls to keep in mind:
102- </para>
103-104- <itemizedlist>
105- <listitem>
106 <para>
107- To comply with the default structure of <literal>ZSH</literal> the entire
108- output needs to be written to <literal>$out/share/zsh.</literal>
00109 </para>
110- </listitem>
111- <listitem>
112 <para>
113- Completion scripts are supposed to be stored at
114- <literal>$out/share/zsh/site-functions</literal>. This directory is part
115- of the
116- <literal><link xlink:href="http://zsh.sourceforge.net/Doc/Release/Functions.html">fpath</link></literal>
117- and the package should be compatible with pure <literal>ZSH</literal>
118- setups. The module will automatically link the contents of
119- <literal>site-functions</literal> to completions directory in the proper
120- store path.
121 </para>
122- </listitem>
123- <listitem>
0124 <para>
125- The <literal>plugins</literal> directory needs the structure
126- <literal>pluginname/pluginname.plugin.zsh</literal> as structured in the
127- <link xlink:href="https://github.com/robbyrussell/oh-my-zsh/tree/91b771914bc7c43dd7c7a43b586c5de2c225ceb7/plugins">upstream
128- repo.</link>
00000000000000000000000000000000129 </para>
130- </listitem>
131- </itemizedlist>
132-133- <para>
134- A derivation for <literal>oh-my-zsh</literal> may look like this:
135-<programlisting>
136{ stdenv, fetchFromGitHub }:
137138stdenv.mkDerivation rec {
139- name = "exemplary-zsh-customization-${version}";
140- version = "1.0.0";
141 src = fetchFromGitHub {
142 # path to the upstream repository
143 };
···150 '';
151}
152</programlisting>
153- </para>
154- </section>
155</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-programs-zsh-ohmyzsh">
4+ <title>Oh my ZSH</title>
000000000005 <para>
6+ <link xlink:href="https://ohmyz.sh/"><literal>oh-my-zsh</literal></link>
7+ is a framework to manage your
8+ <link xlink:href="https://www.zsh.org/">ZSH</link> configuration
9+ including completion scripts for several CLI tools or custom prompt
10+ themes.
11+ </para>
12+ <section xml:id="module-programs-oh-my-zsh-usage">
13+ <title>Basic usage</title>
14+ <para>
15+ The module uses the <literal>oh-my-zsh</literal> package with all
16+ available features. The initial setup using Nix expressions is
17+ fairly similar to the configuration format of
18+ <literal>oh-my-zsh</literal>.
19+ </para>
20+ <programlisting>
21{
22 programs.zsh.ohMyZsh = {
23 enable = true;
24+ plugins = [ "git" "python" "man" ];
25+ theme = "agnoster";
26 };
27}
28</programlisting>
29+ <para>
30+ For a detailed explanation of these arguments please refer to the
31+ <link xlink:href="https://github.com/robbyrussell/oh-my-zsh/wiki"><literal>oh-my-zsh</literal>
32+ docs</link>.
33+ </para>
34+ <para>
35+ The expression generates the needed configuration and writes it
36+ into your <literal>/etc/zshrc</literal>.
37+ </para>
38+ </section>
39+ <section xml:id="module-programs-oh-my-zsh-additions">
40+ <title>Custom additions</title>
41+ <para>
42+ Sometimes third-party or custom scripts such as a modified theme
43+ may be needed. <literal>oh-my-zsh</literal> provides the
44+ <link xlink:href="https://github.com/robbyrussell/oh-my-zsh/wiki/Customization#overriding-internals"><literal>ZSH_CUSTOM</literal></link>
45+ environment variable for this which points to a directory with
46+ additional scripts.
47+ </para>
48+ <para>
49+ The module can do this as well:
50+ </para>
51+ <programlisting>
052{
53+ programs.zsh.ohMyZsh.custom = "~/path/to/custom/scripts";
54}
55</programlisting>
56+ </section>
57+ <section xml:id="module-programs-oh-my-zsh-environments">
58+ <title>Custom environments</title>
59+ <para>
60+ There are several extensions for <literal>oh-my-zsh</literal>
61+ packaged in <literal>nixpkgs</literal>. One of them is
62+ <link xlink:href="https://github.com/spwhitt/nix-zsh-completions">nix-zsh-completions</link>
63+ which bundles completion scripts and a plugin for
64+ <literal>oh-my-zsh</literal>.
65+ </para>
66+ <para>
67+ Rather than using a single mutable path for
68+ <literal>ZSH_CUSTOM</literal>, it’s also possible to generate this
69+ path from a list of Nix packages:
70+ </para>
71+ <programlisting>
072{ pkgs, ... }:
73{
74 programs.zsh.ohMyZsh.customPkgs = [
···77 ];
78}
79</programlisting>
00000000000000000000000080 <para>
81+ Internally a single store path will be created using
82+ <literal>buildEnv</literal>. Please refer to the docs of
83+ <link xlink:href="https://nixos.org/nixpkgs/manual/#sec-building-environment"><literal>buildEnv</literal></link>
84+ for further reference.
85 </para>
0086 <para>
87+ <emphasis>Please keep in mind that this is not compatible with
88+ <literal>programs.zsh.ohMyZsh.custom</literal> as it requires an
89+ immutable store path while <literal>custom</literal> shall remain
90+ mutable! An evaluation failure will be thrown if both
91+ <literal>custom</literal> and <literal>customPkgs</literal> are
92+ set.</emphasis>
0093 </para>
94+ </section>
95+ <section xml:id="module-programs-oh-my-zsh-packaging-customizations">
96+ <title>Package your own customizations</title>
97 <para>
98+ If third-party customizations (e.g. new themes) are supposed to be
99+ added to <literal>oh-my-zsh</literal> there are several pitfalls
100+ to keep in mind:
101+ </para>
102+ <itemizedlist>
103+ <listitem>
104+ <para>
105+ To comply with the default structure of <literal>ZSH</literal>
106+ the entire output needs to be written to
107+ <literal>$out/share/zsh.</literal>
108+ </para>
109+ </listitem>
110+ <listitem>
111+ <para>
112+ Completion scripts are supposed to be stored at
113+ <literal>$out/share/zsh/site-functions</literal>. This
114+ directory is part of the
115+ <link xlink:href="http://zsh.sourceforge.net/Doc/Release/Functions.html"><literal>fpath</literal></link>
116+ and the package should be compatible with pure
117+ <literal>ZSH</literal> setups. The module will automatically
118+ link the contents of <literal>site-functions</literal> to
119+ completions directory in the proper store path.
120+ </para>
121+ </listitem>
122+ <listitem>
123+ <para>
124+ The <literal>plugins</literal> directory needs the structure
125+ <literal>pluginname/pluginname.plugin.zsh</literal> as
126+ structured in the
127+ <link xlink:href="https://github.com/robbyrussell/oh-my-zsh/tree/91b771914bc7c43dd7c7a43b586c5de2c225ceb7/plugins">upstream
128+ repo.</link>
129+ </para>
130+ </listitem>
131+ </itemizedlist>
132+ <para>
133+ A derivation for <literal>oh-my-zsh</literal> may look like this:
134 </para>
135+ <programlisting>
00000136{ stdenv, fetchFromGitHub }:
137138stdenv.mkDerivation rec {
139+ name = "exemplary-zsh-customization-${version}";
140+ version = "1.0.0";
141 src = fetchFromGitHub {
142 # path to the upstream repository
143 };
···150 '';
151}
152</programlisting>
153+ </section>
0154</chapter>
···1+# SSL/TLS Certificates with ACME {#module-security-acme}
2+3+NixOS supports automatic domain validation & certificate retrieval and
4+renewal using the ACME protocol. Any provider can be used, but by default
5+NixOS uses Let's Encrypt. The alternative ACME client
6+[lego](https://go-acme.github.io/lego/) is used under
7+the hood.
8+9+Automatic cert validation and configuration for Apache and Nginx virtual
10+hosts is included in NixOS, however if you would like to generate a wildcard
11+cert or you are not using a web server you will have to configure DNS
12+based validation.
13+14+## Prerequisites {#module-security-acme-prerequisites}
15+16+To use the ACME module, you must accept the provider's terms of service
17+by setting [](#opt-security.acme.acceptTerms)
18+to `true`. The Let's Encrypt ToS can be found
19+[here](https://letsencrypt.org/repository/).
20+21+You must also set an email address to be used when creating accounts with
22+Let's Encrypt. You can set this for all certs with
23+[](#opt-security.acme.defaults.email)
24+and/or on a per-cert basis with
25+[](#opt-security.acme.certs._name_.email).
26+This address is only used for registration and renewal reminders,
27+and cannot be used to administer the certificates in any way.
28+29+Alternatively, you can use a different ACME server by changing the
30+[](#opt-security.acme.defaults.server) option
31+to a provider of your choosing, or just change the server for one cert with
32+[](#opt-security.acme.certs._name_.server).
33+34+You will need an HTTP server or DNS server for verification. For HTTP,
35+the server must have a webroot defined that can serve
36+{file}`.well-known/acme-challenge`. This directory must be
37+writeable by the user that will run the ACME client. For DNS, you must
38+set up credentials with your provider/server for use with lego.
39+40+## Using ACME certificates in Nginx {#module-security-acme-nginx}
41+42+NixOS supports fetching ACME certificates for you by setting
43+`enableACME = true;` in a virtualHost config. We first create self-signed
44+placeholder certificates in place of the real ACME certs. The placeholder
45+certs are overwritten when the ACME certs arrive. For
46+`foo.example.com` the config would look like this:
47+48+```
49+security.acme.acceptTerms = true;
50+security.acme.defaults.email = "admin+acme@example.com";
51+services.nginx = {
52+ enable = true;
53+ virtualHosts = {
54+ "foo.example.com" = {
55+ forceSSL = true;
56+ enableACME = true;
57+ # All serverAliases will be added as extra domain names on the certificate.
58+ serverAliases = [ "bar.example.com" ];
59+ locations."/" = {
60+ root = "/var/www";
61+ };
62+ };
63+64+ # We can also add a different vhost and reuse the same certificate
65+ # but we have to append extraDomainNames manually beforehand:
66+ # security.acme.certs."foo.example.com".extraDomainNames = [ "baz.example.com" ];
67+ "baz.example.com" = {
68+ forceSSL = true;
69+ useACMEHost = "foo.example.com";
70+ locations."/" = {
71+ root = "/var/www";
72+ };
73+ };
74+ };
75+}
76+```
77+78+## Using ACME certificates in Apache/httpd {#module-security-acme-httpd}
79+80+Using ACME certificates with Apache virtual hosts is identical
81+to using them with Nginx. The attribute names are all the same, just replace
82+"nginx" with "httpd" where appropriate.
83+84+## Manual configuration of HTTP-01 validation {#module-security-acme-configuring}
85+86+First off you will need to set up a virtual host to serve the challenges.
87+This example uses a vhost called `certs.example.com`, with
88+the intent that you will generate certs for all your vhosts and redirect
89+everyone to HTTPS.
90+91+```
92+security.acme.acceptTerms = true;
93+security.acme.defaults.email = "admin+acme@example.com";
94+95+# /var/lib/acme/.challenges must be writable by the ACME user
96+# and readable by the Nginx user. The easiest way to achieve
97+# this is to add the Nginx user to the ACME group.
98+users.users.nginx.extraGroups = [ "acme" ];
99+100+services.nginx = {
101+ enable = true;
102+ virtualHosts = {
103+ "acmechallenge.example.com" = {
104+ # Catchall vhost, will redirect users to HTTPS for all vhosts
105+ serverAliases = [ "*.example.com" ];
106+ locations."/.well-known/acme-challenge" = {
107+ root = "/var/lib/acme/.challenges";
108+ };
109+ locations."/" = {
110+ return = "301 https://$host$request_uri";
111+ };
112+ };
113+ };
114+}
115+# Alternative config for Apache
116+users.users.wwwrun.extraGroups = [ "acme" ];
117+services.httpd = {
118+ enable = true;
119+ virtualHosts = {
120+ "acmechallenge.example.com" = {
121+ # Catchall vhost, will redirect users to HTTPS for all vhosts
122+ serverAliases = [ "*.example.com" ];
123+ # /var/lib/acme/.challenges must be writable by the ACME user and readable by the Apache user.
124+ # By default, this is the case.
125+ documentRoot = "/var/lib/acme/.challenges";
126+ extraConfig = ''
127+ RewriteEngine On
128+ RewriteCond %{HTTPS} off
129+ RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge [NC]
130+ RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301]
131+ '';
132+ };
133+ };
134+}
135+```
136+137+Now you need to configure ACME to generate a certificate.
138+139+```
140+security.acme.certs."foo.example.com" = {
141+ webroot = "/var/lib/acme/.challenges";
142+ email = "foo@example.com";
143+ # Ensure that the web server you use can read the generated certs
144+ # Take a look at the group option for the web server you choose.
145+ group = "nginx";
146+ # Since we have a wildcard vhost to handle port 80,
147+ # we can generate certs for anything!
148+ # Just make sure your DNS resolves them.
149+ extraDomainNames = [ "mail.example.com" ];
150+};
151+```
152+153+The private key {file}`key.pem` and certificate
154+{file}`fullchain.pem` will be put into
155+{file}`/var/lib/acme/foo.example.com`.
156+157+Refer to [](#ch-options) for all available configuration
158+options for the [security.acme](#opt-security.acme.certs)
159+module.
160+161+## Configuring ACME for DNS validation {#module-security-acme-config-dns}
162+163+This is useful if you want to generate a wildcard certificate, since
164+ACME servers will only hand out wildcard certs over DNS validation.
165+There are a number of supported DNS providers and servers you can utilise,
166+see the [lego docs](https://go-acme.github.io/lego/dns/)
167+for provider/server specific configuration values. For the sake of these
168+docs, we will provide a fully self-hosted example using bind.
169+170+```
171+services.bind = {
172+ enable = true;
173+ extraConfig = ''
174+ include "/var/lib/secrets/dnskeys.conf";
175+ '';
176+ zones = [
177+ rec {
178+ name = "example.com";
179+ file = "/var/db/bind/${name}";
180+ master = true;
181+ extraConfig = "allow-update { key rfc2136key.example.com.; };";
182+ }
183+ ];
184+}
185+186+# Now we can configure ACME
187+security.acme.acceptTerms = true;
188+security.acme.defaults.email = "admin+acme@example.com";
189+security.acme.certs."example.com" = {
190+ domain = "*.example.com";
191+ dnsProvider = "rfc2136";
192+ credentialsFile = "/var/lib/secrets/certs.secret";
193+ # We don't need to wait for propagation since this is a local DNS server
194+ dnsPropagationCheck = false;
195+};
196+```
197+198+The {file}`dnskeys.conf` and {file}`certs.secret`
199+must be kept secure and thus you should not keep their contents in your
200+Nix config. Instead, generate them one time with a systemd service:
201+202+```
203+systemd.services.dns-rfc2136-conf = {
204+ requiredBy = ["acme-example.com.service" "bind.service"];
205+ before = ["acme-example.com.service" "bind.service"];
206+ unitConfig = {
207+ ConditionPathExists = "!/var/lib/secrets/dnskeys.conf";
208+ };
209+ serviceConfig = {
210+ Type = "oneshot";
211+ UMask = 0077;
212+ };
213+ path = [ pkgs.bind ];
214+ script = ''
215+ mkdir -p /var/lib/secrets
216+ chmod 755 /var/lib/secrets
217+ tsig-keygen rfc2136key.example.com > /var/lib/secrets/dnskeys.conf
218+ chown named:root /var/lib/secrets/dnskeys.conf
219+ chmod 400 /var/lib/secrets/dnskeys.conf
220+221+ # extract secret value from the dnskeys.conf
222+ while read x y; do if [ "$x" = "secret" ]; then secret="''${y:1:''${#y}-3}"; fi; done < /var/lib/secrets/dnskeys.conf
223+224+ cat > /var/lib/secrets/certs.secret << EOF
225+ RFC2136_NAMESERVER='127.0.0.1:53'
226+ RFC2136_TSIG_ALGORITHM='hmac-sha256.'
227+ RFC2136_TSIG_KEY='rfc2136key.example.com'
228+ RFC2136_TSIG_SECRET='$secret'
229+ EOF
230+ chmod 400 /var/lib/secrets/certs.secret
231+ '';
232+};
233+```
234+235+Now you're all set to generate certs! You should monitor the first invocation
236+by running `systemctl start acme-example.com.service &
237+journalctl -fu acme-example.com.service` and watching its log output.
238+239+## Using DNS validation with web server virtual hosts {#module-security-acme-config-dns-with-vhosts}
240+241+It is possible to use DNS-01 validation with all certificates,
242+including those automatically configured via the Nginx/Apache
243+[`enableACME`](#opt-services.nginx.virtualHosts._name_.enableACME)
244+option. This configuration pattern is fully
245+supported and part of the module's test suite for Nginx + Apache.
246+247+You must follow the guide above on configuring DNS-01 validation
248+first, however instead of setting the options for one certificate
249+(e.g. [](#opt-security.acme.certs._name_.dnsProvider))
250+you will set them as defaults
251+(e.g. [](#opt-security.acme.defaults.dnsProvider)).
252+253+```
254+# Configure ACME appropriately
255+security.acme.acceptTerms = true;
256+security.acme.defaults.email = "admin+acme@example.com";
257+security.acme.defaults = {
258+ dnsProvider = "rfc2136";
259+ credentialsFile = "/var/lib/secrets/certs.secret";
260+ # We don't need to wait for propagation since this is a local DNS server
261+ dnsPropagationCheck = false;
262+};
263+264+# For each virtual host you would like to use DNS-01 validation with,
265+# set acmeRoot = null
266+services.nginx = {
267+ enable = true;
268+ virtualHosts = {
269+ "foo.example.com" = {
270+ enableACME = true;
271+ acmeRoot = null;
272+ };
273+ };
274+}
275+```
276+277+And that's it! Next time your configuration is rebuilt, or when
278+you add a new virtualHost, it will be DNS-01 validated.
279+280+## Using ACME with services demanding root owned certificates {#module-security-acme-root-owned}
281+282+Some services refuse to start if the configured certificate files
283+are not owned by root. PostgreSQL and OpenSMTPD are examples of these.
284+There is no way to change the user the ACME module uses (it will always be
285+`acme`), however you can use systemd's
286+`LoadCredential` feature to resolve this elegantly.
287+Below is an example configuration for OpenSMTPD, but this pattern
288+can be applied to any service.
289+290+```
291+# Configure ACME however you like (DNS or HTTP validation), adding
292+# the following configuration for the relevant certificate.
293+# Note: You cannot use `systemctl reload` here as that would mean
294+# the LoadCredential configuration below would be skipped and
295+# the service would continue to use old certificates.
296+security.acme.certs."mail.example.com".postRun = ''
297+ systemctl restart opensmtpd
298+'';
299+300+# Now you must augment OpenSMTPD's systemd service to load
301+# the certificate files.
302+systemd.services.opensmtpd.requires = ["acme-finished-mail.example.com.target"];
303+systemd.services.opensmtpd.serviceConfig.LoadCredential = let
304+ certDir = config.security.acme.certs."mail.example.com".directory;
305+in [
306+ "cert.pem:${certDir}/cert.pem"
307+ "key.pem:${certDir}/key.pem"
308+];
309+310+# Finally, configure OpenSMTPD to use these certs.
311+services.opensmtpd = let
312+ credsDir = "/run/credentials/opensmtpd.service";
313+in {
314+ enable = true;
315+ setSendmail = false;
316+ serverConfiguration = ''
317+ pki mail.example.com cert "${credsDir}/cert.pem"
318+ pki mail.example.com key "${credsDir}/key.pem"
319+ listen on localhost tls pki mail.example.com
320+ action act1 relay host smtp://127.0.0.1:10027
321+ match for local action act1
322+ '';
323+};
324+```
325+326+## Regenerating certificates {#module-security-acme-regenerate}
327+328+Should you need to regenerate a particular certificate in a hurry, such
329+as when a vulnerability is found in Let's Encrypt, there is now a convenient
330+mechanism for doing so. Running
331+`systemctl clean --what=state acme-example.com.service`
332+will remove all certificate files and the account data for the given domain,
333+allowing you to then `systemctl start acme-example.com.service`
334+to generate fresh ones.
335+336+## Fixing JWS Verification error {#module-security-acme-fix-jws}
337+338+It is possible that your account credentials file may become corrupt and need
339+to be regenerated. In this scenario lego will produce the error `JWS verification error`.
340+The solution is to simply delete the associated accounts file and
341+re-run the affected service(s).
342+343+```
344+# Find the accounts folder for the certificate
345+systemctl cat acme-example.com.service | grep -Po 'accounts/[^:]*'
346+export accountdir="$(!!)"
347+# Move this folder to some place else
348+mv /var/lib/acme/.lego/$accountdir{,.bak}
349+# Recreate the folder using systemd-tmpfiles
350+systemd-tmpfiles --create
351+# Get a new account and reissue certificates
352+# Note: Do this for all certs that share the same account email address
353+systemctl start acme-example.com.service
354+```
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-security-acme">
4+ <title>SSL/TLS Certificates with ACME</title>
5+ <para>
6+ NixOS supports automatic domain validation & certificate
7+ retrieval and renewal using the ACME protocol. Any provider can be
8+ used, but by default NixOS uses Let’s Encrypt. The alternative ACME
9+ client
10+ <link xlink:href="https://go-acme.github.io/lego/">lego</link> is
11+ used under the hood.
12+ </para>
13+ <para>
14+ Automatic cert validation and configuration for Apache and Nginx
15+ virtual hosts is included in NixOS, however if you would like to
16+ generate a wildcard cert or you are not using a web server you will
17+ have to configure DNS based validation.
18+ </para>
19+ <section xml:id="module-security-acme-prerequisites">
20+ <title>Prerequisites</title>
21+ <para>
22+ To use the ACME module, you must accept the provider’s terms of
23+ service by setting
24+ <xref linkend="opt-security.acme.acceptTerms" /> to
25+ <literal>true</literal>. The Let’s Encrypt ToS can be found
26+ <link xlink:href="https://letsencrypt.org/repository/">here</link>.
27+ </para>
28+ <para>
29+ You must also set an email address to be used when creating
30+ accounts with Let’s Encrypt. You can set this for all certs with
31+ <xref linkend="opt-security.acme.defaults.email" /> and/or on a
32+ per-cert basis with
33+ <xref linkend="opt-security.acme.certs._name_.email" />. This
34+ address is only used for registration and renewal reminders, and
35+ cannot be used to administer the certificates in any way.
36+ </para>
37+ <para>
38+ Alternatively, you can use a different ACME server by changing the
39+ <xref linkend="opt-security.acme.defaults.server" /> option to a
40+ provider of your choosing, or just change the server for one cert
41+ with <xref linkend="opt-security.acme.certs._name_.server" />.
42+ </para>
43+ <para>
44+ You will need an HTTP server or DNS server for verification. For
45+ HTTP, the server must have a webroot defined that can serve
46+ <filename>.well-known/acme-challenge</filename>. This directory
47+ must be writeable by the user that will run the ACME client. For
48+ DNS, you must set up credentials with your provider/server for use
49+ with lego.
50+ </para>
51+ </section>
52+ <section xml:id="module-security-acme-nginx">
53+ <title>Using ACME certificates in Nginx</title>
54+ <para>
55+ NixOS supports fetching ACME certificates for you by setting
56+ <literal>enableACME = true;</literal> in a virtualHost config. We
57+ first create self-signed placeholder certificates in place of the
58+ real ACME certs. The placeholder certs are overwritten when the
59+ ACME certs arrive. For <literal>foo.example.com</literal> the
60+ config would look like this:
61+ </para>
62+ <programlisting>
63+security.acme.acceptTerms = true;
64+security.acme.defaults.email = "admin+acme@example.com";
65+services.nginx = {
66+ enable = true;
67+ virtualHosts = {
68+ "foo.example.com" = {
69+ forceSSL = true;
70+ enableACME = true;
71+ # All serverAliases will be added as extra domain names on the certificate.
72+ serverAliases = [ "bar.example.com" ];
73+ locations."/" = {
74+ root = "/var/www";
75+ };
76+ };
77+78+ # We can also add a different vhost and reuse the same certificate
79+ # but we have to append extraDomainNames manually beforehand:
80+ # security.acme.certs."foo.example.com".extraDomainNames = [ "baz.example.com" ];
81+ "baz.example.com" = {
82+ forceSSL = true;
83+ useACMEHost = "foo.example.com";
84+ locations."/" = {
85+ root = "/var/www";
86+ };
87+ };
88+ };
89+}
90+</programlisting>
91+ </section>
92+ <section xml:id="module-security-acme-httpd">
93+ <title>Using ACME certificates in Apache/httpd</title>
94+ <para>
95+ Using ACME certificates with Apache virtual hosts is identical to
96+ using them with Nginx. The attribute names are all the same, just
97+ replace <quote>nginx</quote> with <quote>httpd</quote> where
98+ appropriate.
99+ </para>
100+ </section>
101+ <section xml:id="module-security-acme-configuring">
102+ <title>Manual configuration of HTTP-01 validation</title>
103+ <para>
104+ First off you will need to set up a virtual host to serve the
105+ challenges. This example uses a vhost called
106+ <literal>certs.example.com</literal>, with the intent that you
107+ will generate certs for all your vhosts and redirect everyone to
108+ HTTPS.
109+ </para>
110+ <programlisting>
111+security.acme.acceptTerms = true;
112+security.acme.defaults.email = "admin+acme@example.com";
113+114+# /var/lib/acme/.challenges must be writable by the ACME user
115+# and readable by the Nginx user. The easiest way to achieve
116+# this is to add the Nginx user to the ACME group.
117+users.users.nginx.extraGroups = [ "acme" ];
118+119+services.nginx = {
120+ enable = true;
121+ virtualHosts = {
122+ "acmechallenge.example.com" = {
123+ # Catchall vhost, will redirect users to HTTPS for all vhosts
124+ serverAliases = [ "*.example.com" ];
125+ locations."/.well-known/acme-challenge" = {
126+ root = "/var/lib/acme/.challenges";
127+ };
128+ locations."/" = {
129+ return = "301 https://$host$request_uri";
130+ };
131+ };
132+ };
133+}
134+# Alternative config for Apache
135+users.users.wwwrun.extraGroups = [ "acme" ];
136+services.httpd = {
137+ enable = true;
138+ virtualHosts = {
139+ "acmechallenge.example.com" = {
140+ # Catchall vhost, will redirect users to HTTPS for all vhosts
141+ serverAliases = [ "*.example.com" ];
142+ # /var/lib/acme/.challenges must be writable by the ACME user and readable by the Apache user.
143+ # By default, this is the case.
144+ documentRoot = "/var/lib/acme/.challenges";
145+ extraConfig = ''
146+ RewriteEngine On
147+ RewriteCond %{HTTPS} off
148+ RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge [NC]
149+ RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301]
150+ '';
151+ };
152+ };
153+}
154+</programlisting>
155+ <para>
156+ Now you need to configure ACME to generate a certificate.
157+ </para>
158+ <programlisting>
159+security.acme.certs."foo.example.com" = {
160+ webroot = "/var/lib/acme/.challenges";
161+ email = "foo@example.com";
162+ # Ensure that the web server you use can read the generated certs
163+ # Take a look at the group option for the web server you choose.
164+ group = "nginx";
165+ # Since we have a wildcard vhost to handle port 80,
166+ # we can generate certs for anything!
167+ # Just make sure your DNS resolves them.
168+ extraDomainNames = [ "mail.example.com" ];
169+};
170+</programlisting>
171+ <para>
172+ The private key <filename>key.pem</filename> and certificate
173+ <filename>fullchain.pem</filename> will be put into
174+ <filename>/var/lib/acme/foo.example.com</filename>.
175+ </para>
176+ <para>
177+ Refer to <xref linkend="ch-options" /> for all available
178+ configuration options for the
179+ <link linkend="opt-security.acme.certs">security.acme</link>
180+ module.
181+ </para>
182+ </section>
183+ <section xml:id="module-security-acme-config-dns">
184+ <title>Configuring ACME for DNS validation</title>
185+ <para>
186+ This is useful if you want to generate a wildcard certificate,
187+ since ACME servers will only hand out wildcard certs over DNS
188+ validation. There are a number of supported DNS providers and
189+ servers you can utilise, see the
190+ <link xlink:href="https://go-acme.github.io/lego/dns/">lego
191+ docs</link> for provider/server specific configuration values. For
192+ the sake of these docs, we will provide a fully self-hosted
193+ example using bind.
194+ </para>
195+ <programlisting>
196+services.bind = {
197+ enable = true;
198+ extraConfig = ''
199+ include "/var/lib/secrets/dnskeys.conf";
200+ '';
201+ zones = [
202+ rec {
203+ name = "example.com";
204+ file = "/var/db/bind/${name}";
205+ master = true;
206+ extraConfig = "allow-update { key rfc2136key.example.com.; };";
207+ }
208+ ];
209+}
210+211+# Now we can configure ACME
212+security.acme.acceptTerms = true;
213+security.acme.defaults.email = "admin+acme@example.com";
214+security.acme.certs."example.com" = {
215+ domain = "*.example.com";
216+ dnsProvider = "rfc2136";
217+ credentialsFile = "/var/lib/secrets/certs.secret";
218+ # We don't need to wait for propagation since this is a local DNS server
219+ dnsPropagationCheck = false;
220+};
221+</programlisting>
222+ <para>
223+ The <filename>dnskeys.conf</filename> and
224+ <filename>certs.secret</filename> must be kept secure and thus you
225+ should not keep their contents in your Nix config. Instead,
226+ generate them one time with a systemd service:
227+ </para>
228+ <programlisting>
229+systemd.services.dns-rfc2136-conf = {
230+ requiredBy = ["acme-example.com.service" "bind.service"];
231+ before = ["acme-example.com.service" "bind.service"];
232+ unitConfig = {
233+ ConditionPathExists = "!/var/lib/secrets/dnskeys.conf";
234+ };
235+ serviceConfig = {
236+ Type = "oneshot";
237+ UMask = 0077;
238+ };
239+ path = [ pkgs.bind ];
240+ script = ''
241+ mkdir -p /var/lib/secrets
242+ chmod 755 /var/lib/secrets
243+ tsig-keygen rfc2136key.example.com > /var/lib/secrets/dnskeys.conf
244+ chown named:root /var/lib/secrets/dnskeys.conf
245+ chmod 400 /var/lib/secrets/dnskeys.conf
246+247+ # extract secret value from the dnskeys.conf
248+ while read x y; do if [ "$x" = "secret" ]; then secret="''${y:1:''${#y}-3}"; fi; done < /var/lib/secrets/dnskeys.conf
249+250+ cat > /var/lib/secrets/certs.secret << EOF
251+ RFC2136_NAMESERVER='127.0.0.1:53'
252+ RFC2136_TSIG_ALGORITHM='hmac-sha256.'
253+ RFC2136_TSIG_KEY='rfc2136key.example.com'
254+ RFC2136_TSIG_SECRET='$secret'
255+ EOF
256+ chmod 400 /var/lib/secrets/certs.secret
257+ '';
258+};
259+</programlisting>
260+ <para>
261+ Now you’re all set to generate certs! You should monitor the first
262+ invocation by running
263+ <literal>systemctl start acme-example.com.service & journalctl -fu acme-example.com.service</literal>
264+ and watching its log output.
265+ </para>
266+ </section>
267+ <section xml:id="module-security-acme-config-dns-with-vhosts">
268+ <title>Using DNS validation with web server virtual hosts</title>
269+ <para>
270+ It is possible to use DNS-01 validation with all certificates,
271+ including those automatically configured via the Nginx/Apache
272+ <link linkend="opt-services.nginx.virtualHosts._name_.enableACME"><literal>enableACME</literal></link>
273+ option. This configuration pattern is fully supported and part of
274+ the module’s test suite for Nginx + Apache.
275+ </para>
276+ <para>
277+ You must follow the guide above on configuring DNS-01 validation
278+ first, however instead of setting the options for one certificate
279+ (e.g.
280+ <xref linkend="opt-security.acme.certs._name_.dnsProvider" />) you
281+ will set them as defaults (e.g.
282+ <xref linkend="opt-security.acme.defaults.dnsProvider" />).
283+ </para>
284+ <programlisting>
285+# Configure ACME appropriately
286+security.acme.acceptTerms = true;
287+security.acme.defaults.email = "admin+acme@example.com";
288+security.acme.defaults = {
289+ dnsProvider = "rfc2136";
290+ credentialsFile = "/var/lib/secrets/certs.secret";
291+ # We don't need to wait for propagation since this is a local DNS server
292+ dnsPropagationCheck = false;
293+};
294+295+# For each virtual host you would like to use DNS-01 validation with,
296+# set acmeRoot = null
297+services.nginx = {
298+ enable = true;
299+ virtualHosts = {
300+ "foo.example.com" = {
301+ enableACME = true;
302+ acmeRoot = null;
303+ };
304+ };
305+}
306+</programlisting>
307+ <para>
308+ And that’s it! Next time your configuration is rebuilt, or when
309+ you add a new virtualHost, it will be DNS-01 validated.
310+ </para>
311+ </section>
312+ <section xml:id="module-security-acme-root-owned">
313+ <title>Using ACME with services demanding root owned
314+ certificates</title>
315+ <para>
316+ Some services refuse to start if the configured certificate files
317+ are not owned by root. PostgreSQL and OpenSMTPD are examples of
318+ these. There is no way to change the user the ACME module uses (it
319+ will always be <literal>acme</literal>), however you can use
320+ systemd’s <literal>LoadCredential</literal> feature to resolve
321+ this elegantly. Below is an example configuration for OpenSMTPD,
322+ but this pattern can be applied to any service.
323+ </para>
324+ <programlisting>
325+# Configure ACME however you like (DNS or HTTP validation), adding
326+# the following configuration for the relevant certificate.
327+# Note: You cannot use `systemctl reload` here as that would mean
328+# the LoadCredential configuration below would be skipped and
329+# the service would continue to use old certificates.
330+security.acme.certs."mail.example.com".postRun = ''
331+ systemctl restart opensmtpd
332+'';
333+334+# Now you must augment OpenSMTPD's systemd service to load
335+# the certificate files.
336+systemd.services.opensmtpd.requires = ["acme-finished-mail.example.com.target"];
337+systemd.services.opensmtpd.serviceConfig.LoadCredential = let
338+ certDir = config.security.acme.certs."mail.example.com".directory;
339+in [
340+ "cert.pem:${certDir}/cert.pem"
341+ "key.pem:${certDir}/key.pem"
342+];
343+344+# Finally, configure OpenSMTPD to use these certs.
345+services.opensmtpd = let
346+ credsDir = "/run/credentials/opensmtpd.service";
347+in {
348+ enable = true;
349+ setSendmail = false;
350+ serverConfiguration = ''
351+ pki mail.example.com cert "${credsDir}/cert.pem"
352+ pki mail.example.com key "${credsDir}/key.pem"
353+ listen on localhost tls pki mail.example.com
354+ action act1 relay host smtp://127.0.0.1:10027
355+ match for local action act1
356+ '';
357+};
358+</programlisting>
359+ </section>
360+ <section xml:id="module-security-acme-regenerate">
361+ <title>Regenerating certificates</title>
362+ <para>
363+ Should you need to regenerate a particular certificate in a hurry,
364+ such as when a vulnerability is found in Let’s Encrypt, there is
365+ now a convenient mechanism for doing so. Running
366+ <literal>systemctl clean --what=state acme-example.com.service</literal>
367+ will remove all certificate files and the account data for the
368+ given domain, allowing you to then
369+ <literal>systemctl start acme-example.com.service</literal> to
370+ generate fresh ones.
371+ </para>
372+ </section>
373+ <section xml:id="module-security-acme-fix-jws">
374+ <title>Fixing JWS Verification error</title>
375+ <para>
376+ It is possible that your account credentials file may become
377+ corrupt and need to be regenerated. In this scenario lego will
378+ produce the error <literal>JWS verification error</literal>. The
379+ solution is to simply delete the associated accounts file and
380+ re-run the affected service(s).
381+ </para>
382+ <programlisting>
383+# Find the accounts folder for the certificate
384+systemctl cat acme-example.com.service | grep -Po 'accounts/[^:]*'
385+export accountdir="$(!!)"
386+# Move this folder to some place else
387+mv /var/lib/acme/.lego/$accountdir{,.bak}
388+# Recreate the folder using systemd-tmpfiles
389+systemd-tmpfiles --create
390+# Get a new account and reissue certificates
391+# Note: Do this for all certs that share the same account email address
392+systemctl start acme-example.com.service
393+</programlisting>
394+ </section>
395+</chapter>
-414
nixos/modules/security/acme/doc.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-security-acme">
6- <title>SSL/TLS Certificates with ACME</title>
7- <para>
8- NixOS supports automatic domain validation & certificate retrieval and
9- renewal using the ACME protocol. Any provider can be used, but by default
10- NixOS uses Let's Encrypt. The alternative ACME client
11- <link xlink:href="https://go-acme.github.io/lego/">lego</link> is used under
12- the hood.
13- </para>
14- <para>
15- Automatic cert validation and configuration for Apache and Nginx virtual
16- hosts is included in NixOS, however if you would like to generate a wildcard
17- cert or you are not using a web server you will have to configure DNS
18- based validation.
19- </para>
20- <section xml:id="module-security-acme-prerequisites">
21- <title>Prerequisites</title>
22-23- <para>
24- To use the ACME module, you must accept the provider's terms of service
25- by setting <literal><xref linkend="opt-security.acme.acceptTerms" /></literal>
26- to <literal>true</literal>. The Let's Encrypt ToS can be found
27- <link xlink:href="https://letsencrypt.org/repository/">here</link>.
28- </para>
29-30- <para>
31- You must also set an email address to be used when creating accounts with
32- Let's Encrypt. You can set this for all certs with
33- <literal><xref linkend="opt-security.acme.defaults.email" /></literal>
34- and/or on a per-cert basis with
35- <literal><xref linkend="opt-security.acme.certs._name_.email" /></literal>.
36- This address is only used for registration and renewal reminders,
37- and cannot be used to administer the certificates in any way.
38- </para>
39-40- <para>
41- Alternatively, you can use a different ACME server by changing the
42- <literal><xref linkend="opt-security.acme.defaults.server" /></literal> option
43- to a provider of your choosing, or just change the server for one cert with
44- <literal><xref linkend="opt-security.acme.certs._name_.server" /></literal>.
45- </para>
46-47- <para>
48- You will need an HTTP server or DNS server for verification. For HTTP,
49- the server must have a webroot defined that can serve
50- <filename>.well-known/acme-challenge</filename>. This directory must be
51- writeable by the user that will run the ACME client. For DNS, you must
52- set up credentials with your provider/server for use with lego.
53- </para>
54- </section>
55- <section xml:id="module-security-acme-nginx">
56- <title>Using ACME certificates in Nginx</title>
57-58- <para>
59- NixOS supports fetching ACME certificates for you by setting
60- <literal><link linkend="opt-services.nginx.virtualHosts._name_.enableACME">enableACME</link>
61- = true;</literal> in a virtualHost config. We first create self-signed
62- placeholder certificates in place of the real ACME certs. The placeholder
63- certs are overwritten when the ACME certs arrive. For
64- <literal>foo.example.com</literal> the config would look like this:
65- </para>
66-67-<programlisting>
68-<xref linkend="opt-security.acme.acceptTerms" /> = true;
69-<xref linkend="opt-security.acme.defaults.email" /> = "admin+acme@example.com";
70-services.nginx = {
71- <link linkend="opt-services.nginx.enable">enable</link> = true;
72- <link linkend="opt-services.nginx.virtualHosts">virtualHosts</link> = {
73- "foo.example.com" = {
74- <link linkend="opt-services.nginx.virtualHosts._name_.forceSSL">forceSSL</link> = true;
75- <link linkend="opt-services.nginx.virtualHosts._name_.enableACME">enableACME</link> = true;
76- # All serverAliases will be added as <link linkend="opt-security.acme.certs._name_.extraDomainNames">extra domain names</link> on the certificate.
77- <link linkend="opt-services.nginx.virtualHosts._name_.serverAliases">serverAliases</link> = [ "bar.example.com" ];
78- locations."/" = {
79- <link linkend="opt-services.nginx.virtualHosts._name_.locations._name_.root">root</link> = "/var/www";
80- };
81- };
82-83- # We can also add a different vhost and reuse the same certificate
84- # but we have to append extraDomainNames manually beforehand:
85- # <link linkend="opt-security.acme.certs._name_.extraDomainNames">security.acme.certs."foo.example.com".extraDomainNames</link> = [ "baz.example.com" ];
86- "baz.example.com" = {
87- <link linkend="opt-services.nginx.virtualHosts._name_.forceSSL">forceSSL</link> = true;
88- <link linkend="opt-services.nginx.virtualHosts._name_.useACMEHost">useACMEHost</link> = "foo.example.com";
89- locations."/" = {
90- <link linkend="opt-services.nginx.virtualHosts._name_.locations._name_.root">root</link> = "/var/www";
91- };
92- };
93- };
94-}
95-</programlisting>
96- </section>
97- <section xml:id="module-security-acme-httpd">
98- <title>Using ACME certificates in Apache/httpd</title>
99-100- <para>
101- Using ACME certificates with Apache virtual hosts is identical
102- to using them with Nginx. The attribute names are all the same, just replace
103- "nginx" with "httpd" where appropriate.
104- </para>
105- </section>
106- <section xml:id="module-security-acme-configuring">
107- <title>Manual configuration of HTTP-01 validation</title>
108-109- <para>
110- First off you will need to set up a virtual host to serve the challenges.
111- This example uses a vhost called <literal>certs.example.com</literal>, with
112- the intent that you will generate certs for all your vhosts and redirect
113- everyone to HTTPS.
114- </para>
115-116-<programlisting>
117-<xref linkend="opt-security.acme.acceptTerms" /> = true;
118-<xref linkend="opt-security.acme.defaults.email" /> = "admin+acme@example.com";
119-120-# /var/lib/acme/.challenges must be writable by the ACME user
121-# and readable by the Nginx user. The easiest way to achieve
122-# this is to add the Nginx user to the ACME group.
123-<link linkend="opt-users.users._name_.extraGroups">users.users.nginx.extraGroups</link> = [ "acme" ];
124-125-services.nginx = {
126- <link linkend="opt-services.nginx.enable">enable</link> = true;
127- <link linkend="opt-services.nginx.virtualHosts">virtualHosts</link> = {
128- "acmechallenge.example.com" = {
129- # Catchall vhost, will redirect users to HTTPS for all vhosts
130- <link linkend="opt-services.nginx.virtualHosts._name_.serverAliases">serverAliases</link> = [ "*.example.com" ];
131- locations."/.well-known/acme-challenge" = {
132- <link linkend="opt-services.nginx.virtualHosts._name_.locations._name_.root">root</link> = "/var/lib/acme/.challenges";
133- };
134- locations."/" = {
135- <link linkend="opt-services.nginx.virtualHosts._name_.locations._name_.return">return</link> = "301 https://$host$request_uri";
136- };
137- };
138- };
139-}
140-# Alternative config for Apache
141-<link linkend="opt-users.users._name_.extraGroups">users.users.wwwrun.extraGroups</link> = [ "acme" ];
142-services.httpd = {
143- <link linkend="opt-services.httpd.enable">enable = true;</link>
144- <link linkend="opt-services.httpd.virtualHosts">virtualHosts</link> = {
145- "acmechallenge.example.com" = {
146- # Catchall vhost, will redirect users to HTTPS for all vhosts
147- <link linkend="opt-services.httpd.virtualHosts._name_.serverAliases">serverAliases</link> = [ "*.example.com" ];
148- # /var/lib/acme/.challenges must be writable by the ACME user and readable by the Apache user.
149- # By default, this is the case.
150- <link linkend="opt-services.httpd.virtualHosts._name_.documentRoot">documentRoot</link> = "/var/lib/acme/.challenges";
151- <link linkend="opt-services.httpd.virtualHosts._name_.extraConfig">extraConfig</link> = ''
152- RewriteEngine On
153- RewriteCond %{HTTPS} off
154- RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge [NC]
155- RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301]
156- '';
157- };
158- };
159-}
160-</programlisting>
161-162- <para>
163- Now you need to configure ACME to generate a certificate.
164- </para>
165-166-<programlisting>
167-<xref linkend="opt-security.acme.certs"/>."foo.example.com" = {
168- <link linkend="opt-security.acme.certs._name_.webroot">webroot</link> = "/var/lib/acme/.challenges";
169- <link linkend="opt-security.acme.certs._name_.email">email</link> = "foo@example.com";
170- # Ensure that the web server you use can read the generated certs
171- # Take a look at the <link linkend="opt-services.nginx.group">group</link> option for the web server you choose.
172- <link linkend="opt-security.acme.certs._name_.group">group</link> = "nginx";
173- # Since we have a wildcard vhost to handle port 80,
174- # we can generate certs for anything!
175- # Just make sure your DNS resolves them.
176- <link linkend="opt-security.acme.certs._name_.extraDomainNames">extraDomainNames</link> = [ "mail.example.com" ];
177-};
178-</programlisting>
179-180- <para>
181- The private key <filename>key.pem</filename> and certificate
182- <filename>fullchain.pem</filename> will be put into
183- <filename>/var/lib/acme/foo.example.com</filename>.
184- </para>
185-186- <para>
187- Refer to <xref linkend="ch-options" /> for all available configuration
188- options for the <link linkend="opt-security.acme.certs">security.acme</link>
189- module.
190- </para>
191- </section>
192- <section xml:id="module-security-acme-config-dns">
193- <title>Configuring ACME for DNS validation</title>
194-195- <para>
196- This is useful if you want to generate a wildcard certificate, since
197- ACME servers will only hand out wildcard certs over DNS validation.
198- There are a number of supported DNS providers and servers you can utilise,
199- see the <link xlink:href="https://go-acme.github.io/lego/dns/">lego docs</link>
200- for provider/server specific configuration values. For the sake of these
201- docs, we will provide a fully self-hosted example using bind.
202- </para>
203-204-<programlisting>
205-services.bind = {
206- <link linkend="opt-services.bind.enable">enable</link> = true;
207- <link linkend="opt-services.bind.extraConfig">extraConfig</link> = ''
208- include "/var/lib/secrets/dnskeys.conf";
209- '';
210- <link linkend="opt-services.bind.zones">zones</link> = [
211- rec {
212- name = "example.com";
213- file = "/var/db/bind/${name}";
214- master = true;
215- extraConfig = "allow-update { key rfc2136key.example.com.; };";
216- }
217- ];
218-}
219-220-# Now we can configure ACME
221-<xref linkend="opt-security.acme.acceptTerms" /> = true;
222-<xref linkend="opt-security.acme.defaults.email" /> = "admin+acme@example.com";
223-<xref linkend="opt-security.acme.certs" />."example.com" = {
224- <link linkend="opt-security.acme.certs._name_.domain">domain</link> = "*.example.com";
225- <link linkend="opt-security.acme.certs._name_.dnsProvider">dnsProvider</link> = "rfc2136";
226- <link linkend="opt-security.acme.certs._name_.credentialsFile">credentialsFile</link> = "/var/lib/secrets/certs.secret";
227- # We don't need to wait for propagation since this is a local DNS server
228- <link linkend="opt-security.acme.certs._name_.dnsPropagationCheck">dnsPropagationCheck</link> = false;
229-};
230-</programlisting>
231-232- <para>
233- The <filename>dnskeys.conf</filename> and <filename>certs.secret</filename>
234- must be kept secure and thus you should not keep their contents in your
235- Nix config. Instead, generate them one time with a systemd service:
236- </para>
237-238-<programlisting>
239-systemd.services.dns-rfc2136-conf = {
240- requiredBy = ["acme-example.com.service" "bind.service"];
241- before = ["acme-example.com.service" "bind.service"];
242- unitConfig = {
243- ConditionPathExists = "!/var/lib/secrets/dnskeys.conf";
244- };
245- serviceConfig = {
246- Type = "oneshot";
247- UMask = 0077;
248- };
249- path = [ pkgs.bind ];
250- script = ''
251- mkdir -p /var/lib/secrets
252- chmod 755 /var/lib/secrets
253- tsig-keygen rfc2136key.example.com > /var/lib/secrets/dnskeys.conf
254- chown named:root /var/lib/secrets/dnskeys.conf
255- chmod 400 /var/lib/secrets/dnskeys.conf
256-257- # extract secret value from the dnskeys.conf
258- while read x y; do if [ "$x" = "secret" ]; then secret="''${y:1:''${#y}-3}"; fi; done < /var/lib/secrets/dnskeys.conf
259-260- cat > /var/lib/secrets/certs.secret << EOF
261- RFC2136_NAMESERVER='127.0.0.1:53'
262- RFC2136_TSIG_ALGORITHM='hmac-sha256.'
263- RFC2136_TSIG_KEY='rfc2136key.example.com'
264- RFC2136_TSIG_SECRET='$secret'
265- EOF
266- chmod 400 /var/lib/secrets/certs.secret
267- '';
268-};
269-</programlisting>
270-271- <para>
272- Now you're all set to generate certs! You should monitor the first invocation
273- by running <literal>systemctl start acme-example.com.service &
274- journalctl -fu acme-example.com.service</literal> and watching its log output.
275- </para>
276- </section>
277-278- <section xml:id="module-security-acme-config-dns-with-vhosts">
279- <title>Using DNS validation with web server virtual hosts</title>
280-281- <para>
282- It is possible to use DNS-01 validation with all certificates,
283- including those automatically configured via the Nginx/Apache
284- <literal><link linkend="opt-services.nginx.virtualHosts._name_.enableACME">enableACME</link></literal>
285- option. This configuration pattern is fully
286- supported and part of the module's test suite for Nginx + Apache.
287- </para>
288-289- <para>
290- You must follow the guide above on configuring DNS-01 validation
291- first, however instead of setting the options for one certificate
292- (e.g. <xref linkend="opt-security.acme.certs._name_.dnsProvider" />)
293- you will set them as defaults
294- (e.g. <xref linkend="opt-security.acme.defaults.dnsProvider" />).
295- </para>
296-297-<programlisting>
298-# Configure ACME appropriately
299-<xref linkend="opt-security.acme.acceptTerms" /> = true;
300-<xref linkend="opt-security.acme.defaults.email" /> = "admin+acme@example.com";
301-<xref linkend="opt-security.acme.defaults" /> = {
302- <link linkend="opt-security.acme.defaults.dnsProvider">dnsProvider</link> = "rfc2136";
303- <link linkend="opt-security.acme.defaults.credentialsFile">credentialsFile</link> = "/var/lib/secrets/certs.secret";
304- # We don't need to wait for propagation since this is a local DNS server
305- <link linkend="opt-security.acme.defaults.dnsPropagationCheck">dnsPropagationCheck</link> = false;
306-};
307-308-# For each virtual host you would like to use DNS-01 validation with,
309-# set acmeRoot = null
310-services.nginx = {
311- <link linkend="opt-services.nginx.enable">enable</link> = true;
312- <link linkend="opt-services.nginx.virtualHosts">virtualHosts</link> = {
313- "foo.example.com" = {
314- <link linkend="opt-services.nginx.virtualHosts._name_.enableACME">enableACME</link> = true;
315- <link linkend="opt-services.nginx.virtualHosts._name_.acmeRoot">acmeRoot</link> = null;
316- };
317- };
318-}
319-</programlisting>
320-321- <para>
322- And that's it! Next time your configuration is rebuilt, or when
323- you add a new virtualHost, it will be DNS-01 validated.
324- </para>
325- </section>
326-327- <section xml:id="module-security-acme-root-owned">
328- <title>Using ACME with services demanding root owned certificates</title>
329-330- <para>
331- Some services refuse to start if the configured certificate files
332- are not owned by root. PostgreSQL and OpenSMTPD are examples of these.
333- There is no way to change the user the ACME module uses (it will always be
334- <literal>acme</literal>), however you can use systemd's
335- <literal>LoadCredential</literal> feature to resolve this elegantly.
336- Below is an example configuration for OpenSMTPD, but this pattern
337- can be applied to any service.
338- </para>
339-340-<programlisting>
341-# Configure ACME however you like (DNS or HTTP validation), adding
342-# the following configuration for the relevant certificate.
343-# Note: You cannot use `systemctl reload` here as that would mean
344-# the LoadCredential configuration below would be skipped and
345-# the service would continue to use old certificates.
346-security.acme.certs."mail.example.com".postRun = ''
347- systemctl restart opensmtpd
348-'';
349-350-# Now you must augment OpenSMTPD's systemd service to load
351-# the certificate files.
352-<link linkend="opt-systemd.services._name_.requires">systemd.services.opensmtpd.requires</link> = ["acme-finished-mail.example.com.target"];
353-<link linkend="opt-systemd.services._name_.serviceConfig">systemd.services.opensmtpd.serviceConfig.LoadCredential</link> = let
354- certDir = config.security.acme.certs."mail.example.com".directory;
355-in [
356- "cert.pem:${certDir}/cert.pem"
357- "key.pem:${certDir}/key.pem"
358-];
359-360-# Finally, configure OpenSMTPD to use these certs.
361-services.opensmtpd = let
362- credsDir = "/run/credentials/opensmtpd.service";
363-in {
364- enable = true;
365- setSendmail = false;
366- serverConfiguration = ''
367- pki mail.example.com cert "${credsDir}/cert.pem"
368- pki mail.example.com key "${credsDir}/key.pem"
369- listen on localhost tls pki mail.example.com
370- action act1 relay host smtp://127.0.0.1:10027
371- match for local action act1
372- '';
373-};
374-</programlisting>
375- </section>
376-377- <section xml:id="module-security-acme-regenerate">
378- <title>Regenerating certificates</title>
379-380- <para>
381- Should you need to regenerate a particular certificate in a hurry, such
382- as when a vulnerability is found in Let's Encrypt, there is now a convenient
383- mechanism for doing so. Running
384- <literal>systemctl clean --what=state acme-example.com.service</literal>
385- will remove all certificate files and the account data for the given domain,
386- allowing you to then <literal>systemctl start acme-example.com.service</literal>
387- to generate fresh ones.
388- </para>
389- </section>
390- <section xml:id="module-security-acme-fix-jws">
391- <title>Fixing JWS Verification error</title>
392-393- <para>
394- It is possible that your account credentials file may become corrupt and need
395- to be regenerated. In this scenario lego will produce the error <literal>JWS verification error</literal>.
396- The solution is to simply delete the associated accounts file and
397- re-run the affected service(s).
398- </para>
399-400-<programlisting>
401-# Find the accounts folder for the certificate
402-systemctl cat acme-example.com.service | grep -Po 'accounts/[^:]*'
403-export accountdir="$(!!)"
404-# Move this folder to some place else
405-mv /var/lib/acme/.lego/$accountdir{,.bak}
406-# Recreate the folder using systemd-tmpfiles
407-systemd-tmpfiles --create
408-# Get a new account and reissue certificates
409-# Note: Do this for all certs that share the same account email address
410-systemctl start acme-example.com.service
411-</programlisting>
412-413- </section>
414-</chapter>
···1+# BorgBackup {#module-borgbase}
2+3+*Source:* {file}`modules/services/backup/borgbackup.nix`
4+5+*Upstream documentation:* <https://borgbackup.readthedocs.io/>
6+7+[BorgBackup](https://www.borgbackup.org/) (short: Borg)
8+is a deduplicating backup program. Optionally, it supports compression and
9+authenticated encryption.
10+11+The main goal of Borg is to provide an efficient and secure way to backup
12+data. The data deduplication technique used makes Borg suitable for daily
13+backups since only changes are stored. The authenticated encryption technique
14+makes it suitable for backups to not fully trusted targets.
15+16+## Configuring {#module-services-backup-borgbackup-configuring}
17+18+A complete list of options for the Borgbase module may be found
19+[here](#opt-services.borgbackup.jobs).
20+21+## Basic usage for a local backup {#opt-services-backup-borgbackup-local-directory}
22+23+A very basic configuration for backing up to a locally accessible directory is:
24+```
25+{
26+ opt.services.borgbackup.jobs = {
27+ { rootBackup = {
28+ paths = "/";
29+ exclude = [ "/nix" "/path/to/local/repo" ];
30+ repo = "/path/to/local/repo";
31+ doInit = true;
32+ encryption = {
33+ mode = "repokey";
34+ passphrase = "secret";
35+ };
36+ compression = "auto,lzma";
37+ startAt = "weekly";
38+ };
39+ }
40+ };
41+}
42+```
43+44+::: {.warning}
45+If you do not want the passphrase to be stored in the world-readable
46+Nix store, use passCommand. You find an example below.
47+:::
48+49+## Create a borg backup server {#opt-services-backup-create-server}
50+51+You should use a different SSH key for each repository you write to,
52+because the specified keys are restricted to running borg serve and can only
53+access this single repository. You need the output of the generate pub file.
54+55+```ShellSession
56+# sudo ssh-keygen -N '' -t ed25519 -f /run/keys/id_ed25519_my_borg_repo
57+# cat /run/keys/id_ed25519_my_borg_repo
58+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID78zmOyA+5uPG4Ot0hfAy+sLDPU1L4AiIoRYEIVbbQ/ root@nixos
59+```
60+61+Add the following snippet to your NixOS configuration:
62+```
63+{
64+ services.borgbackup.repos = {
65+ my_borg_repo = {
66+ authorizedKeys = [
67+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID78zmOyA+5uPG4Ot0hfAy+sLDPU1L4AiIoRYEIVbbQ/ root@nixos"
68+ ] ;
69+ path = "/var/lib/my_borg_repo" ;
70+ };
71+ };
72+}
73+```
74+75+## Backup to the borg repository server {#opt-services-backup-borgbackup-remote-server}
76+77+The following NixOS snippet creates an hourly backup to the service
78+(on the host nixos) as created in the section above. We assume
79+that you have stored a secret passphrasse in the file
80+{file}`/run/keys/borgbackup_passphrase`, which should be only
81+accessible by root
82+83+```
84+{
85+ services.borgbackup.jobs = {
86+ backupToLocalServer = {
87+ paths = [ "/etc/nixos" ];
88+ doInit = true;
89+ repo = "borg@nixos:." ;
90+ encryption = {
91+ mode = "repokey-blake2";
92+ passCommand = "cat /run/keys/borgbackup_passphrase";
93+ };
94+ environment = { BORG_RSH = "ssh -i /run/keys/id_ed25519_my_borg_repo"; };
95+ compression = "auto,lzma";
96+ startAt = "hourly";
97+ };
98+ };
99+};
100+```
101+102+The following few commands (run as root) let you test your backup.
103+```
104+> nixos-rebuild switch
105+...restarting the following units: polkit.service
106+> systemctl restart borgbackup-job-backupToLocalServer
107+> sleep 10
108+> systemctl restart borgbackup-job-backupToLocalServer
109+> export BORG_PASSPHRASE=topSecrect
110+> borg list --rsh='ssh -i /run/keys/id_ed25519_my_borg_repo' borg@nixos:.
111+nixos-backupToLocalServer-2020-03-30T21:46:17 Mon, 2020-03-30 21:46:19 [84feb97710954931ca384182f5f3cb90665f35cef214760abd7350fb064786ac]
112+nixos-backupToLocalServer-2020-03-30T21:46:30 Mon, 2020-03-30 21:46:32 [e77321694ecd160ca2228611747c6ad1be177d6e0d894538898de7a2621b6e68]
113+```
114+115+## Backup to a hosting service {#opt-services-backup-borgbackup-borgbase}
116+117+Several companies offer [(paid) hosting services](https://www.borgbackup.org/support/commercial.html)
118+for Borg repositories.
119+120+To backup your home directory to borgbase you have to:
121+122+ - Generate a SSH key without a password, to access the remote server. E.g.
123+124+ sudo ssh-keygen -N '' -t ed25519 -f /run/keys/id_ed25519_borgbase
125+126+ - Create the repository on the server by following the instructions for your
127+ hosting server.
128+ - Initialize the repository on the server. Eg.
129+130+ sudo borg init --encryption=repokey-blake2 \
131+ -rsh "ssh -i /run/keys/id_ed25519_borgbase" \
132+ zzz2aaaaa@zzz2aaaaa.repo.borgbase.com:repo
133+134+ - Add it to your NixOS configuration, e.g.
135+136+ {
137+ services.borgbackup.jobs = {
138+ my_Remote_Backup = {
139+ paths = [ "/" ];
140+ exclude = [ "/nix" "'**/.cache'" ];
141+ repo = "zzz2aaaaa@zzz2aaaaa.repo.borgbase.com:repo";
142+ encryption = {
143+ mode = "repokey-blake2";
144+ passCommand = "cat /run/keys/borgbackup_passphrase";
145+ };
146+ environment = { BORG_RSH = "ssh -i /run/keys/id_ed25519_borgbase"; };
147+ compression = "auto,lzma";
148+ startAt = "daily";
149+ };
150+ };
151+ }}
152+153+## Vorta backup client for the desktop {#opt-services-backup-borgbackup-vorta}
154+155+Vorta is a backup client for macOS and Linux desktops. It integrates the
156+mighty BorgBackup with your desktop environment to protect your data from
157+disk failure, ransomware and theft.
158+159+It can be installed in NixOS e.g. by adding `pkgs.vorta`
160+to [](#opt-environment.systemPackages).
161+162+Details about using Vorta can be found under
163+[https://vorta.borgbase.com](https://vorta.borgbase.com/usage) .
+164-158
nixos/modules/services/backup/borgbackup.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-borgbase">
6- <title>BorgBackup</title>
7 <para>
8- <emphasis>Source:</emphasis>
9- <filename>modules/services/backup/borgbackup.nix</filename>
10- </para>
11- <para>
12- <emphasis>Upstream documentation:</emphasis>
13- <link xlink:href="https://borgbackup.readthedocs.io/"/>
14- </para>
15- <para>
16- <link xlink:href="https://www.borgbackup.org/">BorgBackup</link> (short: Borg)
17- is a deduplicating backup program. Optionally, it supports compression and
18- authenticated encryption.
19 </para>
20 <para>
21- The main goal of Borg is to provide an efficient and secure way to backup
22- data. The data deduplication technique used makes Borg suitable for daily
23- backups since only changes are stored. The authenticated encryption technique
24- makes it suitable for backups to not fully trusted targets.
25- </para>
26- <section xml:id="module-services-backup-borgbackup-configuring">
27- <title>Configuring</title>
28 <para>
29- A complete list of options for the Borgbase module may be found
30- <link linkend="opt-services.borgbackup.jobs">here</link>.
031 </para>
32-</section>
33- <section xml:id="opt-services-backup-borgbackup-local-directory">
34- <title>Basic usage for a local backup</title>
35-36 <para>
37- A very basic configuration for backing up to a locally accessible directory
38- is:
39-<programlisting>
0000000000000000040{
41 opt.services.borgbackup.jobs = {
42 { rootBackup = {
43- paths = "/";
44- exclude = [ "/nix" "/path/to/local/repo" ];
45- repo = "/path/to/local/repo";
46 doInit = true;
47 encryption = {
48- mode = "repokey";
49- passphrase = "secret";
50 };
51- compression = "auto,lzma";
52- startAt = "weekly";
53 };
54 }
55 };
56-}</programlisting>
57- </para>
58- <warning>
59- <para>
60- If you do not want the passphrase to be stored in the world-readable
61- Nix store, use passCommand. You find an example below.
62- </para>
63- </warning>
64- </section>
65-<section xml:id="opt-services-backup-create-server">
66- <title>Create a borg backup server</title>
67- <para>You should use a different SSH key for each repository you write to,
68- because the specified keys are restricted to running borg serve and can only
69- access this single repository. You need the output of the generate pub file.
70- </para>
71 <para>
72-<screen>
73-<prompt># </prompt>sudo ssh-keygen -N '' -t ed25519 -f /run/keys/id_ed25519_my_borg_repo
74-<prompt># </prompt>cat /run/keys/id_ed25519_my_borg_repo
75-ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID78zmOyA+5uPG4Ot0hfAy+sLDPU1L4AiIoRYEIVbbQ/ root@nixos</screen>
76 </para>
0000077 <para>
78 Add the following snippet to your NixOS configuration:
79- <programlisting>
080{
81 services.borgbackup.repos = {
82 my_borg_repo = {
83 authorizedKeys = [
84- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID78zmOyA+5uPG4Ot0hfAy+sLDPU1L4AiIoRYEIVbbQ/ root@nixos"
85 ] ;
86- path = "/var/lib/my_borg_repo" ;
87 };
88 };
89-}</programlisting>
000000000090 </para>
91-</section>
92-93- <section xml:id="opt-services-backup-borgbackup-remote-server">
94- <title>Backup to the borg repository server</title>
95- <para>The following NixOS snippet creates an hourly backup to the service
96- (on the host nixos) as created in the section above. We assume
97- that you have stored a secret passphrasse in the file
98- <code>/run/keys/borgbackup_passphrase</code>, which should be only
99- accessible by root
100- </para>
101- <para>
102- <programlisting>
103{
104 services.borgbackup.jobs = {
105 backupToLocalServer = {
106- paths = [ "/etc/nixos" ];
107 doInit = true;
108- repo = "borg@nixos:." ;
109 encryption = {
110- mode = "repokey-blake2";
111- passCommand = "cat /run/keys/borgbackup_passphrase";
112 };
113- environment = { BORG_RSH = "ssh -i /run/keys/id_ed25519_my_borg_repo"; };
114- compression = "auto,lzma";
115- startAt = "hourly";
116 };
117 };
118-};</programlisting>
119- </para>
120- <para>The following few commands (run as root) let you test your backup.
121- <programlisting>
122-> nixos-rebuild switch
00123...restarting the following units: polkit.service
124-> systemctl restart borgbackup-job-backupToLocalServer
125-> sleep 10
126-> systemctl restart borgbackup-job-backupToLocalServer
127-> export BORG_PASSPHRASE=topSecrect
128-> borg list --rsh='ssh -i /run/keys/id_ed25519_my_borg_repo' borg@nixos:.
129nixos-backupToLocalServer-2020-03-30T21:46:17 Mon, 2020-03-30 21:46:19 [84feb97710954931ca384182f5f3cb90665f35cef214760abd7350fb064786ac]
130-nixos-backupToLocalServer-2020-03-30T21:46:30 Mon, 2020-03-30 21:46:32 [e77321694ecd160ca2228611747c6ad1be177d6e0d894538898de7a2621b6e68]</programlisting>
131- </para>
132-</section>
133-134- <section xml:id="opt-services-backup-borgbackup-borgbase">
135- <title>Backup to a hosting service</title>
136-137- <para>
138- Several companies offer <link
139- xlink:href="https://www.borgbackup.org/support/commercial.html">(paid)
140 hosting services</link> for Borg repositories.
141- </para>
142- <para>
143- To backup your home directory to borgbase you have to:
144- </para>
145- <itemizedlist>
146- <listitem>
147- <para>
148- Generate a SSH key without a password, to access the remote server. E.g.
149 </para>
150 <para>
151- <programlisting>sudo ssh-keygen -N '' -t ed25519 -f /run/keys/id_ed25519_borgbase</programlisting>
152- </para>
153- </listitem>
154- <listitem>
155- <para>
156- Create the repository on the server by following the instructions for your
157- hosting server.
158 </para>
159- </listitem>
160- <listitem>
161- <para>
162- Initialize the repository on the server. Eg.
163- <programlisting>
0000000000000000164sudo borg init --encryption=repokey-blake2 \
165- -rsh "ssh -i /run/keys/id_ed25519_borgbase" \
166- zzz2aaaaa@zzz2aaaaa.repo.borgbase.com:repo</programlisting>
167- </para>
168- </listitem>
169- <listitem>
170-<para>Add it to your NixOS configuration, e.g.
171-<programlisting>
00172{
173 services.borgbackup.jobs = {
174 my_Remote_Backup = {
175- paths = [ "/" ];
176- exclude = [ "/nix" "'**/.cache'" ];
177- repo = "zzz2aaaaa@zzz2aaaaa.repo.borgbase.com:repo";
178 encryption = {
179- mode = "repokey-blake2";
180- passCommand = "cat /run/keys/borgbackup_passphrase";
181 };
182- environment = { BORG_RSH = "ssh -i /run/keys/id_ed25519_borgbase"; };
183- compression = "auto,lzma";
184- startAt = "daily";
185 };
186 };
187-}}</programlisting>
188- </para>
189- </listitem>
190-</itemizedlist>
191- </section>
192 <section xml:id="opt-services-backup-borgbackup-vorta">
193- <title>Vorta backup client for the desktop</title>
194- <para>
195- Vorta is a backup client for macOS and Linux desktops. It integrates the
196- mighty BorgBackup with your desktop environment to protect your data from
197- disk failure, ransomware and theft.
198- </para>
199- <para>
200- It can be installed in NixOS e.g. by adding <package>pkgs.vorta</package>
201- to <xref linkend="opt-environment.systemPackages" />.
202- </para>
203- <para>
204- Details about using Vorta can be found under <link
205- xlink:href="https://vorta.borgbase.com/usage">https://vorta.borgbase.com
206- </link>.
207- </para>
208- </section>
0209</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-borgbase">
4+ <title>BorgBackup</title>
005 <para>
6+ <emphasis>Source:</emphasis>
7+ <filename>modules/services/backup/borgbackup.nix</filename>
0000000008 </para>
9 <para>
10+ <emphasis>Upstream documentation:</emphasis>
11+ <link xlink:href="https://borgbackup.readthedocs.io/">https://borgbackup.readthedocs.io/</link>
12+ </para>
000013 <para>
14+ <link xlink:href="https://www.borgbackup.org/">BorgBackup</link>
15+ (short: Borg) is a deduplicating backup program. Optionally, it
16+ supports compression and authenticated encryption.
17 </para>
000018 <para>
19+ The main goal of Borg is to provide an efficient and secure way to
20+ backup data. The data deduplication technique used makes Borg
21+ suitable for daily backups since only changes are stored. The
22+ authenticated encryption technique makes it suitable for backups to
23+ not fully trusted targets.
24+ </para>
25+ <section xml:id="module-services-backup-borgbackup-configuring">
26+ <title>Configuring</title>
27+ <para>
28+ A complete list of options for the Borgbase module may be found
29+ <link linkend="opt-services.borgbackup.jobs">here</link>.
30+ </para>
31+ </section>
32+ <section xml:id="opt-services-backup-borgbackup-local-directory">
33+ <title>Basic usage for a local backup</title>
34+ <para>
35+ A very basic configuration for backing up to a locally accessible
36+ directory is:
37+ </para>
38+ <programlisting>
39{
40 opt.services.borgbackup.jobs = {
41 { rootBackup = {
42+ paths = "/";
43+ exclude = [ "/nix" "/path/to/local/repo" ];
44+ repo = "/path/to/local/repo";
45 doInit = true;
46 encryption = {
47+ mode = "repokey";
48+ passphrase = "secret";
49 };
50+ compression = "auto,lzma";
51+ startAt = "weekly";
52 };
53 }
54 };
55+}
56+</programlisting>
57+ <warning>
58+ <para>
59+ If you do not want the passphrase to be stored in the
60+ world-readable Nix store, use passCommand. You find an example
61+ below.
62+ </para>
63+ </warning>
64+ </section>
65+ <section xml:id="opt-services-backup-create-server">
66+ <title>Create a borg backup server</title>
00067 <para>
68+ You should use a different SSH key for each repository you write
69+ to, because the specified keys are restricted to running borg
70+ serve and can only access this single repository. You need the
71+ output of the generate pub file.
72 </para>
73+ <programlisting>
74+# sudo ssh-keygen -N '' -t ed25519 -f /run/keys/id_ed25519_my_borg_repo
75+# cat /run/keys/id_ed25519_my_borg_repo
76+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID78zmOyA+5uPG4Ot0hfAy+sLDPU1L4AiIoRYEIVbbQ/ root@nixos
77+</programlisting>
78 <para>
79 Add the following snippet to your NixOS configuration:
80+ </para>
81+ <programlisting>
82{
83 services.borgbackup.repos = {
84 my_borg_repo = {
85 authorizedKeys = [
86+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID78zmOyA+5uPG4Ot0hfAy+sLDPU1L4AiIoRYEIVbbQ/ root@nixos"
87 ] ;
88+ path = "/var/lib/my_borg_repo" ;
89 };
90 };
91+}
92+</programlisting>
93+ </section>
94+ <section xml:id="opt-services-backup-borgbackup-remote-server">
95+ <title>Backup to the borg repository server</title>
96+ <para>
97+ The following NixOS snippet creates an hourly backup to the
98+ service (on the host nixos) as created in the section above. We
99+ assume that you have stored a secret passphrasse in the file
100+ <filename>/run/keys/borgbackup_passphrase</filename>, which should
101+ be only accessible by root
102 </para>
103+ <programlisting>
00000000000104{
105 services.borgbackup.jobs = {
106 backupToLocalServer = {
107+ paths = [ "/etc/nixos" ];
108 doInit = true;
109+ repo = "borg@nixos:." ;
110 encryption = {
111+ mode = "repokey-blake2";
112+ passCommand = "cat /run/keys/borgbackup_passphrase";
113 };
114+ environment = { BORG_RSH = "ssh -i /run/keys/id_ed25519_my_borg_repo"; };
115+ compression = "auto,lzma";
116+ startAt = "hourly";
117 };
118 };
119+};
120+</programlisting>
121+ <para>
122+ The following few commands (run as root) let you test your backup.
123+ </para>
124+ <programlisting>
125+> nixos-rebuild switch
126...restarting the following units: polkit.service
127+> systemctl restart borgbackup-job-backupToLocalServer
128+> sleep 10
129+> systemctl restart borgbackup-job-backupToLocalServer
130+> export BORG_PASSPHRASE=topSecrect
131+> borg list --rsh='ssh -i /run/keys/id_ed25519_my_borg_repo' borg@nixos:.
132nixos-backupToLocalServer-2020-03-30T21:46:17 Mon, 2020-03-30 21:46:19 [84feb97710954931ca384182f5f3cb90665f35cef214760abd7350fb064786ac]
133+nixos-backupToLocalServer-2020-03-30T21:46:30 Mon, 2020-03-30 21:46:32 [e77321694ecd160ca2228611747c6ad1be177d6e0d894538898de7a2621b6e68]
134+</programlisting>
135+ </section>
136+ <section xml:id="opt-services-backup-borgbackup-borgbase">
137+ <title>Backup to a hosting service</title>
138+ <para>
139+ Several companies offer
140+ <link xlink:href="https://www.borgbackup.org/support/commercial.html">(paid)
00141 hosting services</link> for Borg repositories.
00000000142 </para>
143 <para>
144+ To backup your home directory to borgbase you have to:
000000145 </para>
146+ <itemizedlist>
147+ <listitem>
148+ <para>
149+ Generate a SSH key without a password, to access the remote
150+ server. E.g.
151+ </para>
152+ <programlisting>
153+sudo ssh-keygen -N '' -t ed25519 -f /run/keys/id_ed25519_borgbase
154+</programlisting>
155+ </listitem>
156+ <listitem>
157+ <para>
158+ Create the repository on the server by following the
159+ instructions for your hosting server.
160+ </para>
161+ </listitem>
162+ <listitem>
163+ <para>
164+ Initialize the repository on the server. Eg.
165+ </para>
166+ <programlisting>
167sudo borg init --encryption=repokey-blake2 \
168+ -rsh "ssh -i /run/keys/id_ed25519_borgbase" \
169+ zzz2aaaaa@zzz2aaaaa.repo.borgbase.com:repo
170+</programlisting>
171+ </listitem>
172+ <listitem>
173+ <para>
174+ Add it to your NixOS configuration, e.g.
175+ </para>
176+ <programlisting>
177{
178 services.borgbackup.jobs = {
179 my_Remote_Backup = {
180+ paths = [ "/" ];
181+ exclude = [ "/nix" "'**/.cache'" ];
182+ repo = "zzz2aaaaa@zzz2aaaaa.repo.borgbase.com:repo";
183 encryption = {
184+ mode = "repokey-blake2";
185+ passCommand = "cat /run/keys/borgbackup_passphrase";
186 };
187+ environment = { BORG_RSH = "ssh -i /run/keys/id_ed25519_borgbase"; };
188+ compression = "auto,lzma";
189+ startAt = "daily";
190 };
191 };
192+}}
193+</programlisting>
194+ </listitem>
195+ </itemizedlist>
196+ </section>
197 <section xml:id="opt-services-backup-borgbackup-vorta">
198+ <title>Vorta backup client for the desktop</title>
199+ <para>
200+ Vorta is a backup client for macOS and Linux desktops. It
201+ integrates the mighty BorgBackup with your desktop environment to
202+ protect your data from disk failure, ransomware and theft.
203+ </para>
204+ <para>
205+ It can be installed in NixOS e.g. by adding
206+ <literal>pkgs.vorta</literal> to
207+ <xref linkend="opt-environment.systemPackages" />.
208+ </para>
209+ <para>
210+ Details about using Vorta can be found under
211+ <link xlink:href="https://vorta.borgbase.com/usage">https://vorta.borgbase.com</link>
212+ .
213+ </para>
214+ </section>
215</chapter>
···1+# FoundationDB {#module-services-foundationdb}
2+3+*Source:* {file}`modules/services/databases/foundationdb.nix`
4+5+*Upstream documentation:* <https://apple.github.io/foundationdb/>
6+7+*Maintainer:* Austin Seipp
8+9+*Available version(s):* 5.1.x, 5.2.x, 6.0.x
10+11+FoundationDB (or "FDB") is an open source, distributed, transactional
12+key-value store.
13+14+## Configuring and basic setup {#module-services-foundationdb-configuring}
15+16+To enable FoundationDB, add the following to your
17+{file}`configuration.nix`:
18+```
19+services.foundationdb.enable = true;
20+services.foundationdb.package = pkgs.foundationdb52; # FoundationDB 5.2.x
21+```
22+23+The {option}`services.foundationdb.package` option is required, and
24+must always be specified. Due to the fact FoundationDB network protocols and
25+on-disk storage formats may change between (major) versions, and upgrades
26+must be explicitly handled by the user, you must always manually specify
27+this yourself so that the NixOS module will use the proper version. Note
28+that minor, bugfix releases are always compatible.
29+30+After running {command}`nixos-rebuild`, you can verify whether
31+FoundationDB is running by executing {command}`fdbcli` (which is
32+added to {option}`environment.systemPackages`):
33+```ShellSession
34+$ sudo -u foundationdb fdbcli
35+Using cluster file `/etc/foundationdb/fdb.cluster'.
36+37+The database is available.
38+39+Welcome to the fdbcli. For help, type `help'.
40+fdb> status
41+42+Using cluster file `/etc/foundationdb/fdb.cluster'.
43+44+Configuration:
45+ Redundancy mode - single
46+ Storage engine - memory
47+ Coordinators - 1
48+49+Cluster:
50+ FoundationDB processes - 1
51+ Machines - 1
52+ Memory availability - 5.4 GB per process on machine with least available
53+ Fault Tolerance - 0 machines
54+ Server time - 04/20/18 15:21:14
55+56+...
57+58+fdb>
59+```
60+61+You can also write programs using the available client libraries. For
62+example, the following Python program can be run in order to grab the
63+cluster status, as a quick example. (This example uses
64+{command}`nix-shell` shebang support to automatically supply the
65+necessary Python modules).
66+```ShellSession
67+a@link> cat fdb-status.py
68+#! /usr/bin/env nix-shell
69+#! nix-shell -i python -p python pythonPackages.foundationdb52
70+71+import fdb
72+import json
73+74+def main():
75+ fdb.api_version(520)
76+ db = fdb.open()
77+78+ @fdb.transactional
79+ def get_status(tr):
80+ return str(tr['\xff\xff/status/json'])
81+82+ obj = json.loads(get_status(db))
83+ print('FoundationDB available: %s' % obj['client']['database_status']['available'])
84+85+if __name__ == "__main__":
86+ main()
87+a@link> chmod +x fdb-status.py
88+a@link> ./fdb-status.py
89+FoundationDB available: True
90+a@link>
91+```
92+93+FoundationDB is run under the {command}`foundationdb` user and group
94+by default, but this may be changed in the NixOS configuration. The systemd
95+unit {command}`foundationdb.service` controls the
96+{command}`fdbmonitor` process.
97+98+By default, the NixOS module for FoundationDB creates a single SSD-storage
99+based database for development and basic usage. This storage engine is
100+designed for SSDs and will perform poorly on HDDs; however it can handle far
101+more data than the alternative "memory" engine and is a better default
102+choice for most deployments. (Note that you can change the storage backend
103+on-the-fly for a given FoundationDB cluster using
104+{command}`fdbcli`.)
105+106+Furthermore, only 1 server process and 1 backup agent are started in the
107+default configuration. See below for more on scaling to increase this.
108+109+FoundationDB stores all data for all server processes under
110+{file}`/var/lib/foundationdb`. You can override this using
111+{option}`services.foundationdb.dataDir`, e.g.
112+```
113+services.foundationdb.dataDir = "/data/fdb";
114+```
115+116+Similarly, logs are stored under {file}`/var/log/foundationdb`
117+by default, and there is a corresponding
118+{option}`services.foundationdb.logDir` as well.
119+120+## Scaling processes and backup agents {#module-services-foundationdb-scaling}
121+122+Scaling the number of server processes is quite easy; simply specify
123+{option}`services.foundationdb.serverProcesses` to be the number of
124+FoundationDB worker processes that should be started on the machine.
125+126+FoundationDB worker processes typically require 4GB of RAM per-process at
127+minimum for good performance, so this option is set to 1 by default since
128+the maximum amount of RAM is unknown. You're advised to abide by this
129+restriction, so pick a number of processes so that each has 4GB or more.
130+131+A similar option exists in order to scale backup agent processes,
132+{option}`services.foundationdb.backupProcesses`. Backup agents are
133+not as performance/RAM sensitive, so feel free to experiment with the number
134+of available backup processes.
135+136+## Clustering {#module-services-foundationdb-clustering}
137+138+FoundationDB on NixOS works similarly to other Linux systems, so this
139+section will be brief. Please refer to the full FoundationDB documentation
140+for more on clustering.
141+142+FoundationDB organizes clusters using a set of
143+*coordinators*, which are just specially-designated
144+worker processes. By default, every installation of FoundationDB on NixOS
145+will start as its own individual cluster, with a single coordinator: the
146+first worker process on {command}`localhost`.
147+148+Coordinators are specified globally using the
149+{command}`/etc/foundationdb/fdb.cluster` file, which all servers and
150+client applications will use to find and join coordinators. Note that this
151+file *can not* be managed by NixOS so easily:
152+FoundationDB is designed so that it will rewrite the file at runtime for all
153+clients and nodes when cluster coordinators change, with clients
154+transparently handling this without intervention. It is fundamentally a
155+mutable file, and you should not try to manage it in any way in NixOS.
156+157+When dealing with a cluster, there are two main things you want to do:
158+159+ - Add a node to the cluster for storage/compute.
160+ - Promote an ordinary worker to a coordinator.
161+162+A node must already be a member of the cluster in order to properly be
163+promoted to a coordinator, so you must always add it first if you wish to
164+promote it.
165+166+To add a machine to a FoundationDB cluster:
167+168+ - Choose one of the servers to start as the initial coordinator.
169+ - Copy the {command}`/etc/foundationdb/fdb.cluster` file from this
170+ server to all the other servers. Restart FoundationDB on all of these
171+ other servers, so they join the cluster.
172+ - All of these servers are now connected and working together in the
173+ cluster, under the chosen coordinator.
174+175+At this point, you can add as many nodes as you want by just repeating the
176+above steps. By default there will still be a single coordinator: you can
177+use {command}`fdbcli` to change this and add new coordinators.
178+179+As a convenience, FoundationDB can automatically assign coordinators based
180+on the redundancy mode you wish to achieve for the cluster. Once all the
181+nodes have been joined, simply set the replication policy, and then issue
182+the {command}`coordinators auto` command
183+184+For example, assuming we have 3 nodes available, we can enable double
185+redundancy mode, then auto-select coordinators. For double redundancy, 3
186+coordinators is ideal: therefore FoundationDB will make
187+*every* node a coordinator automatically:
188+189+```ShellSession
190+fdbcli> configure double ssd
191+fdbcli> coordinators auto
192+```
193+194+This will transparently update all the servers within seconds, and
195+appropriately rewrite the {command}`fdb.cluster` file, as well as
196+informing all client processes to do the same.
197+198+## Client connectivity {#module-services-foundationdb-connectivity}
199+200+By default, all clients must use the current {command}`fdb.cluster`
201+file to access a given FoundationDB cluster. This file is located by default
202+in {command}`/etc/foundationdb/fdb.cluster` on all machines with the
203+FoundationDB service enabled, so you may copy the active one from your
204+cluster to a new node in order to connect, if it is not part of the cluster.
205+206+## Client authorization and TLS {#module-services-foundationdb-authorization}
207+208+By default, any user who can connect to a FoundationDB process with the
209+correct cluster configuration can access anything. FoundationDB uses a
210+pluggable design to transport security, and out of the box it supports a
211+LibreSSL-based plugin for TLS support. This plugin not only does in-flight
212+encryption, but also performs client authorization based on the given
213+endpoint's certificate chain. For example, a FoundationDB server may be
214+configured to only accept client connections over TLS, where the client TLS
215+certificate is from organization *Acme Co* in the
216+*Research and Development* unit.
217+218+Configuring TLS with FoundationDB is done using the
219+{option}`services.foundationdb.tls` options in order to control the
220+peer verification string, as well as the certificate and its private key.
221+222+Note that the certificate and its private key must be accessible to the
223+FoundationDB user account that the server runs under. These files are also
224+NOT managed by NixOS, as putting them into the store may reveal private
225+information.
226+227+After you have a key and certificate file in place, it is not enough to
228+simply set the NixOS module options -- you must also configure the
229+{command}`fdb.cluster` file to specify that a given set of
230+coordinators use TLS. This is as simple as adding the suffix
231+{command}`:tls` to your cluster coordinator configuration, after the
232+port number. For example, assuming you have a coordinator on localhost with
233+the default configuration, simply specifying:
234+235+```
236+XXXXXX:XXXXXX@127.0.0.1:4500:tls
237+```
238+239+will configure all clients and server processes to use TLS from now on.
240+241+## Backups and Disaster Recovery {#module-services-foundationdb-disaster-recovery}
242+243+The usual rules for doing FoundationDB backups apply on NixOS as written in
244+the FoundationDB manual. However, one important difference is the security
245+profile for NixOS: by default, the {command}`foundationdb` systemd
246+unit uses *Linux namespaces* to restrict write access to
247+the system, except for the log directory, data directory, and the
248+{command}`/etc/foundationdb/` directory. This is enforced by default
249+and cannot be disabled.
250+251+However, a side effect of this is that the {command}`fdbbackup`
252+command doesn't work properly for local filesystem backups: FoundationDB
253+uses a server process alongside the database processes to perform backups
254+and copy the backups to the filesystem. As a result, this process is put
255+under the restricted namespaces above: the backup process can only write to
256+a limited number of paths.
257+258+In order to allow flexible backup locations on local disks, the FoundationDB
259+NixOS module supports a
260+{option}`services.foundationdb.extraReadWritePaths` option. This
261+option takes a list of paths, and adds them to the systemd unit, allowing
262+the processes inside the service to write (and read) the specified
263+directories.
264+265+For example, to create backups in {command}`/opt/fdb-backups`, first
266+set up the paths in the module options:
267+268+```
269+services.foundationdb.extraReadWritePaths = [ "/opt/fdb-backups" ];
270+```
271+272+Restart the FoundationDB service, and it will now be able to write to this
273+directory (even if it does not yet exist.) Note: this path
274+*must* exist before restarting the unit. Otherwise,
275+systemd will not include it in the private FoundationDB namespace (and it
276+will not add it dynamically at runtime).
277+278+You can now perform a backup:
279+280+```ShellSession
281+$ sudo -u foundationdb fdbbackup start -t default -d file:///opt/fdb-backups
282+$ sudo -u foundationdb fdbbackup status -t default
283+```
284+285+## Known limitations {#module-services-foundationdb-limitations}
286+287+The FoundationDB setup for NixOS should currently be considered beta.
288+FoundationDB is not new software, but the NixOS compilation and integration
289+has only undergone fairly basic testing of all the available functionality.
290+291+ - There is no way to specify individual parameters for individual
292+ {command}`fdbserver` processes. Currently, all server processes
293+ inherit all the global {command}`fdbmonitor` settings.
294+ - Ruby bindings are not currently installed.
295+ - Go bindings are not currently installed.
296+297+## Options {#module-services-foundationdb-options}
298+299+NixOS's FoundationDB module allows you to configure all of the most relevant
300+configuration options for {command}`fdbmonitor`, matching it quite
301+closely. A complete list of options for the FoundationDB module may be found
302+[here](#opt-services.foundationdb.enable). You should
303+also read the FoundationDB documentation as well.
304+305+## Full documentation {#module-services-foundationdb-full-docs}
306+307+FoundationDB is a complex piece of software, and requires careful
308+administration to properly use. Full documentation for administration can be
309+found here: <https://apple.github.io/foundationdb/>.
+358-376
nixos/modules/services/databases/foundationdb.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-foundationdb">
6- <title>FoundationDB</title>
7- <para>
8- <emphasis>Source:</emphasis>
9- <filename>modules/services/databases/foundationdb.nix</filename>
10- </para>
11- <para>
12- <emphasis>Upstream documentation:</emphasis>
13- <link xlink:href="https://apple.github.io/foundationdb/"/>
14- </para>
15- <para>
16- <emphasis>Maintainer:</emphasis> Austin Seipp
17- </para>
18- <para>
19- <emphasis>Available version(s):</emphasis> 5.1.x, 5.2.x, 6.0.x
20- </para>
21- <para>
22- FoundationDB (or "FDB") is an open source, distributed, transactional
23- key-value store.
24- </para>
25- <section xml:id="module-services-foundationdb-configuring">
26- <title>Configuring and basic setup</title>
27-28 <para>
29- To enable FoundationDB, add the following to your
30- <filename>configuration.nix</filename>:
31-<programlisting>
32-services.foundationdb.enable = true;
33-services.foundationdb.package = pkgs.foundationdb52; # FoundationDB 5.2.x
34-</programlisting>
35 </para>
36-37 <para>
38- The <option>services.foundationdb.package</option> option is required, and
39- must always be specified. Due to the fact FoundationDB network protocols and
40- on-disk storage formats may change between (major) versions, and upgrades
41- must be explicitly handled by the user, you must always manually specify
42- this yourself so that the NixOS module will use the proper version. Note
43- that minor, bugfix releases are always compatible.
44 </para>
45-0046 <para>
47- After running <command>nixos-rebuild</command>, you can verify whether
48- FoundationDB is running by executing <command>fdbcli</command> (which is
49- added to <option>environment.systemPackages</option>):
50-<screen>
51-<prompt>$ </prompt>sudo -u foundationdb fdbcli
000000000000000000000000000052Using cluster file `/etc/foundationdb/fdb.cluster'.
5354The database is available.
5556Welcome to the fdbcli. For help, type `help'.
57-<prompt>fdb> </prompt>status
5859Using cluster file `/etc/foundationdb/fdb.cluster'.
60···7273...
7475-<prompt>fdb></prompt>
76-</screen>
77- </para>
78-79- <para>
80- You can also write programs using the available client libraries. For
81- example, the following Python program can be run in order to grab the
82- cluster status, as a quick example. (This example uses
83- <command>nix-shell</command> shebang support to automatically supply the
84- necessary Python modules).
85-<screen>
86-<prompt>a@link> </prompt>cat fdb-status.py
87#! /usr/bin/env nix-shell
88#! nix-shell -i python -p python pythonPackages.foundationdb52
89···101 obj = json.loads(get_status(db))
102 print('FoundationDB available: %s' % obj['client']['database_status']['available'])
103104-if __name__ == "__main__":
105 main()
106-<prompt>a@link> </prompt>chmod +x fdb-status.py
107-<prompt>a@link> </prompt>./fdb-status.py
108FoundationDB available: True
109-<prompt>a@link></prompt>
110-</screen>
111- </para>
112-113- <para>
114- FoundationDB is run under the <command>foundationdb</command> user and group
115- by default, but this may be changed in the NixOS configuration. The systemd
116- unit <command>foundationdb.service</command> controls the
117- <command>fdbmonitor</command> process.
118- </para>
119-120- <para>
121- By default, the NixOS module for FoundationDB creates a single SSD-storage
122- based database for development and basic usage. This storage engine is
123- designed for SSDs and will perform poorly on HDDs; however it can handle far
124- more data than the alternative "memory" engine and is a better default
125- choice for most deployments. (Note that you can change the storage backend
126- on-the-fly for a given FoundationDB cluster using
127- <command>fdbcli</command>.)
128- </para>
129-130- <para>
131- Furthermore, only 1 server process and 1 backup agent are started in the
132- default configuration. See below for more on scaling to increase this.
133- </para>
134-135- <para>
136- FoundationDB stores all data for all server processes under
137- <filename>/var/lib/foundationdb</filename>. You can override this using
138- <option>services.foundationdb.dataDir</option>, e.g.
139-<programlisting>
140-services.foundationdb.dataDir = "/data/fdb";
141</programlisting>
142- </para>
143-144- <para>
145- Similarly, logs are stored under <filename>/var/log/foundationdb</filename>
146- by default, and there is a corresponding
147- <option>services.foundationdb.logDir</option> as well.
148- </para>
149- </section>
150- <section xml:id="module-services-foundationdb-scaling">
151- <title>Scaling processes and backup agents</title>
152-153- <para>
154- Scaling the number of server processes is quite easy; simply specify
155- <option>services.foundationdb.serverProcesses</option> to be the number of
156- FoundationDB worker processes that should be started on the machine.
157- </para>
158-159- <para>
160- FoundationDB worker processes typically require 4GB of RAM per-process at
161- minimum for good performance, so this option is set to 1 by default since
162- the maximum amount of RAM is unknown. You're advised to abide by this
163- restriction, so pick a number of processes so that each has 4GB or more.
164- </para>
165-166- <para>
167- A similar option exists in order to scale backup agent processes,
168- <option>services.foundationdb.backupProcesses</option>. Backup agents are
169- not as performance/RAM sensitive, so feel free to experiment with the number
170- of available backup processes.
171- </para>
172- </section>
173- <section xml:id="module-services-foundationdb-clustering">
174- <title>Clustering</title>
175-176- <para>
177- FoundationDB on NixOS works similarly to other Linux systems, so this
178- section will be brief. Please refer to the full FoundationDB documentation
179- for more on clustering.
180- </para>
181-182- <para>
183- FoundationDB organizes clusters using a set of
184- <emphasis>coordinators</emphasis>, which are just specially-designated
185- worker processes. By default, every installation of FoundationDB on NixOS
186- will start as its own individual cluster, with a single coordinator: the
187- first worker process on <command>localhost</command>.
188- </para>
189-190- <para>
191- Coordinators are specified globally using the
192- <command>/etc/foundationdb/fdb.cluster</command> file, which all servers and
193- client applications will use to find and join coordinators. Note that this
194- file <emphasis>can not</emphasis> be managed by NixOS so easily:
195- FoundationDB is designed so that it will rewrite the file at runtime for all
196- clients and nodes when cluster coordinators change, with clients
197- transparently handling this without intervention. It is fundamentally a
198- mutable file, and you should not try to manage it in any way in NixOS.
199- </para>
200-201- <para>
202- When dealing with a cluster, there are two main things you want to do:
203- </para>
204-205- <itemizedlist>
206- <listitem>
207 <para>
208- Add a node to the cluster for storage/compute.
0000000209 </para>
210- </listitem>
211- <listitem>
212 <para>
213- Promote an ordinary worker to a coordinator.
00214 </para>
215- </listitem>
216- </itemizedlist>
217-218- <para>
219- A node must already be a member of the cluster in order to properly be
220- promoted to a coordinator, so you must always add it first if you wish to
221- promote it.
222- </para>
223-224- <para>
225- To add a machine to a FoundationDB cluster:
226- </para>
227-228- <itemizedlist>
229- <listitem>
230 <para>
231- Choose one of the servers to start as the initial coordinator.
00232 </para>
233- </listitem>
234- <listitem>
0235 <para>
236- Copy the <command>/etc/foundationdb/fdb.cluster</command> file from this
237- server to all the other servers. Restart FoundationDB on all of these
238- other servers, so they join the cluster.
0239 </para>
240- </listitem>
241- <listitem>
0242 <para>
243- All of these servers are now connected and working together in the
244- cluster, under the chosen coordinator.
00245 </para>
246- </listitem>
247- </itemizedlist>
248-249- <para>
250- At this point, you can add as many nodes as you want by just repeating the
251- above steps. By default there will still be a single coordinator: you can
252- use <command>fdbcli</command> to change this and add new coordinators.
253- </para>
254-255- <para>
256- As a convenience, FoundationDB can automatically assign coordinators based
257- on the redundancy mode you wish to achieve for the cluster. Once all the
258- nodes have been joined, simply set the replication policy, and then issue
259- the <command>coordinators auto</command> command
260- </para>
261-262- <para>
263- For example, assuming we have 3 nodes available, we can enable double
264- redundancy mode, then auto-select coordinators. For double redundancy, 3
265- coordinators is ideal: therefore FoundationDB will make
266- <emphasis>every</emphasis> node a coordinator automatically:
267- </para>
268-269-<screen>
270-<prompt>fdbcli> </prompt>configure double ssd
271-<prompt>fdbcli> </prompt>coordinators auto
272-</screen>
273-274- <para>
275- This will transparently update all the servers within seconds, and
276- appropriately rewrite the <command>fdb.cluster</command> file, as well as
277- informing all client processes to do the same.
278- </para>
279- </section>
280- <section xml:id="module-services-foundationdb-connectivity">
281- <title>Client connectivity</title>
282-283- <para>
284- By default, all clients must use the current <command>fdb.cluster</command>
285- file to access a given FoundationDB cluster. This file is located by default
286- in <command>/etc/foundationdb/fdb.cluster</command> on all machines with the
287- FoundationDB service enabled, so you may copy the active one from your
288- cluster to a new node in order to connect, if it is not part of the cluster.
289- </para>
290- </section>
291- <section xml:id="module-services-foundationdb-authorization">
292- <title>Client authorization and TLS</title>
293-294- <para>
295- By default, any user who can connect to a FoundationDB process with the
296- correct cluster configuration can access anything. FoundationDB uses a
297- pluggable design to transport security, and out of the box it supports a
298- LibreSSL-based plugin for TLS support. This plugin not only does in-flight
299- encryption, but also performs client authorization based on the given
300- endpoint's certificate chain. For example, a FoundationDB server may be
301- configured to only accept client connections over TLS, where the client TLS
302- certificate is from organization <emphasis>Acme Co</emphasis> in the
303- <emphasis>Research and Development</emphasis> unit.
304- </para>
305-306- <para>
307- Configuring TLS with FoundationDB is done using the
308- <option>services.foundationdb.tls</option> options in order to control the
309- peer verification string, as well as the certificate and its private key.
310- </para>
311-312- <para>
313- Note that the certificate and its private key must be accessible to the
314- FoundationDB user account that the server runs under. These files are also
315- NOT managed by NixOS, as putting them into the store may reveal private
316- information.
317- </para>
318-319- <para>
320- After you have a key and certificate file in place, it is not enough to
321- simply set the NixOS module options -- you must also configure the
322- <command>fdb.cluster</command> file to specify that a given set of
323- coordinators use TLS. This is as simple as adding the suffix
324- <command>:tls</command> to your cluster coordinator configuration, after the
325- port number. For example, assuming you have a coordinator on localhost with
326- the default configuration, simply specifying:
327- </para>
328-329-<programlisting>
00000000000000000000000000000000000000000000000000000000000000000000000000000000330XXXXXX:XXXXXX@127.0.0.1:4500:tls
331</programlisting>
332-333- <para>
334- will configure all clients and server processes to use TLS from now on.
335- </para>
336- </section>
337- <section xml:id="module-services-foundationdb-disaster-recovery">
338- <title>Backups and Disaster Recovery</title>
339-340- <para>
341- The usual rules for doing FoundationDB backups apply on NixOS as written in
342- the FoundationDB manual. However, one important difference is the security
343- profile for NixOS: by default, the <command>foundationdb</command> systemd
344- unit uses <emphasis>Linux namespaces</emphasis> to restrict write access to
345- the system, except for the log directory, data directory, and the
346- <command>/etc/foundationdb/</command> directory. This is enforced by default
347- and cannot be disabled.
348- </para>
349-350- <para>
351- However, a side effect of this is that the <command>fdbbackup</command>
352- command doesn't work properly for local filesystem backups: FoundationDB
353- uses a server process alongside the database processes to perform backups
354- and copy the backups to the filesystem. As a result, this process is put
355- under the restricted namespaces above: the backup process can only write to
356- a limited number of paths.
357- </para>
358-359- <para>
360- In order to allow flexible backup locations on local disks, the FoundationDB
361- NixOS module supports a
362- <option>services.foundationdb.extraReadWritePaths</option> option. This
363- option takes a list of paths, and adds them to the systemd unit, allowing
364- the processes inside the service to write (and read) the specified
365- directories.
366- </para>
367-368- <para>
369- For example, to create backups in <command>/opt/fdb-backups</command>, first
370- set up the paths in the module options:
371- </para>
372-373-<programlisting>
374-services.foundationdb.extraReadWritePaths = [ "/opt/fdb-backups" ];
375</programlisting>
376-377- <para>
378- Restart the FoundationDB service, and it will now be able to write to this
379- directory (even if it does not yet exist.) Note: this path
380- <emphasis>must</emphasis> exist before restarting the unit. Otherwise,
381- systemd will not include it in the private FoundationDB namespace (and it
382- will not add it dynamically at runtime).
383- </para>
384-385- <para>
386- You can now perform a backup:
387- </para>
388-389-<screen>
390-<prompt>$ </prompt>sudo -u foundationdb fdbbackup start -t default -d file:///opt/fdb-backups
391-<prompt>$ </prompt>sudo -u foundationdb fdbbackup status -t default
392-</screen>
393- </section>
394- <section xml:id="module-services-foundationdb-limitations">
395- <title>Known limitations</title>
396-397- <para>
398- The FoundationDB setup for NixOS should currently be considered beta.
399- FoundationDB is not new software, but the NixOS compilation and integration
400- has only undergone fairly basic testing of all the available functionality.
401- </para>
402-403- <itemizedlist>
404- <listitem>
405 <para>
406- There is no way to specify individual parameters for individual
407- <command>fdbserver</command> processes. Currently, all server processes
408- inherit all the global <command>fdbmonitor</command> settings.
0409 </para>
410- </listitem>
411- <listitem>
000000000000000000000412 <para>
413- Ruby bindings are not currently installed.
00000414 </para>
415- </listitem>
416- <listitem>
0417 <para>
418- Go bindings are not currently installed.
000419 </para>
420- </listitem>
421- </itemizedlist>
422- </section>
423- <section xml:id="module-services-foundationdb-options">
424- <title>Options</title>
425-426- <para>
427- NixOS's FoundationDB module allows you to configure all of the most relevant
428- configuration options for <command>fdbmonitor</command>, matching it quite
429- closely. A complete list of options for the FoundationDB module may be found
430- <link linkend="opt-services.foundationdb.enable">here</link>. You should
431- also read the FoundationDB documentation as well.
432- </para>
433- </section>
434- <section xml:id="module-services-foundationdb-full-docs">
435- <title>Full documentation</title>
436-437- <para>
438- FoundationDB is a complex piece of software, and requires careful
439- administration to properly use. Full documentation for administration can be
440- found here: <link xlink:href="https://apple.github.io/foundationdb/"/>.
441- </para>
442- </section>
443</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-foundationdb">
4+ <title>FoundationDB</title>
000000000000000000000005 <para>
6+ <emphasis>Source:</emphasis>
7+ <filename>modules/services/databases/foundationdb.nix</filename>
00008 </para>
09 <para>
10+ <emphasis>Upstream documentation:</emphasis>
11+ <link xlink:href="https://apple.github.io/foundationdb/">https://apple.github.io/foundationdb/</link>
000012 </para>
13+ <para>
14+ <emphasis>Maintainer:</emphasis> Austin Seipp
15+ </para>
16 <para>
17+ <emphasis>Available version(s):</emphasis> 5.1.x, 5.2.x, 6.0.x
18+ </para>
19+ <para>
20+ FoundationDB (or <quote>FDB</quote>) is an open source, distributed,
21+ transactional key-value store.
22+ </para>
23+ <section xml:id="module-services-foundationdb-configuring">
24+ <title>Configuring and basic setup</title>
25+ <para>
26+ To enable FoundationDB, add the following to your
27+ <filename>configuration.nix</filename>:
28+ </para>
29+ <programlisting>
30+services.foundationdb.enable = true;
31+services.foundationdb.package = pkgs.foundationdb52; # FoundationDB 5.2.x
32+</programlisting>
33+ <para>
34+ The <option>services.foundationdb.package</option> option is
35+ required, and must always be specified. Due to the fact
36+ FoundationDB network protocols and on-disk storage formats may
37+ change between (major) versions, and upgrades must be explicitly
38+ handled by the user, you must always manually specify this
39+ yourself so that the NixOS module will use the proper version.
40+ Note that minor, bugfix releases are always compatible.
41+ </para>
42+ <para>
43+ After running <command>nixos-rebuild</command>, you can verify
44+ whether FoundationDB is running by executing
45+ <command>fdbcli</command> (which is added to
46+ <option>environment.systemPackages</option>):
47+ </para>
48+ <programlisting>
49+$ sudo -u foundationdb fdbcli
50Using cluster file `/etc/foundationdb/fdb.cluster'.
5152The database is available.
5354Welcome to the fdbcli. For help, type `help'.
55+fdb> status
5657Using cluster file `/etc/foundationdb/fdb.cluster'.
58···7071...
7273+fdb>
74+</programlisting>
75+ <para>
76+ You can also write programs using the available client libraries.
77+ For example, the following Python program can be run in order to
78+ grab the cluster status, as a quick example. (This example uses
79+ <command>nix-shell</command> shebang support to automatically
80+ supply the necessary Python modules).
81+ </para>
82+ <programlisting>
83+a@link> cat fdb-status.py
084#! /usr/bin/env nix-shell
85#! nix-shell -i python -p python pythonPackages.foundationdb52
86···98 obj = json.loads(get_status(db))
99 print('FoundationDB available: %s' % obj['client']['database_status']['available'])
100101+if __name__ == "__main__":
102 main()
103+a@link> chmod +x fdb-status.py
104+a@link> ./fdb-status.py
105FoundationDB available: True
106+a@link>
0000000000000000000000000000000107</programlisting>
108+ <para>
109+ FoundationDB is run under the <command>foundationdb</command> user
110+ and group by default, but this may be changed in the NixOS
111+ configuration. The systemd unit
112+ <command>foundationdb.service</command> controls the
113+ <command>fdbmonitor</command> process.
114+ </para>
0000000000000000000000000000000000000000000000000000000000115 <para>
116+ By default, the NixOS module for FoundationDB creates a single
117+ SSD-storage based database for development and basic usage. This
118+ storage engine is designed for SSDs and will perform poorly on
119+ HDDs; however it can handle far more data than the alternative
120+ <quote>memory</quote> engine and is a better default choice for
121+ most deployments. (Note that you can change the storage backend
122+ on-the-fly for a given FoundationDB cluster using
123+ <command>fdbcli</command>.)
124 </para>
00125 <para>
126+ Furthermore, only 1 server process and 1 backup agent are started
127+ in the default configuration. See below for more on scaling to
128+ increase this.
129 </para>
000000000000000130 <para>
131+ FoundationDB stores all data for all server processes under
132+ <filename>/var/lib/foundationdb</filename>. You can override this
133+ using <option>services.foundationdb.dataDir</option>, e.g.
134 </para>
135+ <programlisting>
136+services.foundationdb.dataDir = "/data/fdb";
137+</programlisting>
138 <para>
139+ Similarly, logs are stored under
140+ <filename>/var/log/foundationdb</filename> by default, and there
141+ is a corresponding <option>services.foundationdb.logDir</option>
142+ as well.
143 </para>
144+ </section>
145+ <section xml:id="module-services-foundationdb-scaling">
146+ <title>Scaling processes and backup agents</title>
147 <para>
148+ Scaling the number of server processes is quite easy; simply
149+ specify <option>services.foundationdb.serverProcesses</option> to
150+ be the number of FoundationDB worker processes that should be
151+ started on the machine.
152 </para>
153+ <para>
154+ FoundationDB worker processes typically require 4GB of RAM
155+ per-process at minimum for good performance, so this option is set
156+ to 1 by default since the maximum amount of RAM is unknown. You’re
157+ advised to abide by this restriction, so pick a number of
158+ processes so that each has 4GB or more.
159+ </para>
160+ <para>
161+ A similar option exists in order to scale backup agent processes,
162+ <option>services.foundationdb.backupProcesses</option>. Backup
163+ agents are not as performance/RAM sensitive, so feel free to
164+ experiment with the number of available backup processes.
165+ </para>
166+ </section>
167+ <section xml:id="module-services-foundationdb-clustering">
168+ <title>Clustering</title>
169+ <para>
170+ FoundationDB on NixOS works similarly to other Linux systems, so
171+ this section will be brief. Please refer to the full FoundationDB
172+ documentation for more on clustering.
173+ </para>
174+ <para>
175+ FoundationDB organizes clusters using a set of
176+ <emphasis>coordinators</emphasis>, which are just
177+ specially-designated worker processes. By default, every
178+ installation of FoundationDB on NixOS will start as its own
179+ individual cluster, with a single coordinator: the first worker
180+ process on <command>localhost</command>.
181+ </para>
182+ <para>
183+ Coordinators are specified globally using the
184+ <command>/etc/foundationdb/fdb.cluster</command> file, which all
185+ servers and client applications will use to find and join
186+ coordinators. Note that this file <emphasis>can not</emphasis> be
187+ managed by NixOS so easily: FoundationDB is designed so that it
188+ will rewrite the file at runtime for all clients and nodes when
189+ cluster coordinators change, with clients transparently handling
190+ this without intervention. It is fundamentally a mutable file, and
191+ you should not try to manage it in any way in NixOS.
192+ </para>
193+ <para>
194+ When dealing with a cluster, there are two main things you want to
195+ do:
196+ </para>
197+ <itemizedlist spacing="compact">
198+ <listitem>
199+ <para>
200+ Add a node to the cluster for storage/compute.
201+ </para>
202+ </listitem>
203+ <listitem>
204+ <para>
205+ Promote an ordinary worker to a coordinator.
206+ </para>
207+ </listitem>
208+ </itemizedlist>
209+ <para>
210+ A node must already be a member of the cluster in order to
211+ properly be promoted to a coordinator, so you must always add it
212+ first if you wish to promote it.
213+ </para>
214+ <para>
215+ To add a machine to a FoundationDB cluster:
216+ </para>
217+ <itemizedlist spacing="compact">
218+ <listitem>
219+ <para>
220+ Choose one of the servers to start as the initial coordinator.
221+ </para>
222+ </listitem>
223+ <listitem>
224+ <para>
225+ Copy the <command>/etc/foundationdb/fdb.cluster</command> file
226+ from this server to all the other servers. Restart
227+ FoundationDB on all of these other servers, so they join the
228+ cluster.
229+ </para>
230+ </listitem>
231+ <listitem>
232+ <para>
233+ All of these servers are now connected and working together in
234+ the cluster, under the chosen coordinator.
235+ </para>
236+ </listitem>
237+ </itemizedlist>
238+ <para>
239+ At this point, you can add as many nodes as you want by just
240+ repeating the above steps. By default there will still be a single
241+ coordinator: you can use <command>fdbcli</command> to change this
242+ and add new coordinators.
243+ </para>
244+ <para>
245+ As a convenience, FoundationDB can automatically assign
246+ coordinators based on the redundancy mode you wish to achieve for
247+ the cluster. Once all the nodes have been joined, simply set the
248+ replication policy, and then issue the
249+ <command>coordinators auto</command> command
250+ </para>
251+ <para>
252+ For example, assuming we have 3 nodes available, we can enable
253+ double redundancy mode, then auto-select coordinators. For double
254+ redundancy, 3 coordinators is ideal: therefore FoundationDB will
255+ make <emphasis>every</emphasis> node a coordinator automatically:
256+ </para>
257+ <programlisting>
258+fdbcli> configure double ssd
259+fdbcli> coordinators auto
260+</programlisting>
261+ <para>
262+ This will transparently update all the servers within seconds, and
263+ appropriately rewrite the <command>fdb.cluster</command> file, as
264+ well as informing all client processes to do the same.
265+ </para>
266+ </section>
267+ <section xml:id="module-services-foundationdb-connectivity">
268+ <title>Client connectivity</title>
269+ <para>
270+ By default, all clients must use the current
271+ <command>fdb.cluster</command> file to access a given FoundationDB
272+ cluster. This file is located by default in
273+ <command>/etc/foundationdb/fdb.cluster</command> on all machines
274+ with the FoundationDB service enabled, so you may copy the active
275+ one from your cluster to a new node in order to connect, if it is
276+ not part of the cluster.
277+ </para>
278+ </section>
279+ <section xml:id="module-services-foundationdb-authorization">
280+ <title>Client authorization and TLS</title>
281+ <para>
282+ By default, any user who can connect to a FoundationDB process
283+ with the correct cluster configuration can access anything.
284+ FoundationDB uses a pluggable design to transport security, and
285+ out of the box it supports a LibreSSL-based plugin for TLS
286+ support. This plugin not only does in-flight encryption, but also
287+ performs client authorization based on the given endpoint’s
288+ certificate chain. For example, a FoundationDB server may be
289+ configured to only accept client connections over TLS, where the
290+ client TLS certificate is from organization <emphasis>Acme
291+ Co</emphasis> in the <emphasis>Research and Development</emphasis>
292+ unit.
293+ </para>
294+ <para>
295+ Configuring TLS with FoundationDB is done using the
296+ <option>services.foundationdb.tls</option> options in order to
297+ control the peer verification string, as well as the certificate
298+ and its private key.
299+ </para>
300+ <para>
301+ Note that the certificate and its private key must be accessible
302+ to the FoundationDB user account that the server runs under. These
303+ files are also NOT managed by NixOS, as putting them into the
304+ store may reveal private information.
305+ </para>
306+ <para>
307+ After you have a key and certificate file in place, it is not
308+ enough to simply set the NixOS module options – you must also
309+ configure the <command>fdb.cluster</command> file to specify that
310+ a given set of coordinators use TLS. This is as simple as adding
311+ the suffix <command>:tls</command> to your cluster coordinator
312+ configuration, after the port number. For example, assuming you
313+ have a coordinator on localhost with the default configuration,
314+ simply specifying:
315+ </para>
316+ <programlisting>
317XXXXXX:XXXXXX@127.0.0.1:4500:tls
318</programlisting>
319+ <para>
320+ will configure all clients and server processes to use TLS from
321+ now on.
322+ </para>
323+ </section>
324+ <section xml:id="module-services-foundationdb-disaster-recovery">
325+ <title>Backups and Disaster Recovery</title>
326+ <para>
327+ The usual rules for doing FoundationDB backups apply on NixOS as
328+ written in the FoundationDB manual. However, one important
329+ difference is the security profile for NixOS: by default, the
330+ <command>foundationdb</command> systemd unit uses <emphasis>Linux
331+ namespaces</emphasis> to restrict write access to the system,
332+ except for the log directory, data directory, and the
333+ <command>/etc/foundationdb/</command> directory. This is enforced
334+ by default and cannot be disabled.
335+ </para>
336+ <para>
337+ However, a side effect of this is that the
338+ <command>fdbbackup</command> command doesn’t work properly for
339+ local filesystem backups: FoundationDB uses a server process
340+ alongside the database processes to perform backups and copy the
341+ backups to the filesystem. As a result, this process is put under
342+ the restricted namespaces above: the backup process can only write
343+ to a limited number of paths.
344+ </para>
345+ <para>
346+ In order to allow flexible backup locations on local disks, the
347+ FoundationDB NixOS module supports a
348+ <option>services.foundationdb.extraReadWritePaths</option> option.
349+ This option takes a list of paths, and adds them to the systemd
350+ unit, allowing the processes inside the service to write (and
351+ read) the specified directories.
352+ </para>
353+ <para>
354+ For example, to create backups in
355+ <command>/opt/fdb-backups</command>, first set up the paths in the
356+ module options:
357+ </para>
358+ <programlisting>
359+services.foundationdb.extraReadWritePaths = [ "/opt/fdb-backups" ];
00360</programlisting>
361+ <para>
362+ Restart the FoundationDB service, and it will now be able to write
363+ to this directory (even if it does not yet exist.) Note: this path
364+ <emphasis>must</emphasis> exist before restarting the unit.
365+ Otherwise, systemd will not include it in the private FoundationDB
366+ namespace (and it will not add it dynamically at runtime).
367+ </para>
368+ <para>
369+ You can now perform a backup:
370+ </para>
371+ <programlisting>
372+$ sudo -u foundationdb fdbbackup start -t default -d file:///opt/fdb-backups
373+$ sudo -u foundationdb fdbbackup status -t default
374+</programlisting>
375+ </section>
376+ <section xml:id="module-services-foundationdb-limitations">
377+ <title>Known limitations</title>
000000000000378 <para>
379+ The FoundationDB setup for NixOS should currently be considered
380+ beta. FoundationDB is not new software, but the NixOS compilation
381+ and integration has only undergone fairly basic testing of all the
382+ available functionality.
383 </para>
384+ <itemizedlist spacing="compact">
385+ <listitem>
386+ <para>
387+ There is no way to specify individual parameters for
388+ individual <command>fdbserver</command> processes. Currently,
389+ all server processes inherit all the global
390+ <command>fdbmonitor</command> settings.
391+ </para>
392+ </listitem>
393+ <listitem>
394+ <para>
395+ Ruby bindings are not currently installed.
396+ </para>
397+ </listitem>
398+ <listitem>
399+ <para>
400+ Go bindings are not currently installed.
401+ </para>
402+ </listitem>
403+ </itemizedlist>
404+ </section>
405+ <section xml:id="module-services-foundationdb-options">
406+ <title>Options</title>
407 <para>
408+ NixOS’s FoundationDB module allows you to configure all of the
409+ most relevant configuration options for
410+ <command>fdbmonitor</command>, matching it quite closely. A
411+ complete list of options for the FoundationDB module may be found
412+ <link linkend="opt-services.foundationdb.enable">here</link>. You
413+ should also read the FoundationDB documentation as well.
414 </para>
415+ </section>
416+ <section xml:id="module-services-foundationdb-full-docs">
417+ <title>Full documentation</title>
418 <para>
419+ FoundationDB is a complex piece of software, and requires careful
420+ administration to properly use. Full documentation for
421+ administration can be found here:
422+ <link xlink:href="https://apple.github.io/foundationdb/">https://apple.github.io/foundationdb/</link>.
423 </para>
424+ </section>
0000000000000000000000425</chapter>
···1+# PostgreSQL {#module-postgresql}
2+3+<!-- FIXME: render nicely -->
4+<!-- FIXME: source can be added automatically -->
5+6+*Source:* {file}`modules/services/databases/postgresql.nix`
7+8+*Upstream documentation:* <http://www.postgresql.org/docs/>
9+10+<!-- FIXME: more stuff, like maintainer? -->
11+12+PostgreSQL is an advanced, free relational database.
13+<!-- MORE -->
14+15+## Configuring {#module-services-postgres-configuring}
16+17+To enable PostgreSQL, add the following to your {file}`configuration.nix`:
18+```
19+services.postgresql.enable = true;
20+services.postgresql.package = pkgs.postgresql_11;
21+```
22+Note that you are required to specify the desired version of PostgreSQL (e.g. `pkgs.postgresql_11`). Since upgrading your PostgreSQL version requires a database dump and reload (see below), NixOS cannot provide a default value for [](#opt-services.postgresql.package) such as the most recent release of PostgreSQL.
23+24+<!--
25+After running {command}`nixos-rebuild`, you can verify
26+whether PostgreSQL works by running {command}`psql`:
27+28+```ShellSession
29+$ psql
30+psql (9.2.9)
31+Type "help" for help.
32+33+alice=>
34+```
35+-->
36+37+By default, PostgreSQL stores its databases in {file}`/var/lib/postgresql/$psqlSchema`. You can override this using [](#opt-services.postgresql.dataDir), e.g.
38+```
39+services.postgresql.dataDir = "/data/postgresql";
40+```
41+42+## Upgrading {#module-services-postgres-upgrading}
43+44+::: {.note}
45+The steps below demonstrate how to upgrade from an older version to `pkgs.postgresql_13`.
46+These instructions are also applicable to other versions.
47+:::
48+49+Major PostgreSQL upgrades require a downtime and a few imperative steps to be called. This is the case because
50+each major version has some internal changes in the databases' state during major releases. Because of that,
51+NixOS places the state into {file}`/var/lib/postgresql/<version>` where each `version`
52+can be obtained like this:
53+```
54+$ nix-instantiate --eval -A postgresql_13.psqlSchema
55+"13"
56+```
57+For an upgrade, a script like this can be used to simplify the process:
58+```
59+{ config, pkgs, ... }:
60+{
61+ environment.systemPackages = [
62+ (let
63+ # XXX specify the postgresql package you'd like to upgrade to.
64+ # Do not forget to list the extensions you need.
65+ newPostgres = pkgs.postgresql_13.withPackages (pp: [
66+ # pp.plv8
67+ ]);
68+ in pkgs.writeScriptBin "upgrade-pg-cluster" ''
69+ set -eux
70+ # XXX it's perhaps advisable to stop all services that depend on postgresql
71+ systemctl stop postgresql
72+73+ export NEWDATA="/var/lib/postgresql/${newPostgres.psqlSchema}"
74+75+ export NEWBIN="${newPostgres}/bin"
76+77+ export OLDDATA="${config.services.postgresql.dataDir}"
78+ export OLDBIN="${config.services.postgresql.package}/bin"
79+80+ install -d -m 0700 -o postgres -g postgres "$NEWDATA"
81+ cd "$NEWDATA"
82+ sudo -u postgres $NEWBIN/initdb -D "$NEWDATA"
83+84+ sudo -u postgres $NEWBIN/pg_upgrade \
85+ --old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \
86+ --old-bindir $OLDBIN --new-bindir $NEWBIN \
87+ "$@"
88+ '')
89+ ];
90+}
91+```
92+93+The upgrade process is:
94+95+ 1. Rebuild nixos configuration with the configuration above added to your {file}`configuration.nix`. Alternatively, add that into separate file and reference it in `imports` list.
96+ 2. Login as root (`sudo su -`)
97+ 3. Run `upgrade-pg-cluster`. It will stop old postgresql, initialize a new one and migrate the old one to the new one. You may supply arguments like `--jobs 4` and `--link` to speedup migration process. See <https://www.postgresql.org/docs/current/pgupgrade.html> for details.
98+ 4. Change postgresql package in NixOS configuration to the one you were upgrading to via [](#opt-services.postgresql.package). Rebuild NixOS. This should start new postgres using upgraded data directory and all services you stopped during the upgrade.
99+ 5. After the upgrade it's advisable to analyze the new cluster.
100+101+ - For PostgreSQL ≥ 14, use the `vacuumdb` command printed by the upgrades script.
102+ - For PostgreSQL < 14, run (as `su -l postgres` in the [](#opt-services.postgresql.dataDir), in this example {file}`/var/lib/postgresql/13`):
103+104+ ```
105+ $ ./analyze_new_cluster.sh
106+ ```
107+108+ ::: {.warning}
109+ The next step removes the old state-directory!
110+ :::
111+112+ ```
113+ $ ./delete_old_cluster.sh
114+ ```
115+116+## Options {#module-services-postgres-options}
117+118+A complete list of options for the PostgreSQL module may be found [here](#opt-services.postgresql.enable).
119+120+## Plugins {#module-services-postgres-plugins}
121+122+Plugins collection for each PostgreSQL version can be accessed with `.pkgs`. For example, for `pkgs.postgresql_11` package, its plugin collection is accessed by `pkgs.postgresql_11.pkgs`:
123+```ShellSession
124+$ nix repl '<nixpkgs>'
125+126+Loading '<nixpkgs>'...
127+Added 10574 variables.
128+129+nix-repl> postgresql_11.pkgs.<TAB><TAB>
130+postgresql_11.pkgs.cstore_fdw postgresql_11.pkgs.pg_repack
131+postgresql_11.pkgs.pg_auto_failover postgresql_11.pkgs.pg_safeupdate
132+postgresql_11.pkgs.pg_bigm postgresql_11.pkgs.pg_similarity
133+postgresql_11.pkgs.pg_cron postgresql_11.pkgs.pg_topn
134+postgresql_11.pkgs.pg_hll postgresql_11.pkgs.pgjwt
135+postgresql_11.pkgs.pg_partman postgresql_11.pkgs.pgroonga
136+...
137+```
138+139+To add plugins via NixOS configuration, set `services.postgresql.extraPlugins`:
140+```
141+services.postgresql.package = pkgs.postgresql_11;
142+services.postgresql.extraPlugins = with pkgs.postgresql_11.pkgs; [
143+ pg_repack
144+ postgis
145+];
146+```
147+148+You can build custom PostgreSQL-with-plugins (to be used outside of NixOS) using function `.withPackages`. For example, creating a custom PostgreSQL package in an overlay can look like:
149+```
150+self: super: {
151+ postgresql_custom = self.postgresql_11.withPackages (ps: [
152+ ps.pg_repack
153+ ps.postgis
154+ ]);
155+}
156+```
157+158+Here's a recipe on how to override a particular plugin through an overlay:
159+```
160+self: super: {
161+ postgresql_11 = super.postgresql_11.override { this = self.postgresql_11; } // {
162+ pkgs = super.postgresql_11.pkgs // {
163+ pg_repack = super.postgresql_11.pkgs.pg_repack.overrideAttrs (_: {
164+ name = "pg_repack-v20181024";
165+ src = self.fetchzip {
166+ url = "https://github.com/reorg/pg_repack/archive/923fa2f3c709a506e111cc963034bf2fd127aa00.tar.gz";
167+ sha256 = "17k6hq9xaax87yz79j773qyigm4fwk8z4zh5cyp6z0sxnwfqxxw5";
168+ };
169+ });
170+ };
171+ };
172+}
173+```
+182-163
nixos/modules/services/databases/postgresql.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-postgresql">
6- <title>PostgreSQL</title>
7-<!-- FIXME: render nicely -->
8-<!-- FIXME: source can be added automatically -->
9- <para>
10- <emphasis>Source:</emphasis> <filename>modules/services/databases/postgresql.nix</filename>
11- </para>
12- <para>
13- <emphasis>Upstream documentation:</emphasis> <link xlink:href="http://www.postgresql.org/docs/"/>
14- </para>
15-<!-- FIXME: more stuff, like maintainer? -->
16- <para>
17- PostgreSQL is an advanced, free relational database.
18-<!-- MORE -->
19- </para>
20- <section xml:id="module-services-postgres-configuring">
21- <title>Configuring</title>
22-23 <para>
24- To enable PostgreSQL, add the following to your <filename>configuration.nix</filename>:
25-<programlisting>
26-<xref linkend="opt-services.postgresql.enable"/> = true;
27-<xref linkend="opt-services.postgresql.package"/> = pkgs.postgresql_11;
28-</programlisting>
29- Note that you are required to specify the desired version of PostgreSQL (e.g. <literal>pkgs.postgresql_11</literal>). Since upgrading your PostgreSQL version requires a database dump and reload (see below), NixOS cannot provide a default value for <xref linkend="opt-services.postgresql.package"/> such as the most recent release of PostgreSQL.
30 </para>
31-32-<!--
33-<para>After running <command>nixos-rebuild</command>, you can verify
34-whether PostgreSQL works by running <command>psql</command>:
35-36-<screen>
37-<prompt>$ </prompt>psql
38-psql (9.2.9)
39-Type "help" for help.
40-41-<prompt>alice=></prompt>
42-</screen>
43--->
44-45 <para>
46- By default, PostgreSQL stores its databases in <filename>/var/lib/postgresql/$psqlSchema</filename>. You can override this using <xref linkend="opt-services.postgresql.dataDir"/>, e.g.
47-<programlisting>
48-<xref linkend="opt-services.postgresql.dataDir"/> = "/data/postgresql";
49-</programlisting>
50 </para>
51- </section>
52- <section xml:id="module-services-postgres-upgrading">
53- <title>Upgrading</title>
54-55- <note>
56- <para>
57- The steps below demonstrate how to upgrade from an older version to <package>pkgs.postgresql_13</package>.
58- These instructions are also applicable to other versions.
59- </para>
60- </note>
61 <para>
62- Major PostgreSQL upgrades require a downtime and a few imperative steps to be called. This is the case because
63- each major version has some internal changes in the databases' state during major releases. Because of that,
64- NixOS places the state into <filename>/var/lib/postgresql/<version></filename> where each <literal>version</literal>
65- can be obtained like this:
66-<programlisting>
67-<prompt>$ </prompt>nix-instantiate --eval -A postgresql_13.psqlSchema
68-"13"
000000000000000000000000000000000000000000069</programlisting>
70- For an upgrade, a script like this can be used to simplify the process:
71-<programlisting>
00072{ config, pkgs, ... }:
73{
74- <xref linkend="opt-environment.systemPackages" /> = [
75 (let
76 # XXX specify the postgresql package you'd like to upgrade to.
77 # Do not forget to list the extensions you need.
78 newPostgres = pkgs.postgresql_13.withPackages (pp: [
79 # pp.plv8
80 ]);
81- in pkgs.writeScriptBin "upgrade-pg-cluster" ''
82 set -eux
83 # XXX it's perhaps advisable to stop all services that depend on postgresql
84 systemctl stop postgresql
8586- export NEWDATA="/var/lib/postgresql/${newPostgres.psqlSchema}"
8788- export NEWBIN="${newPostgres}/bin"
8990- export OLDDATA="${config.<xref linkend="opt-services.postgresql.dataDir"/>}"
91- export OLDBIN="${config.<xref linkend="opt-services.postgresql.package"/>}/bin"
9293- install -d -m 0700 -o postgres -g postgres "$NEWDATA"
94- cd "$NEWDATA"
95- sudo -u postgres $NEWBIN/initdb -D "$NEWDATA"
9697 sudo -u postgres $NEWBIN/pg_upgrade \
98- --old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \
99 --old-bindir $OLDBIN --new-bindir $NEWBIN \
100- "$@"
101 '')
102 ];
103}
104</programlisting>
105- </para>
106-107- <para>
108- The upgrade process is:
109- </para>
110-111- <orderedlist>
112- <listitem>
113 <para>
114- Rebuild nixos configuration with the configuration above added to your <filename>configuration.nix</filename>. Alternatively, add that into separate file and reference it in <literal>imports</literal> list.
115 </para>
116- </listitem>
117- <listitem>
118- <para>
119- Login as root (<literal>sudo su -</literal>)
120- </para>
121- </listitem>
122- <listitem>
123- <para>
124- Run <literal>upgrade-pg-cluster</literal>. It will stop old postgresql, initialize a new one and migrate the old one to the new one. You may supply arguments like <literal>--jobs 4</literal> and <literal>--link</literal> to speedup migration process. See <link xlink:href="https://www.postgresql.org/docs/current/pgupgrade.html" /> for details.
125- </para>
126- </listitem>
127- <listitem>
128- <para>
129- Change postgresql package in NixOS configuration to the one you were upgrading to via <xref linkend="opt-services.postgresql.package" />. Rebuild NixOS. This should start new postgres using upgraded data directory and all services you stopped during the upgrade.
130- </para>
131- </listitem>
132- <listitem>
00000000000000000000000000000000000000000000000000000133 <para>
134- After the upgrade it's advisable to analyze the new cluster.
0135 </para>
136- <itemizedlist>
137- <listitem>
138- <para>
139- For PostgreSQL ≥ 14, use the <literal>vacuumdb</literal> command printed by the upgrades script.
140- </para>
141- </listitem>
142- <listitem>
143- <para>
144- For PostgreSQL < 14, run (as <literal>su -l postgres</literal> in the <xref linkend="opt-services.postgresql.dataDir" />, in this example <filename>/var/lib/postgresql/13</filename>):
145-<programlisting>
146-<prompt>$ </prompt>./analyze_new_cluster.sh
147-</programlisting>
148- </para>
149- </listitem>
150- </itemizedlist>
151 <para>
152- <warning><para>The next step removes the old state-directory!</para></warning>
153-<programlisting>
154-<prompt>$ </prompt>./delete_old_cluster.sh
155-</programlisting>
0156 </para>
157- </listitem>
158- </orderedlist>
159- </section>
160- <section xml:id="module-services-postgres-options">
161- <title>Options</title>
162-163- <para>
164- A complete list of options for the PostgreSQL module may be found <link linkend="opt-services.postgresql.enable">here</link>.
165- </para>
166- </section>
167- <section xml:id="module-services-postgres-plugins">
168- <title>Plugins</title>
169-170- <para>
171- Plugins collection for each PostgreSQL version can be accessed with <literal>.pkgs</literal>. For example, for <literal>pkgs.postgresql_11</literal> package, its plugin collection is accessed by <literal>pkgs.postgresql_11.pkgs</literal>:
172-<screen>
173-<prompt>$ </prompt>nix repl '<nixpkgs>'
174175Loading '<nixpkgs>'...
176Added 10574 variables.
177178-<prompt>nix-repl> </prompt>postgresql_11.pkgs.<TAB><TAB>
179postgresql_11.pkgs.cstore_fdw postgresql_11.pkgs.pg_repack
180postgresql_11.pkgs.pg_auto_failover postgresql_11.pkgs.pg_safeupdate
181postgresql_11.pkgs.pg_bigm postgresql_11.pkgs.pg_similarity
···183postgresql_11.pkgs.pg_hll postgresql_11.pkgs.pgjwt
184postgresql_11.pkgs.pg_partman postgresql_11.pkgs.pgroonga
185...
186-</screen>
187- </para>
188-189- <para>
190- To add plugins via NixOS configuration, set <literal>services.postgresql.extraPlugins</literal>:
191-<programlisting>
192-<xref linkend="opt-services.postgresql.package"/> = pkgs.postgresql_11;
193-<xref linkend="opt-services.postgresql.extraPlugins"/> = with pkgs.postgresql_11.pkgs; [
194 pg_repack
195 postgis
196];
197</programlisting>
198- </para>
199-200- <para>
201- You can build custom PostgreSQL-with-plugins (to be used outside of NixOS) using function <literal>.withPackages</literal>. For example, creating a custom PostgreSQL package in an overlay can look like:
202-<programlisting>
00203self: super: {
204 postgresql_custom = self.postgresql_11.withPackages (ps: [
205 ps.pg_repack
···207 ]);
208}
209</programlisting>
210- </para>
211-212- <para>
213- Here's a recipe on how to override a particular plugin through an overlay:
214-<programlisting>
215self: super: {
216 postgresql_11 = super.postgresql_11.override { this = self.postgresql_11; } // {
217 pkgs = super.postgresql_11.pkgs // {
218 pg_repack = super.postgresql_11.pkgs.pg_repack.overrideAttrs (_: {
219- name = "pg_repack-v20181024";
220 src = self.fetchzip {
221- url = "https://github.com/reorg/pg_repack/archive/923fa2f3c709a506e111cc963034bf2fd127aa00.tar.gz";
222- sha256 = "17k6hq9xaax87yz79j773qyigm4fwk8z4zh5cyp6z0sxnwfqxxw5";
223 };
224 });
225 };
226 };
227}
228</programlisting>
229- </para>
230- </section>
231</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-postgresql">
4+ <title>PostgreSQL</title>
0000000000000000005 <para>
6+ <emphasis>Source:</emphasis>
7+ <filename>modules/services/databases/postgresql.nix</filename>
00008 </para>
000000000000009 <para>
10+ <emphasis>Upstream documentation:</emphasis>
11+ <link xlink:href="http://www.postgresql.org/docs/">http://www.postgresql.org/docs/</link>
0012 </para>
000000000013 <para>
14+ PostgreSQL is an advanced, free relational database.
15+ </para>
16+ <section xml:id="module-services-postgres-configuring">
17+ <title>Configuring</title>
18+ <para>
19+ To enable PostgreSQL, add the following to your
20+ <filename>configuration.nix</filename>:
21+ </para>
22+ <programlisting>
23+services.postgresql.enable = true;
24+services.postgresql.package = pkgs.postgresql_11;
25+</programlisting>
26+ <para>
27+ Note that you are required to specify the desired version of
28+ PostgreSQL (e.g. <literal>pkgs.postgresql_11</literal>). Since
29+ upgrading your PostgreSQL version requires a database dump and
30+ reload (see below), NixOS cannot provide a default value for
31+ <xref linkend="opt-services.postgresql.package" /> such as the
32+ most recent release of PostgreSQL.
33+ </para>
34+ <para>
35+ By default, PostgreSQL stores its databases in
36+ <filename>/var/lib/postgresql/$psqlSchema</filename>. You can
37+ override this using
38+ <xref linkend="opt-services.postgresql.dataDir" />, e.g.
39+ </para>
40+ <programlisting>
41+services.postgresql.dataDir = "/data/postgresql";
42+</programlisting>
43+ </section>
44+ <section xml:id="module-services-postgres-upgrading">
45+ <title>Upgrading</title>
46+ <note>
47+ <para>
48+ The steps below demonstrate how to upgrade from an older version
49+ to <literal>pkgs.postgresql_13</literal>. These instructions are
50+ also applicable to other versions.
51+ </para>
52+ </note>
53+ <para>
54+ Major PostgreSQL upgrades require a downtime and a few imperative
55+ steps to be called. This is the case because each major version
56+ has some internal changes in the databases’ state during major
57+ releases. Because of that, NixOS places the state into
58+ <filename>/var/lib/postgresql/<version></filename> where
59+ each <literal>version</literal> can be obtained like this:
60+ </para>
61+ <programlisting>
62+$ nix-instantiate --eval -A postgresql_13.psqlSchema
63+"13"
64</programlisting>
65+ <para>
66+ For an upgrade, a script like this can be used to simplify the
67+ process:
68+ </para>
69+ <programlisting>
70{ config, pkgs, ... }:
71{
72+ environment.systemPackages = [
73 (let
74 # XXX specify the postgresql package you'd like to upgrade to.
75 # Do not forget to list the extensions you need.
76 newPostgres = pkgs.postgresql_13.withPackages (pp: [
77 # pp.plv8
78 ]);
79+ in pkgs.writeScriptBin "upgrade-pg-cluster" ''
80 set -eux
81 # XXX it's perhaps advisable to stop all services that depend on postgresql
82 systemctl stop postgresql
8384+ export NEWDATA="/var/lib/postgresql/${newPostgres.psqlSchema}"
8586+ export NEWBIN="${newPostgres}/bin"
8788+ export OLDDATA="${config.services.postgresql.dataDir}"
89+ export OLDBIN="${config.services.postgresql.package}/bin"
9091+ install -d -m 0700 -o postgres -g postgres "$NEWDATA"
92+ cd "$NEWDATA"
93+ sudo -u postgres $NEWBIN/initdb -D "$NEWDATA"
9495 sudo -u postgres $NEWBIN/pg_upgrade \
96+ --old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \
97 --old-bindir $OLDBIN --new-bindir $NEWBIN \
98+ "$@"
99 '')
100 ];
101}
102</programlisting>
00000000103 <para>
104+ The upgrade process is:
105 </para>
106+ <orderedlist numeration="arabic">
107+ <listitem>
108+ <para>
109+ Rebuild nixos configuration with the configuration above added
110+ to your <filename>configuration.nix</filename>. Alternatively,
111+ add that into separate file and reference it in
112+ <literal>imports</literal> list.
113+ </para>
114+ </listitem>
115+ <listitem>
116+ <para>
117+ Login as root (<literal>sudo su -</literal>)
118+ </para>
119+ </listitem>
120+ <listitem>
121+ <para>
122+ Run <literal>upgrade-pg-cluster</literal>. It will stop old
123+ postgresql, initialize a new one and migrate the old one to
124+ the new one. You may supply arguments like
125+ <literal>--jobs 4</literal> and <literal>--link</literal> to
126+ speedup migration process. See
127+ <link xlink:href="https://www.postgresql.org/docs/current/pgupgrade.html">https://www.postgresql.org/docs/current/pgupgrade.html</link>
128+ for details.
129+ </para>
130+ </listitem>
131+ <listitem>
132+ <para>
133+ Change postgresql package in NixOS configuration to the one
134+ you were upgrading to via
135+ <xref linkend="opt-services.postgresql.package" />. Rebuild
136+ NixOS. This should start new postgres using upgraded data
137+ directory and all services you stopped during the upgrade.
138+ </para>
139+ </listitem>
140+ <listitem>
141+ <para>
142+ After the upgrade it’s advisable to analyze the new cluster.
143+ </para>
144+ <itemizedlist>
145+ <listitem>
146+ <para>
147+ For PostgreSQL ≥ 14, use the <literal>vacuumdb</literal>
148+ command printed by the upgrades script.
149+ </para>
150+ </listitem>
151+ <listitem>
152+ <para>
153+ For PostgreSQL < 14, run (as
154+ <literal>su -l postgres</literal> in the
155+ <xref linkend="opt-services.postgresql.dataDir" />, in
156+ this example <filename>/var/lib/postgresql/13</filename>):
157+ </para>
158+ <programlisting>
159+$ ./analyze_new_cluster.sh
160+</programlisting>
161+ </listitem>
162+ </itemizedlist>
163+ <warning>
164+ <para>
165+ The next step removes the old state-directory!
166+ </para>
167+ </warning>
168+ <programlisting>
169+$ ./delete_old_cluster.sh
170+</programlisting>
171+ </listitem>
172+ </orderedlist>
173+ </section>
174+ <section xml:id="module-services-postgres-options">
175+ <title>Options</title>
176 <para>
177+ A complete list of options for the PostgreSQL module may be found
178+ <link linkend="opt-services.postgresql.enable">here</link>.
179 </para>
180+ </section>
181+ <section xml:id="module-services-postgres-plugins">
182+ <title>Plugins</title>
000000000000183 <para>
184+ Plugins collection for each PostgreSQL version can be accessed
185+ with <literal>.pkgs</literal>. For example, for
186+ <literal>pkgs.postgresql_11</literal> package, its plugin
187+ collection is accessed by
188+ <literal>pkgs.postgresql_11.pkgs</literal>:
189 </para>
190+ <programlisting>
191+$ nix repl '<nixpkgs>'
000000000000000192193Loading '<nixpkgs>'...
194Added 10574 variables.
195196+nix-repl> postgresql_11.pkgs.<TAB><TAB>
197postgresql_11.pkgs.cstore_fdw postgresql_11.pkgs.pg_repack
198postgresql_11.pkgs.pg_auto_failover postgresql_11.pkgs.pg_safeupdate
199postgresql_11.pkgs.pg_bigm postgresql_11.pkgs.pg_similarity
···201postgresql_11.pkgs.pg_hll postgresql_11.pkgs.pgjwt
202postgresql_11.pkgs.pg_partman postgresql_11.pkgs.pgroonga
203...
204+</programlisting>
205+ <para>
206+ To add plugins via NixOS configuration, set
207+ <literal>services.postgresql.extraPlugins</literal>:
208+ </para>
209+ <programlisting>
210+services.postgresql.package = pkgs.postgresql_11;
211+services.postgresql.extraPlugins = with pkgs.postgresql_11.pkgs; [
212 pg_repack
213 postgis
214];
215</programlisting>
216+ <para>
217+ You can build custom PostgreSQL-with-plugins (to be used outside
218+ of NixOS) using function <literal>.withPackages</literal>. For
219+ example, creating a custom PostgreSQL package in an overlay can
220+ look like:
221+ </para>
222+ <programlisting>
223self: super: {
224 postgresql_custom = self.postgresql_11.withPackages (ps: [
225 ps.pg_repack
···227 ]);
228}
229</programlisting>
230+ <para>
231+ Here’s a recipe on how to override a particular plugin through an
232+ overlay:
233+ </para>
234+ <programlisting>
235self: super: {
236 postgresql_11 = super.postgresql_11.override { this = self.postgresql_11; } // {
237 pkgs = super.postgresql_11.pkgs // {
238 pg_repack = super.postgresql_11.pkgs.pg_repack.overrideAttrs (_: {
239+ name = "pg_repack-v20181024";
240 src = self.fetchzip {
241+ url = "https://github.com/reorg/pg_repack/archive/923fa2f3c709a506e111cc963034bf2fd127aa00.tar.gz";
242+ sha256 = "17k6hq9xaax87yz79j773qyigm4fwk8z4zh5cyp6z0sxnwfqxxw5";
243 };
244 });
245 };
246 };
247}
248</programlisting>
249+ </section>
0250</chapter>
+39
nixos/modules/services/desktops/flatpak.md
···000000000000000000000000000000000000000
···1+# Flatpak {#module-services-flatpak}
2+3+*Source:* {file}`modules/services/desktop/flatpak.nix`
4+5+*Upstream documentation:* <https://github.com/flatpak/flatpak/wiki>
6+7+Flatpak is a system for building, distributing, and running sandboxed desktop
8+applications on Linux.
9+10+To enable Flatpak, add the following to your {file}`configuration.nix`:
11+```
12+ services.flatpak.enable = true;
13+```
14+15+For the sandboxed apps to work correctly, desktop integration portals need to
16+be installed. If you run GNOME, this will be handled automatically for you;
17+in other cases, you will need to add something like the following to your
18+{file}`configuration.nix`:
19+```
20+ xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
21+```
22+23+Then, you will need to add a repository, for example,
24+[Flathub](https://github.com/flatpak/flatpak/wiki),
25+either using the following commands:
26+```ShellSession
27+$ flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
28+$ flatpak update
29+```
30+or by opening the
31+[repository file](https://flathub.org/repo/flathub.flatpakrepo) in GNOME Software.
32+33+Finally, you can search and install programs:
34+```ShellSession
35+$ flatpak search bustle
36+$ flatpak install flathub org.freedesktop.Bustle
37+$ flatpak run org.freedesktop.Bustle
38+```
39+Again, GNOME Software offers graphical interface for these tasks.
+56-53
nixos/modules/services/desktops/flatpak.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-flatpak">
6- <title>Flatpak</title>
7- <para>
8- <emphasis>Source:</emphasis>
9- <filename>modules/services/desktop/flatpak.nix</filename>
10- </para>
11- <para>
12- <emphasis>Upstream documentation:</emphasis>
13- <link xlink:href="https://github.com/flatpak/flatpak/wiki"/>
14- </para>
15- <para>
16- Flatpak is a system for building, distributing, and running sandboxed desktop
17- applications on Linux.
18- </para>
19- <para>
20- To enable Flatpak, add the following to your
21- <filename>configuration.nix</filename>:
22-<programlisting>
23- <xref linkend="opt-services.flatpak.enable"/> = true;
00000000000000000024</programlisting>
25- </para>
26- <para>
27- For the sandboxed apps to work correctly, desktop integration portals need to
28- be installed. If you run GNOME, this will be handled automatically for you;
29- in other cases, you will need to add something like the following to your
30- <filename>configuration.nix</filename>:
31-<programlisting>
32- <xref linkend="opt-xdg.portal.extraPortals"/> = [ pkgs.xdg-desktop-portal-gtk ];
000033</programlisting>
34- </para>
35- <para>
36- Then, you will need to add a repository, for example,
37- <link xlink:href="https://github.com/flatpak/flatpak/wiki">Flathub</link>,
38- either using the following commands:
39-<screen>
40-<prompt>$ </prompt>flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
41-<prompt>$ </prompt>flatpak update
42-</screen>
43- or by opening the
44- <link xlink:href="https://flathub.org/repo/flathub.flatpakrepo">repository
45- file</link> in GNOME Software.
46- </para>
47- <para>
48- Finally, you can search and install programs:
49-<screen>
50-<prompt>$ </prompt>flatpak search bustle
51-<prompt>$ </prompt>flatpak install flathub org.freedesktop.Bustle
52-<prompt>$ </prompt>flatpak run org.freedesktop.Bustle
53-</screen>
54- Again, GNOME Software offers graphical interface for these tasks.
55- </para>
56</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-flatpak">
4+ <title>Flatpak</title>
5+ <para>
6+ <emphasis>Source:</emphasis>
7+ <filename>modules/services/desktop/flatpak.nix</filename>
8+ </para>
9+ <para>
10+ <emphasis>Upstream documentation:</emphasis>
11+ <link xlink:href="https://github.com/flatpak/flatpak/wiki">https://github.com/flatpak/flatpak/wiki</link>
12+ </para>
13+ <para>
14+ Flatpak is a system for building, distributing, and running
15+ sandboxed desktop applications on Linux.
16+ </para>
17+ <para>
18+ To enable Flatpak, add the following to your
19+ <filename>configuration.nix</filename>:
20+ </para>
21+ <programlisting>
22+ services.flatpak.enable = true;
23+</programlisting>
24+ <para>
25+ For the sandboxed apps to work correctly, desktop integration
26+ portals need to be installed. If you run GNOME, this will be handled
27+ automatically for you; in other cases, you will need to add
28+ something like the following to your
29+ <filename>configuration.nix</filename>:
30+ </para>
31+ <programlisting>
32+ xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
33+</programlisting>
34+ <para>
35+ Then, you will need to add a repository, for example,
36+ <link xlink:href="https://github.com/flatpak/flatpak/wiki">Flathub</link>,
37+ either using the following commands:
38+ </para>
39+ <programlisting>
40+$ flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
41+$ flatpak update
42</programlisting>
43+ <para>
44+ or by opening the
45+ <link xlink:href="https://flathub.org/repo/flathub.flatpakrepo">repository
46+ file</link> in GNOME Software.
47+ </para>
48+ <para>
49+ Finally, you can search and install programs:
50+ </para>
51+ <programlisting>
52+$ flatpak search bustle
53+$ flatpak install flathub org.freedesktop.Bustle
54+$ flatpak run org.freedesktop.Bustle
55</programlisting>
56+ <para>
57+ Again, GNOME Software offers graphical interface for these tasks.
58+ </para>
000000000000000000059</chapter>
+39
nixos/modules/services/development/blackfire.md
···000000000000000000000000000000000000000
···1+# Blackfire profiler {#module-services-blackfire}
2+3+*Source:* {file}`modules/services/development/blackfire.nix`
4+5+*Upstream documentation:* <https://blackfire.io/docs/introduction>
6+7+[Blackfire](https://blackfire.io) is a proprietary tool for profiling applications. There are several languages supported by the product but currently only PHP support is packaged in Nixpkgs. The back-end consists of a module that is loaded into the language runtime (called *probe*) and a service (*agent*) that the probe connects to and that sends the profiles to the server.
8+9+To use it, you will need to enable the agent and the probe on your server. The exact method will depend on the way you use PHP but here is an example of NixOS configuration for PHP-FPM:
10+```
11+let
12+ php = pkgs.php.withExtensions ({ enabled, all }: enabled ++ (with all; [
13+ blackfire
14+ ]));
15+in {
16+ # Enable the probe extension for PHP-FPM.
17+ services.phpfpm = {
18+ phpPackage = php;
19+ };
20+21+ # Enable and configure the agent.
22+ services.blackfire-agent = {
23+ enable = true;
24+ settings = {
25+ # You will need to get credentials at https://blackfire.io/my/settings/credentials
26+ # You can also use other options described in https://blackfire.io/docs/up-and-running/configuration/agent
27+ server-id = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
28+ server-token = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
29+ };
30+ };
31+32+ # Make the agent run on start-up.
33+ # (WantedBy= from the upstream unit not respected: https://github.com/NixOS/nixpkgs/issues/81138)
34+ # Alternately, you can start it manually with `systemctl start blackfire-agent`.
35+ systemd.services.blackfire-agent.wantedBy = [ "phpfpm-foo.service" ];
36+}
37+```
38+39+On your developer machine, you will also want to install [the client](https://blackfire.io/docs/up-and-running/installation#install-a-profiling-client) (see `blackfire` package) or the browser extension to actually trigger the profiling.
+39-24
nixos/modules/services/development/blackfire.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="module-services-blackfire">
2- <title>Blackfire profiler</title>
3- <para>
4- <emphasis>Source:</emphasis>
5- <filename>modules/services/development/blackfire.nix</filename>
6- </para>
7- <para>
8- <emphasis>Upstream documentation:</emphasis>
9- <link xlink:href="https://blackfire.io/docs/introduction"/>
10- </para>
11- <para>
12- <link xlink:href="https://blackfire.io">Blackfire</link> is a proprietary tool for profiling applications. There are several languages supported by the product but currently only PHP support is packaged in Nixpkgs. The back-end consists of a module that is loaded into the language runtime (called <firstterm>probe</firstterm>) and a service (<firstterm>agent</firstterm>) that the probe connects to and that sends the profiles to the server.
13- </para>
14- <para>
15- To use it, you will need to enable the agent and the probe on your server. The exact method will depend on the way you use PHP but here is an example of NixOS configuration for PHP-FPM:
16-<programlisting>let
00000000000017 php = pkgs.php.withExtensions ({ enabled, all }: enabled ++ (with all; [
18 blackfire
19 ]));
···29 settings = {
30 # You will need to get credentials at https://blackfire.io/my/settings/credentials
31 # You can also use other options described in https://blackfire.io/docs/up-and-running/configuration/agent
32- server-id = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
33- server-token = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
34 };
35 };
3637 # Make the agent run on start-up.
38 # (WantedBy= from the upstream unit not respected: https://github.com/NixOS/nixpkgs/issues/81138)
39 # Alternately, you can start it manually with `systemctl start blackfire-agent`.
40- systemd.services.blackfire-agent.wantedBy = [ "phpfpm-foo.service" ];
41-}</programlisting>
42- </para>
43- <para>
44- On your developer machine, you will also want to install <link xlink:href="https://blackfire.io/docs/up-and-running/installation#install-a-profiling-client">the client</link> (see <package>blackfire</package> package) or the browser extension to actually trigger the profiling.
45- </para>
00046</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-blackfire">
4+ <title>Blackfire profiler</title>
5+ <para>
6+ <emphasis>Source:</emphasis>
7+ <filename>modules/services/development/blackfire.nix</filename>
8+ </para>
9+ <para>
10+ <emphasis>Upstream documentation:</emphasis>
11+ <link xlink:href="https://blackfire.io/docs/introduction">https://blackfire.io/docs/introduction</link>
12+ </para>
13+ <para>
14+ <link xlink:href="https://blackfire.io">Blackfire</link> is a
15+ proprietary tool for profiling applications. There are several
16+ languages supported by the product but currently only PHP support is
17+ packaged in Nixpkgs. The back-end consists of a module that is
18+ loaded into the language runtime (called <emphasis>probe</emphasis>)
19+ and a service (<emphasis>agent</emphasis>) that the probe connects
20+ to and that sends the profiles to the server.
21+ </para>
22+ <para>
23+ To use it, you will need to enable the agent and the probe on your
24+ server. The exact method will depend on the way you use PHP but here
25+ is an example of NixOS configuration for PHP-FPM:
26+ </para>
27+ <programlisting>
28+let
29 php = pkgs.php.withExtensions ({ enabled, all }: enabled ++ (with all; [
30 blackfire
31 ]));
···41 settings = {
42 # You will need to get credentials at https://blackfire.io/my/settings/credentials
43 # You can also use other options described in https://blackfire.io/docs/up-and-running/configuration/agent
44+ server-id = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
45+ server-token = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
46 };
47 };
4849 # Make the agent run on start-up.
50 # (WantedBy= from the upstream unit not respected: https://github.com/NixOS/nixpkgs/issues/81138)
51 # Alternately, you can start it manually with `systemctl start blackfire-agent`.
52+ systemd.services.blackfire-agent.wantedBy = [ "phpfpm-foo.service" ];
53+}
54+</programlisting>
55+ <para>
56+ On your developer machine, you will also want to install
57+ <link xlink:href="https://blackfire.io/docs/up-and-running/installation#install-a-profiling-client">the
58+ client</link> (see <literal>blackfire</literal> package) or the
59+ browser extension to actually trigger the profiling.
60+ </para>
61</chapter>
···1+# Emacs {#module-services-emacs}
2+3+<!--
4+ Documentation contributors:
5+ Damien Cassou @DamienCassou
6+ Thomas Tuegel @ttuegel
7+ Rodney Lorrimar @rvl
8+ Adam Hoese @adisbladis
9+ -->
10+11+[Emacs](https://www.gnu.org/software/emacs/) is an
12+extensible, customizable, self-documenting real-time display editor — and
13+more. At its core is an interpreter for Emacs Lisp, a dialect of the Lisp
14+programming language with extensions to support text editing.
15+16+Emacs runs within a graphical desktop environment using the X Window System,
17+but works equally well on a text terminal. Under
18+macOS, a "Mac port" edition is available, which
19+uses Apple's native GUI frameworks.
20+21+Nixpkgs provides a superior environment for
22+running Emacs. It's simple to create custom builds
23+by overriding the default packages. Chaotic collections of Emacs Lisp code
24+and extensions can be brought under control using declarative package
25+management. NixOS even provides a
26+{command}`systemd` user service for automatically starting the Emacs
27+daemon.
28+29+## Installing Emacs {#module-services-emacs-installing}
30+31+Emacs can be installed in the normal way for Nix (see
32+[](#sec-package-management)). In addition, a NixOS
33+*service* can be enabled.
34+35+### The Different Releases of Emacs {#module-services-emacs-releases}
36+37+Nixpkgs defines several basic Emacs packages.
38+The following are attributes belonging to the {var}`pkgs` set:
39+40+ {var}`emacs`
41+ : The latest stable version of Emacs using the [GTK 2](http://www.gtk.org)
42+ widget toolkit.
43+44+ {var}`emacs-nox`
45+ : Emacs built without any dependency on X11 libraries.
46+47+ {var}`emacsMacport`
48+ : Emacs with the "Mac port" patches, providing a more native look and
49+ feel under macOS.
50+51+If those aren't suitable, then the following imitation Emacs editors are
52+also available in Nixpkgs:
53+[Zile](https://www.gnu.org/software/zile/),
54+[mg](http://homepage.boetes.org/software/mg/),
55+[Yi](http://yi-editor.github.io/),
56+[jmacs](https://joe-editor.sourceforge.io/).
57+58+### Adding Packages to Emacs {#module-services-emacs-adding-packages}
59+60+Emacs includes an entire ecosystem of functionality beyond text editing,
61+including a project planner, mail and news reader, debugger interface,
62+calendar, and more.
63+64+Most extensions are gotten with the Emacs packaging system
65+({file}`package.el`) from
66+[Emacs Lisp Package Archive (ELPA)](https://elpa.gnu.org/),
67+[MELPA](https://melpa.org/),
68+[MELPA Stable](https://stable.melpa.org/), and
69+[Org ELPA](http://orgmode.org/elpa.html). Nixpkgs is
70+regularly updated to mirror all these archives.
71+72+Under NixOS, you can continue to use
73+`package-list-packages` and
74+`package-install` to install packages. You can also
75+declare the set of Emacs packages you need using the derivations from
76+Nixpkgs. The rest of this section discusses declarative installation of
77+Emacs packages through nixpkgs.
78+79+The first step to declare the list of packages you want in your Emacs
80+installation is to create a dedicated derivation. This can be done in a
81+dedicated {file}`emacs.nix` file such as:
82+83+[]{#ex-emacsNix}
84+85+```nix
86+/*
87+This is a nix expression to build Emacs and some Emacs packages I like
88+from source on any distribution where Nix is installed. This will install
89+all the dependencies from the nixpkgs repository and build the binary files
90+without interfering with the host distribution.
91+92+To build the project, type the following from the current directory:
93+94+$ nix-build emacs.nix
95+96+To run the newly compiled executable:
97+98+$ ./result/bin/emacs
99+*/
100+101+# The first non-comment line in this file indicates that
102+# the whole file represents a function.
103+{ pkgs ? import <nixpkgs> {} }:
104+105+let
106+ # The let expression below defines a myEmacs binding pointing to the
107+ # current stable version of Emacs. This binding is here to separate
108+ # the choice of the Emacs binary from the specification of the
109+ # required packages.
110+ myEmacs = pkgs.emacs;
111+ # This generates an emacsWithPackages function. It takes a single
112+ # argument: a function from a package set to a list of packages
113+ # (the packages that will be available in Emacs).
114+ emacsWithPackages = (pkgs.emacsPackagesFor myEmacs).emacsWithPackages;
115+in
116+ # The rest of the file specifies the list of packages to install. In the
117+ # example, two packages (magit and zerodark-theme) are taken from
118+ # MELPA stable.
119+ emacsWithPackages (epkgs: (with epkgs.melpaStablePackages; [
120+ magit # ; Integrate git <C-x g>
121+ zerodark-theme # ; Nicolas' theme
122+ ])
123+ # Two packages (undo-tree and zoom-frm) are taken from MELPA.
124+ ++ (with epkgs.melpaPackages; [
125+ undo-tree # ; <C-x u> to show the undo tree
126+ zoom-frm # ; increase/decrease font size for all buffers %lt;C-x C-+>
127+ ])
128+ # Three packages are taken from GNU ELPA.
129+ ++ (with epkgs.elpaPackages; [
130+ auctex # ; LaTeX mode
131+ beacon # ; highlight my cursor when scrolling
132+ nameless # ; hide current package name everywhere in elisp code
133+ ])
134+ # notmuch is taken from a nixpkgs derivation which contains an Emacs mode.
135+ ++ [
136+ pkgs.notmuch # From main packages set
137+ ])
138+```
139+140+The result of this configuration will be an {command}`emacs`
141+command which launches Emacs with all of your chosen packages in the
142+{var}`load-path`.
143+144+You can check that it works by executing this in a terminal:
145+```ShellSession
146+$ nix-build emacs.nix
147+$ ./result/bin/emacs -q
148+```
149+and then typing `M-x package-initialize`. Check that you
150+can use all the packages you want in this Emacs instance. For example, try
151+switching to the zerodark theme through `M-x load-theme <RET> zerodark <RET> y`.
152+153+::: {.tip}
154+A few popular extensions worth checking out are: auctex, company,
155+edit-server, flycheck, helm, iedit, magit, multiple-cursors, projectile,
156+and yasnippet.
157+:::
158+159+The list of available packages in the various ELPA repositories can be seen
160+with the following commands:
161+[]{#module-services-emacs-querying-packages}
162+```
163+nix-env -f "<nixpkgs>" -qaP -A emacs.pkgs.elpaPackages
164+nix-env -f "<nixpkgs>" -qaP -A emacs.pkgs.melpaPackages
165+nix-env -f "<nixpkgs>" -qaP -A emacs.pkgs.melpaStablePackages
166+nix-env -f "<nixpkgs>" -qaP -A emacs.pkgs.orgPackages
167+```
168+169+If you are on NixOS, you can install this particular Emacs for all users by
170+adding it to the list of system packages (see
171+[](#sec-declarative-package-mgmt)). Simply modify your file
172+{file}`configuration.nix` to make it contain:
173+[]{#module-services-emacs-configuration-nix}
174+```
175+{
176+ environment.systemPackages = [
177+ # [...]
178+ (import /path/to/emacs.nix { inherit pkgs; })
179+ ];
180+}
181+```
182+183+In this case, the next {command}`nixos-rebuild switch` will take
184+care of adding your {command}`emacs` to the {var}`PATH`
185+environment variable (see [](#sec-changing-config)).
186+187+<!-- fixme: i think the following is better done with config.nix
188+https://nixos.org/nixpkgs/manual/#sec-modify-via-packageOverrides
189+-->
190+191+If you are not on NixOS or want to install this particular Emacs only for
192+yourself, you can do so by adding it to your
193+{file}`~/.config/nixpkgs/config.nix` (see
194+[Nixpkgs manual](https://nixos.org/nixpkgs/manual/#sec-modify-via-packageOverrides)):
195+[]{#module-services-emacs-config-nix}
196+```
197+{
198+ packageOverrides = super: let self = super.pkgs; in {
199+ myemacs = import /path/to/emacs.nix { pkgs = self; };
200+ };
201+}
202+```
203+204+In this case, the next `nix-env -f '<nixpkgs>' -iA
205+myemacs` will take care of adding your emacs to the
206+{var}`PATH` environment variable.
207+208+### Advanced Emacs Configuration {#module-services-emacs-advanced}
209+210+If you want, you can tweak the Emacs package itself from your
211+{file}`emacs.nix`. For example, if you want to have a
212+GTK 3-based Emacs instead of the default GTK 2-based binary and remove the
213+automatically generated {file}`emacs.desktop` (useful if you
214+only use {command}`emacsclient`), you can change your file
215+{file}`emacs.nix` in this way:
216+217+[]{#ex-emacsGtk3Nix}
218+```
219+{ pkgs ? import <nixpkgs> {} }:
220+let
221+ myEmacs = (pkgs.emacs.override {
222+ # Use gtk3 instead of the default gtk2
223+ withGTK3 = true;
224+ withGTK2 = false;
225+ }).overrideAttrs (attrs: {
226+ # I don't want emacs.desktop file because I only use
227+ # emacsclient.
228+ postInstall = (attrs.postInstall or "") + ''
229+ rm $out/share/applications/emacs.desktop
230+ '';
231+ });
232+in [...]
233+```
234+235+After building this file as shown in [the example above](#ex-emacsNix), you
236+will get an GTK 3-based Emacs binary pre-loaded with your favorite packages.
237+238+## Running Emacs as a Service {#module-services-emacs-running}
239+240+NixOS provides an optional
241+{command}`systemd` service which launches
242+[Emacs daemon](https://www.gnu.org/software/emacs/manual/html_node/emacs/Emacs-Server.html)
243+with the user's login session.
244+245+*Source:* {file}`modules/services/editors/emacs.nix`
246+247+### Enabling the Service {#module-services-emacs-enabling}
248+249+To install and enable the {command}`systemd` user service for Emacs
250+daemon, add the following to your {file}`configuration.nix`:
251+```
252+services.emacs.enable = true;
253+services.emacs.package = import /home/cassou/.emacs.d { pkgs = pkgs; };
254+```
255+256+The {var}`services.emacs.package` option allows a custom
257+derivation to be used, for example, one created by
258+`emacsWithPackages`.
259+260+Ensure that the Emacs server is enabled for your user's Emacs
261+configuration, either by customizing the {var}`server-mode`
262+variable, or by adding `(server-start)` to
263+{file}`~/.emacs.d/init.el`.
264+265+To start the daemon, execute the following:
266+```ShellSession
267+$ nixos-rebuild switch # to activate the new configuration.nix
268+$ systemctl --user daemon-reload # to force systemd reload
269+$ systemctl --user start emacs.service # to start the Emacs daemon
270+```
271+The server should now be ready to serve Emacs clients.
272+273+### Starting the client {#module-services-emacs-starting-client}
274+275+Ensure that the emacs server is enabled, either by customizing the
276+{var}`server-mode` variable, or by adding
277+`(server-start)` to {file}`~/.emacs`.
278+279+To connect to the emacs daemon, run one of the following:
280+```
281+emacsclient FILENAME
282+emacsclient --create-frame # opens a new frame (window)
283+emacsclient --create-frame --tty # opens a new frame on the current terminal
284+```
285+286+### Configuring the {var}`EDITOR` variable {#module-services-emacs-editor-variable}
287+288+<!--<title>{command}`emacsclient` as the Default Editor</title>-->
289+290+If [](#opt-services.emacs.defaultEditor) is
291+`true`, the {var}`EDITOR` variable will be set
292+to a wrapper script which launches {command}`emacsclient`.
293+294+Any setting of {var}`EDITOR` in the shell config files will
295+override {var}`services.emacs.defaultEditor`. To make sure
296+{var}`EDITOR` refers to the Emacs wrapper script, remove any
297+existing {var}`EDITOR` assignment from
298+{file}`.profile`, {file}`.bashrc`,
299+{file}`.zshenv` or any other shell config file.
300+301+If you have formed certain bad habits when editing files, these can be
302+corrected with a shell alias to the wrapper script:
303+```
304+alias vi=$EDITOR
305+```
306+307+### Per-User Enabling of the Service {#module-services-emacs-per-user}
308+309+In general, {command}`systemd` user services are globally enabled
310+by symlinks in {file}`/etc/systemd/user`. In the case where
311+Emacs daemon is not wanted for all users, it is possible to install the
312+service but not globally enable it:
313+```
314+services.emacs.enable = false;
315+services.emacs.install = true;
316+```
317+318+To enable the {command}`systemd` user service for just the
319+currently logged in user, run:
320+```
321+systemctl --user enable emacs
322+```
323+This will add the symlink
324+{file}`~/.config/systemd/user/emacs.service`.
325+326+## Configuring Emacs {#module-services-emacs-configuring}
327+328+The Emacs init file should be changed to load the extension packages at
329+startup:
330+[]{#module-services-emacs-package-initialisation}
331+```
332+(require 'package)
333+334+;; optional. makes unpure packages archives unavailable
335+(setq package-archives nil)
336+337+(setq package-enable-at-startup nil)
338+(package-initialize)
339+```
340+341+After the declarative emacs package configuration has been tested,
342+previously downloaded packages can be cleaned up by removing
343+{file}`~/.emacs.d/elpa` (do make a backup first, in case you
344+forgot a package).
345+346+<!--
347+ todo: is it worth documenting customizations for
348+ server-switch-hook, server-done-hook?
349+ -->
350+351+### A Major Mode for Nix Expressions {#module-services-emacs-major-mode}
352+353+Of interest may be {var}`melpaPackages.nix-mode`, which
354+provides syntax highlighting for the Nix language. This is particularly
355+convenient if you regularly edit Nix files.
356+357+### Accessing man pages {#module-services-emacs-man-pages}
358+359+You can use `woman` to get completion of all available
360+man pages. For example, type `M-x woman <RET> nixos-rebuild <RET>.`
361+362+### Editing DocBook 5 XML Documents {#sec-emacs-docbook-xml}
363+364+Emacs includes
365+[nXML](https://www.gnu.org/software/emacs/manual/html_node/nxml-mode/Introduction.html),
366+a major-mode for validating and editing XML documents. When editing DocBook
367+5.0 documents, such as [this one](#book-nixos-manual),
368+nXML needs to be configured with the relevant schema, which is not
369+included.
370+371+To install the DocBook 5.0 schemas, either add
372+{var}`pkgs.docbook5` to [](#opt-environment.systemPackages)
373+([NixOS](#sec-declarative-package-mgmt)), or run
374+`nix-env -f '<nixpkgs>' -iA docbook5`
375+([Nix](#sec-ad-hoc-packages)).
376+377+Then customize the variable {var}`rng-schema-locating-files` to
378+include {file}`~/.emacs.d/schemas.xml` and put the following
379+text into that file:
380+[]{#ex-emacs-docbook-xml}
381+```xml
382+<?xml version="1.0"?>
383+<!--
384+ To let emacs find this file, evaluate:
385+ (add-to-list 'rng-schema-locating-files "~/.emacs.d/schemas.xml")
386+-->
387+<locatingRules xmlns="http://thaiopensource.com/ns/locating-rules/1.0">
388+ <!--
389+ Use this variation if pkgs.docbook5 is added to environment.systemPackages
390+ -->
391+ <namespace ns="http://docbook.org/ns/docbook"
392+ uri="/run/current-system/sw/share/xml/docbook-5.0/rng/docbookxi.rnc"/>
393+ <!--
394+ Use this variation if installing schema with "nix-env -iA pkgs.docbook5".
395+ <namespace ns="http://docbook.org/ns/docbook"
396+ uri="../.nix-profile/share/xml/docbook-5.0/rng/docbookxi.rnc"/>
397+ -->
398+</locatingRules>
399+```
+411-501
nixos/modules/services/editors/emacs.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-emacs">
6- <title>Emacs</title>
7-<!--
8- Documentation contributors:
9- Damien Cassou @DamienCassou
10- Thomas Tuegel @ttuegel
11- Rodney Lorrimar @rvl
12- Adam Hoese @adisbladis
13- -->
14- <para>
15- <link xlink:href="https://www.gnu.org/software/emacs/">Emacs</link> is an
16- extensible, customizable, self-documenting real-time display editor — and
17- more. At its core is an interpreter for Emacs Lisp, a dialect of the Lisp
18- programming language with extensions to support text editing.
19- </para>
20- <para>
21- Emacs runs within a graphical desktop environment using the X Window System,
22- but works equally well on a text terminal. Under
23- <productname>macOS</productname>, a "Mac port" edition is available, which
24- uses Apple's native GUI frameworks.
25- </para>
26- <para>
27- <productname>Nixpkgs</productname> provides a superior environment for
28- running <application>Emacs</application>. It's simple to create custom builds
29- by overriding the default packages. Chaotic collections of Emacs Lisp code
30- and extensions can be brought under control using declarative package
31- management. <productname>NixOS</productname> even provides a
32- <command>systemd</command> user service for automatically starting the Emacs
33- daemon.
34- </para>
35- <section xml:id="module-services-emacs-installing">
36- <title>Installing <application>Emacs</application></title>
37-38 <para>
39- Emacs can be installed in the normal way for Nix (see
40- <xref linkend="sec-package-management" />). In addition, a NixOS
41- <emphasis>service</emphasis> can be enabled.
0042 </para>
43-44- <section xml:id="module-services-emacs-releases">
45- <title>The Different Releases of Emacs</title>
46-47- <para>
48- <productname>Nixpkgs</productname> defines several basic Emacs packages.
49- The following are attributes belonging to the <varname>pkgs</varname> set:
50- <variablelist>
51- <varlistentry>
52- <term>
53- <varname>emacs</varname>
54- </term>
55- <term>
56- <varname>emacs</varname>
57- </term>
58- <listitem>
59- <para>
60- The latest stable version of Emacs using the
61- <link
62- xlink:href="http://www.gtk.org">GTK 2</link>
63- widget toolkit.
64- </para>
65- </listitem>
66- </varlistentry>
67- <varlistentry>
68- <term>
69- <varname>emacs-nox</varname>
70- </term>
71- <listitem>
72- <para>
73- Emacs built without any dependency on X11 libraries.
74- </para>
75- </listitem>
76- </varlistentry>
77- <varlistentry>
78- <term>
79- <varname>emacsMacport</varname>
80- </term>
81- <term>
82- <varname>emacsMacport</varname>
83- </term>
84- <listitem>
85- <para>
86- Emacs with the "Mac port" patches, providing a more native look and
87- feel under macOS.
88- </para>
89- </listitem>
90- </varlistentry>
91- </variablelist>
92- </para>
93-94- <para>
95- If those aren't suitable, then the following imitation Emacs editors are
96- also available in Nixpkgs:
97- <link xlink:href="https://www.gnu.org/software/zile/">Zile</link>,
98- <link xlink:href="http://homepage.boetes.org/software/mg/">mg</link>,
99- <link xlink:href="http://yi-editor.github.io/">Yi</link>,
100- <link xlink:href="https://joe-editor.sourceforge.io/">jmacs</link>.
101- </para>
102- </section>
103-104- <section xml:id="module-services-emacs-adding-packages">
105- <title>Adding Packages to Emacs</title>
106-107- <para>
108- Emacs includes an entire ecosystem of functionality beyond text editing,
109- including a project planner, mail and news reader, debugger interface,
110- calendar, and more.
111- </para>
112-113- <para>
114- Most extensions are gotten with the Emacs packaging system
115- (<filename>package.el</filename>) from
116- <link
117- xlink:href="https://elpa.gnu.org/">Emacs Lisp Package Archive
118- (<acronym>ELPA</acronym>)</link>,
119- <link xlink:href="https://melpa.org/"><acronym>MELPA</acronym></link>,
120- <link xlink:href="https://stable.melpa.org/">MELPA Stable</link>, and
121- <link xlink:href="http://orgmode.org/elpa.html">Org ELPA</link>. Nixpkgs is
122- regularly updated to mirror all these archives.
123- </para>
124-125- <para>
126- Under NixOS, you can continue to use
127- <function>package-list-packages</function> and
128- <function>package-install</function> to install packages. You can also
129- declare the set of Emacs packages you need using the derivations from
130- Nixpkgs. The rest of this section discusses declarative installation of
131- Emacs packages through nixpkgs.
132- </para>
133-134- <para>
135- The first step to declare the list of packages you want in your Emacs
136- installation is to create a dedicated derivation. This can be done in a
137- dedicated <filename>emacs.nix</filename> file such as:
138- <example xml:id="ex-emacsNix">
139- <title>Nix expression to build Emacs with packages (<filename>emacs.nix</filename>)</title>
140-<programlisting language="nix">
000000000141/*
142This is a nix expression to build Emacs and some Emacs packages I like
143from source on any distribution where Nix is installed. This will install
···152153$ ./result/bin/emacs
154*/
155-{ pkgs ? import <nixpkgs> {} }: <co xml:id="ex-emacsNix-1" />
000156157let
158- myEmacs = pkgs.emacs; <co xml:id="ex-emacsNix-2" />
159- emacsWithPackages = (pkgs.emacsPackagesFor myEmacs).emacsWithPackages; <co xml:id="ex-emacsNix-3" />
0000000160in
161- emacsWithPackages (epkgs: (with epkgs.melpaStablePackages; [ <co xml:id="ex-emacsNix-4" />
000162 magit # ; Integrate git <C-x g>
163 zerodark-theme # ; Nicolas' theme
164- ]) ++ (with epkgs.melpaPackages; [ <co xml:id="ex-emacsNix-5" />
00165 undo-tree # ; <C-x u> to show the undo tree
166 zoom-frm # ; increase/decrease font size for all buffers %lt;C-x C-+>
167- ]) ++ (with epkgs.elpaPackages; [ <co xml:id="ex-emacsNix-6" />
00168 auctex # ; LaTeX mode
169 beacon # ; highlight my cursor when scrolling
170 nameless # ; hide current package name everywhere in elisp code
171- ]) ++ [
172- pkgs.notmuch # From main packages set <co xml:id="ex-emacsNix-7" />
00173 ])
174</programlisting>
175- </example>
176- <calloutlist>
177- <callout arearefs="ex-emacsNix-1">
178 <para>
179- The first non-comment line in this file (<literal>{ pkgs ? ...
180- }</literal>) indicates that the whole file represents a function.
0181 </para>
182- </callout>
183- <callout arearefs="ex-emacsNix-2">
184 <para>
185- The <varname>let</varname> expression below defines a
186- <varname>myEmacs</varname> binding pointing to the current stable
187- version of Emacs. This binding is here to separate the choice of the
188- Emacs binary from the specification of the required packages.
189 </para>
190- </callout>
191- <callout arearefs="ex-emacsNix-3">
00192 <para>
193- This generates an <varname>emacsWithPackages</varname> function. It
194- takes a single argument: a function from a package set to a list of
195- packages (the packages that will be available in Emacs).
196- </para>
197- </callout>
198- <callout arearefs="ex-emacsNix-4">
199- <para>
200- The rest of the file specifies the list of packages to install. In the
201- example, two packages (<varname>magit</varname> and
202- <varname>zerodark-theme</varname>) are taken from MELPA stable.
203- </para>
204- </callout>
205- <callout arearefs="ex-emacsNix-5">
206- <para>
207- Two packages (<varname>undo-tree</varname> and
208- <varname>zoom-frm</varname>) are taken from MELPA.
209 </para>
210- </callout>
211- <callout arearefs="ex-emacsNix-6">
00000212 <para>
213- Three packages are taken from GNU ELPA.
00214 </para>
215- </callout>
216- <callout arearefs="ex-emacsNix-7">
0000217 <para>
218- <varname>notmuch</varname> is taken from a nixpkgs derivation which
219- contains an Emacs mode.
0000220 </para>
221- </callout>
222- </calloutlist>
223- </para>
224-225- <para>
226- The result of this configuration will be an <command>emacs</command>
227- command which launches Emacs with all of your chosen packages in the
228- <varname>load-path</varname>.
229- </para>
230-231- <para>
232- You can check that it works by executing this in a terminal:
233-<screen>
234-<prompt>$ </prompt>nix-build emacs.nix
235-<prompt>$ </prompt>./result/bin/emacs -q
236-</screen>
237- and then typing <literal>M-x package-initialize</literal>. Check that you
238- can use all the packages you want in this Emacs instance. For example, try
239- switching to the zerodark theme through <literal>M-x load-theme <RET>
240- zerodark <RET> y</literal>.
241- </para>
242-243- <tip>
244- <para>
245- A few popular extensions worth checking out are: auctex, company,
246- edit-server, flycheck, helm, iedit, magit, multiple-cursors, projectile,
247- and yasnippet.
248- </para>
249- </tip>
250-251- <para>
252- The list of available packages in the various ELPA repositories can be seen
253- with the following commands:
254- <example xml:id="module-services-emacs-querying-packages">
255- <title>Querying Emacs packages</title>
256-<programlisting><![CDATA[
257-nix-env -f "<nixpkgs>" -qaP -A emacs.pkgs.elpaPackages
258-nix-env -f "<nixpkgs>" -qaP -A emacs.pkgs.melpaPackages
259-nix-env -f "<nixpkgs>" -qaP -A emacs.pkgs.melpaStablePackages
260-nix-env -f "<nixpkgs>" -qaP -A emacs.pkgs.orgPackages
261-]]></programlisting>
262- </example>
263- </para>
264-265- <para>
266- If you are on NixOS, you can install this particular Emacs for all users by
267- adding it to the list of system packages (see
268- <xref linkend="sec-declarative-package-mgmt" />). Simply modify your file
269- <filename>configuration.nix</filename> to make it contain:
270- <example xml:id="module-services-emacs-configuration-nix">
271- <title>Custom Emacs in <filename>configuration.nix</filename></title>
272-<programlisting><![CDATA[
273{
274 environment.systemPackages = [
275 # [...]
276 (import /path/to/emacs.nix { inherit pkgs; })
277 ];
278}
279-]]></programlisting>
280- </example>
281- </para>
282-283- <para>
284- In this case, the next <command>nixos-rebuild switch</command> will take
285- care of adding your <command>emacs</command> to the <varname>PATH</varname>
286- environment variable (see <xref linkend="sec-changing-config" />).
287- </para>
288-289-<!-- fixme: i think the following is better done with config.nix
290-https://nixos.org/nixpkgs/manual/#sec-modify-via-packageOverrides
291--->
292-293- <para>
294- If you are not on NixOS or want to install this particular Emacs only for
295- yourself, you can do so by adding it to your
296- <filename>~/.config/nixpkgs/config.nix</filename> (see
297- <link xlink:href="https://nixos.org/nixpkgs/manual/#sec-modify-via-packageOverrides">Nixpkgs
298- manual</link>):
299- <example xml:id="module-services-emacs-config-nix">
300- <title>Custom Emacs in <filename>~/.config/nixpkgs/config.nix</filename></title>
301-<programlisting><![CDATA[
302{
303 packageOverrides = super: let self = super.pkgs; in {
304 myemacs = import /path/to/emacs.nix { pkgs = self; };
305 };
306}
307-]]></programlisting>
308- </example>
309- </para>
310-311- <para>
312- In this case, the next <literal>nix-env -f '<nixpkgs>' -iA
313- myemacs</literal> will take care of adding your emacs to the
314- <varname>PATH</varname> environment variable.
315- </para>
316- </section>
317-318- <section xml:id="module-services-emacs-advanced">
319- <title>Advanced Emacs Configuration</title>
320-321- <para>
322- If you want, you can tweak the Emacs package itself from your
323- <filename>emacs.nix</filename>. For example, if you want to have a
324- GTK 3-based Emacs instead of the default GTK 2-based binary and remove the
325- automatically generated <filename>emacs.desktop</filename> (useful if you
326- only use <command>emacsclient</command>), you can change your file
327- <filename>emacs.nix</filename> in this way:
328- </para>
329-330- <example xml:id="ex-emacsGtk3Nix">
331- <title>Custom Emacs build</title>
332-<programlisting><![CDATA[
333-{ pkgs ? import <nixpkgs> {} }:
334let
335 myEmacs = (pkgs.emacs.override {
336 # Use gtk3 instead of the default gtk2
···339 }).overrideAttrs (attrs: {
340 # I don't want emacs.desktop file because I only use
341 # emacsclient.
342- postInstall = (attrs.postInstall or "") + ''
343 rm $out/share/applications/emacs.desktop
344 '';
345 });
346in [...]
347-]]></programlisting>
348- </example>
349-350- <para>
351- After building this file as shown in <xref linkend="ex-emacsNix" />, you
352- will get an GTK 3-based Emacs binary pre-loaded with your favorite packages.
353- </para>
354- </section>
355- </section>
356- <section xml:id="module-services-emacs-running">
357- <title>Running Emacs as a Service</title>
358-359- <para>
360- <productname>NixOS</productname> provides an optional
361- <command>systemd</command> service which launches
362- <link xlink:href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Emacs-Server.html">
363- Emacs daemon </link> with the user's login session.
364- </para>
365-366- <para>
367- <emphasis>Source:</emphasis>
368- <filename>modules/services/editors/emacs.nix</filename>
369- </para>
370-371- <section xml:id="module-services-emacs-enabling">
372- <title>Enabling the Service</title>
373-374- <para>
375- To install and enable the <command>systemd</command> user service for Emacs
376- daemon, add the following to your <filename>configuration.nix</filename>:
377-<programlisting>
378-<xref linkend="opt-services.emacs.enable"/> = true;
379-<xref linkend="opt-services.emacs.package"/> = import /home/cassou/.emacs.d { pkgs = pkgs; };
380</programlisting>
381- </para>
382-383- <para>
384- The <varname>services.emacs.package</varname> option allows a custom
385- derivation to be used, for example, one created by
386- <function>emacsWithPackages</function>.
387- </para>
388-389- <para>
390- Ensure that the Emacs server is enabled for your user's Emacs
391- configuration, either by customizing the <varname>server-mode</varname>
392- variable, or by adding <literal>(server-start)</literal> to
393- <filename>~/.emacs.d/init.el</filename>.
394- </para>
395-396- <para>
397- To start the daemon, execute the following:
398-<screen>
399-<prompt>$ </prompt>nixos-rebuild switch # to activate the new configuration.nix
400-<prompt>$ </prompt>systemctl --user daemon-reload # to force systemd reload
401-<prompt>$ </prompt>systemctl --user start emacs.service # to start the Emacs daemon
402-</screen>
403- The server should now be ready to serve Emacs clients.
404- </para>
405 </section>
406-407- <section xml:id="module-services-emacs-starting-client">
408- <title>Starting the client</title>
409-410- <para>
411- Ensure that the emacs server is enabled, either by customizing the
412- <varname>server-mode</varname> variable, or by adding
413- <literal>(server-start)</literal> to <filename>~/.emacs</filename>.
414- </para>
415-416- <para>
417- To connect to the emacs daemon, run one of the following:
418-<programlisting><![CDATA[
0000000000000000000000000000000000000000000000419emacsclient FILENAME
420emacsclient --create-frame # opens a new frame (window)
421emacsclient --create-frame --tty # opens a new frame on the current terminal
422-]]></programlisting>
423- </para>
424- </section>
425-426- <section xml:id="module-services-emacs-editor-variable">
427- <title>Configuring the <varname>EDITOR</varname> variable</title>
428-429-<!--<title><command>emacsclient</command> as the Default Editor</title>-->
430-431- <para>
432- If <xref linkend="opt-services.emacs.defaultEditor"/> is
433- <literal>true</literal>, the <varname>EDITOR</varname> variable will be set
434- to a wrapper script which launches <command>emacsclient</command>.
435- </para>
436-437- <para>
438- Any setting of <varname>EDITOR</varname> in the shell config files will
439- override <varname>services.emacs.defaultEditor</varname>. To make sure
440- <varname>EDITOR</varname> refers to the Emacs wrapper script, remove any
441- existing <varname>EDITOR</varname> assignment from
442- <filename>.profile</filename>, <filename>.bashrc</filename>,
443- <filename>.zshenv</filename> or any other shell config file.
444- </para>
445-446- <para>
447- If you have formed certain bad habits when editing files, these can be
448- corrected with a shell alias to the wrapper script:
449-<programlisting>alias vi=$EDITOR</programlisting>
450- </para>
451- </section>
452-453- <section xml:id="module-services-emacs-per-user">
454- <title>Per-User Enabling of the Service</title>
455-456- <para>
457- In general, <command>systemd</command> user services are globally enabled
458- by symlinks in <filename>/etc/systemd/user</filename>. In the case where
459- Emacs daemon is not wanted for all users, it is possible to install the
460- service but not globally enable it:
461-<programlisting>
462-<xref linkend="opt-services.emacs.enable"/> = false;
463-<xref linkend="opt-services.emacs.install"/> = true;
464</programlisting>
465- </para>
466-467- <para>
468- To enable the <command>systemd</command> user service for just the
469- currently logged in user, run:
470-<programlisting>systemctl --user enable emacs</programlisting>
471- This will add the symlink
472- <filename>~/.config/systemd/user/emacs.service</filename>.
473- </para>
000000000000000000000000000000000000000000474 </section>
475- </section>
476- <section xml:id="module-services-emacs-configuring">
477- <title>Configuring Emacs</title>
478-479- <para>
480- The Emacs init file should be changed to load the extension packages at
481- startup:
482- <example xml:id="module-services-emacs-package-initialisation">
483- <title>Package initialization in <filename>.emacs</filename></title>
484-<programlisting><![CDATA[
485(require 'package)
486487;; optional. makes unpure packages archives unavailable
···489490(setq package-enable-at-startup nil)
491(package-initialize)
492-]]></programlisting>
493- </example>
494- </para>
495-496- <para>
497- After the declarative emacs package configuration has been tested,
498- previously downloaded packages can be cleaned up by removing
499- <filename>~/.emacs.d/elpa</filename> (do make a backup first, in case you
500- forgot a package).
501- </para>
502-503-<!--
504- todo: is it worth documenting customizations for
505- server-switch-hook, server-done-hook?
506- -->
507-508- <section xml:id="module-services-emacs-major-mode">
509- <title>A Major Mode for Nix Expressions</title>
510-511- <para>
512- Of interest may be <varname>melpaPackages.nix-mode</varname>, which
513- provides syntax highlighting for the Nix language. This is particularly
514- convenient if you regularly edit Nix files.
515- </para>
516- </section>
517-518- <section xml:id="module-services-emacs-man-pages">
519- <title>Accessing man pages</title>
520-521- <para>
522- You can use <function>woman</function> to get completion of all available
523- man pages. For example, type <literal>M-x woman <RET> nixos-rebuild
524- <RET>.</literal>
525- </para>
526- </section>
527-528- <section xml:id="sec-emacs-docbook-xml">
529- <title>Editing DocBook 5 XML Documents</title>
530-531- <para>
532- Emacs includes
533- <link
534- xlink:href="https://www.gnu.org/software/emacs/manual/html_node/nxml-mode/Introduction.html">nXML</link>,
535- a major-mode for validating and editing XML documents. When editing DocBook
536- 5.0 documents, such as <link linkend="book-nixos-manual">this one</link>,
537- nXML needs to be configured with the relevant schema, which is not
538- included.
539- </para>
540-541- <para>
542- To install the DocBook 5.0 schemas, either add
543- <varname>pkgs.docbook5</varname> to
544- <xref linkend="opt-environment.systemPackages"/>
545- (<link
546- linkend="sec-declarative-package-mgmt">NixOS</link>), or run
547- <literal>nix-env -f '<nixpkgs>' -iA docbook5</literal>
548- (<link linkend="sec-ad-hoc-packages">Nix</link>).
549- </para>
550-551- <para>
552- Then customize the variable <varname>rng-schema-locating-files</varname> to
553- include <filename>~/.emacs.d/schemas.xml</filename> and put the following
554- text into that file:
555- <example xml:id="ex-emacs-docbook-xml">
556- <title>nXML Schema Configuration (<filename>~/.emacs.d/schemas.xml</filename>)</title>
557-<programlisting language="xml"><![CDATA[
558-<?xml version="1.0"?>
559-<!--
560 To let emacs find this file, evaluate:
561- (add-to-list 'rng-schema-locating-files "~/.emacs.d/schemas.xml")
562--->
563-<locatingRules xmlns="http://thaiopensource.com/ns/locating-rules/1.0">
564- <!--
565 Use this variation if pkgs.docbook5 is added to environment.systemPackages
566- -->
567- <namespace ns="http://docbook.org/ns/docbook"
568- uri="/run/current-system/sw/share/xml/docbook-5.0/rng/docbookxi.rnc"/>
569- <!--
570- Use this variation if installing schema with "nix-env -iA pkgs.docbook5".
571- <namespace ns="http://docbook.org/ns/docbook"
572- uri="../.nix-profile/share/xml/docbook-5.0/rng/docbookxi.rnc"/>
573- -->
574-</locatingRules>
575-]]></programlisting>
576- </example>
577- </para>
578 </section>
579- </section>
580</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-emacs">
4+ <title>Emacs</title>
0000000000000000000000000000000005 <para>
6+ <link xlink:href="https://www.gnu.org/software/emacs/">Emacs</link>
7+ is an extensible, customizable, self-documenting real-time display
8+ editor — and more. At its core is an interpreter for Emacs Lisp, a
9+ dialect of the Lisp programming language with extensions to support
10+ text editing.
11 </para>
12+ <para>
13+ Emacs runs within a graphical desktop environment using the X Window
14+ System, but works equally well on a text terminal. Under macOS, a
15+ <quote>Mac port</quote> edition is available, which uses Apple’s
16+ native GUI frameworks.
17+ </para>
18+ <para>
19+ Nixpkgs provides a superior environment for running Emacs. It’s
20+ simple to create custom builds by overriding the default packages.
21+ Chaotic collections of Emacs Lisp code and extensions can be brought
22+ under control using declarative package management. NixOS even
23+ provides a <command>systemd</command> user service for automatically
24+ starting the Emacs daemon.
25+ </para>
26+ <section xml:id="module-services-emacs-installing">
27+ <title>Installing Emacs</title>
28+ <para>
29+ Emacs can be installed in the normal way for Nix (see
30+ <xref linkend="sec-package-management" />). In addition, a NixOS
31+ <emphasis>service</emphasis> can be enabled.
32+ </para>
33+ <section xml:id="module-services-emacs-releases">
34+ <title>The Different Releases of Emacs</title>
35+ <para>
36+ Nixpkgs defines several basic Emacs packages. The following are
37+ attributes belonging to the <varname>pkgs</varname> set:
38+ </para>
39+ <variablelist spacing="compact">
40+ <varlistentry>
41+ <term>
42+ <varname>emacs</varname>
43+ </term>
44+ <listitem>
45+ <para>
46+ The latest stable version of Emacs using the
47+ <link xlink:href="http://www.gtk.org">GTK 2</link> widget
48+ toolkit.
49+ </para>
50+ </listitem>
51+ </varlistentry>
52+ <varlistentry>
53+ <term>
54+ <varname>emacs-nox</varname>
55+ </term>
56+ <listitem>
57+ <para>
58+ Emacs built without any dependency on X11 libraries.
59+ </para>
60+ </listitem>
61+ </varlistentry>
62+ <varlistentry>
63+ <term>
64+ <varname>emacsMacport</varname>
65+ </term>
66+ <listitem>
67+ <para>
68+ Emacs with the <quote>Mac port</quote> patches, providing
69+ a more native look and feel under macOS.
70+ </para>
71+ </listitem>
72+ </varlistentry>
73+ </variablelist>
74+ <para>
75+ If those aren’t suitable, then the following imitation Emacs
76+ editors are also available in Nixpkgs:
77+ <link xlink:href="https://www.gnu.org/software/zile/">Zile</link>,
78+ <link xlink:href="http://homepage.boetes.org/software/mg/">mg</link>,
79+ <link xlink:href="http://yi-editor.github.io/">Yi</link>,
80+ <link xlink:href="https://joe-editor.sourceforge.io/">jmacs</link>.
81+ </para>
82+ </section>
83+ <section xml:id="module-services-emacs-adding-packages">
84+ <title>Adding Packages to Emacs</title>
85+ <para>
86+ Emacs includes an entire ecosystem of functionality beyond text
87+ editing, including a project planner, mail and news reader,
88+ debugger interface, calendar, and more.
89+ </para>
90+ <para>
91+ Most extensions are gotten with the Emacs packaging system
92+ (<filename>package.el</filename>) from
93+ <link xlink:href="https://elpa.gnu.org/">Emacs Lisp Package
94+ Archive (ELPA)</link>,
95+ <link xlink:href="https://melpa.org/">MELPA</link>,
96+ <link xlink:href="https://stable.melpa.org/">MELPA
97+ Stable</link>, and
98+ <link xlink:href="http://orgmode.org/elpa.html">Org ELPA</link>.
99+ Nixpkgs is regularly updated to mirror all these archives.
100+ </para>
101+ <para>
102+ Under NixOS, you can continue to use
103+ <literal>package-list-packages</literal> and
104+ <literal>package-install</literal> to install packages. You can
105+ also declare the set of Emacs packages you need using the
106+ derivations from Nixpkgs. The rest of this section discusses
107+ declarative installation of Emacs packages through nixpkgs.
108+ </para>
109+ <para>
110+ The first step to declare the list of packages you want in your
111+ Emacs installation is to create a dedicated derivation. This can
112+ be done in a dedicated <filename>emacs.nix</filename> file such
113+ as:
114+ </para>
115+ <para>
116+ <anchor xml:id="ex-emacsNix" />
117+ </para>
118+ <programlisting language="nix">
119/*
120This is a nix expression to build Emacs and some Emacs packages I like
121from source on any distribution where Nix is installed. This will install
···130131$ ./result/bin/emacs
132*/
133+134+# The first non-comment line in this file indicates that
135+# the whole file represents a function.
136+{ pkgs ? import <nixpkgs> {} }:
137138let
139+ # The let expression below defines a myEmacs binding pointing to the
140+ # current stable version of Emacs. This binding is here to separate
141+ # the choice of the Emacs binary from the specification of the
142+ # required packages.
143+ myEmacs = pkgs.emacs;
144+ # This generates an emacsWithPackages function. It takes a single
145+ # argument: a function from a package set to a list of packages
146+ # (the packages that will be available in Emacs).
147+ emacsWithPackages = (pkgs.emacsPackagesFor myEmacs).emacsWithPackages;
148in
149+ # The rest of the file specifies the list of packages to install. In the
150+ # example, two packages (magit and zerodark-theme) are taken from
151+ # MELPA stable.
152+ emacsWithPackages (epkgs: (with epkgs.melpaStablePackages; [
153 magit # ; Integrate git <C-x g>
154 zerodark-theme # ; Nicolas' theme
155+ ])
156+ # Two packages (undo-tree and zoom-frm) are taken from MELPA.
157+ ++ (with epkgs.melpaPackages; [
158 undo-tree # ; <C-x u> to show the undo tree
159 zoom-frm # ; increase/decrease font size for all buffers %lt;C-x C-+>
160+ ])
161+ # Three packages are taken from GNU ELPA.
162+ ++ (with epkgs.elpaPackages; [
163 auctex # ; LaTeX mode
164 beacon # ; highlight my cursor when scrolling
165 nameless # ; hide current package name everywhere in elisp code
166+ ])
167+ # notmuch is taken from a nixpkgs derivation which contains an Emacs mode.
168+ ++ [
169+ pkgs.notmuch # From main packages set
170 ])
171</programlisting>
000172 <para>
173+ The result of this configuration will be an
174+ <command>emacs</command> command which launches Emacs with all
175+ of your chosen packages in the <varname>load-path</varname>.
176 </para>
00177 <para>
178+ You can check that it works by executing this in a terminal:
000179 </para>
180+ <programlisting>
181+$ nix-build emacs.nix
182+$ ./result/bin/emacs -q
183+</programlisting>
184 <para>
185+ and then typing <literal>M-x package-initialize</literal>. Check
186+ that you can use all the packages you want in this Emacs
187+ instance. For example, try switching to the zerodark theme
188+ through
189+ <literal>M-x load-theme <RET> zerodark <RET> y</literal>.
00000000000190 </para>
191+ <tip>
192+ <para>
193+ A few popular extensions worth checking out are: auctex,
194+ company, edit-server, flycheck, helm, iedit, magit,
195+ multiple-cursors, projectile, and yasnippet.
196+ </para>
197+ </tip>
198 <para>
199+ The list of available packages in the various ELPA repositories
200+ can be seen with the following commands:
201+ <anchor xml:id="module-services-emacs-querying-packages" />
202 </para>
203+ <programlisting>
204+nix-env -f "<nixpkgs>" -qaP -A emacs.pkgs.elpaPackages
205+nix-env -f "<nixpkgs>" -qaP -A emacs.pkgs.melpaPackages
206+nix-env -f "<nixpkgs>" -qaP -A emacs.pkgs.melpaStablePackages
207+nix-env -f "<nixpkgs>" -qaP -A emacs.pkgs.orgPackages
208+</programlisting>
209 <para>
210+ If you are on NixOS, you can install this particular Emacs for
211+ all users by adding it to the list of system packages (see
212+ <xref linkend="sec-declarative-package-mgmt" />). Simply modify
213+ your file <filename>configuration.nix</filename> to make it
214+ contain:
215+ <anchor xml:id="module-services-emacs-configuration-nix" />
216 </para>
217+ <programlisting>
000000000000000000000000000000000000000000000000000218{
219 environment.systemPackages = [
220 # [...]
221 (import /path/to/emacs.nix { inherit pkgs; })
222 ];
223}
224+</programlisting>
225+ <para>
226+ In this case, the next <command>nixos-rebuild switch</command>
227+ will take care of adding your <command>emacs</command> to the
228+ <varname>PATH</varname> environment variable (see
229+ <xref linkend="sec-changing-config" />).
230+ </para>
231+ <para>
232+ If you are not on NixOS or want to install this particular Emacs
233+ only for yourself, you can do so by adding it to your
234+ <filename>~/.config/nixpkgs/config.nix</filename> (see
235+ <link xlink:href="https://nixos.org/nixpkgs/manual/#sec-modify-via-packageOverrides">Nixpkgs
236+ manual</link>):
237+ <anchor xml:id="module-services-emacs-config-nix" />
238+ </para>
239+ <programlisting>
0000000240{
241 packageOverrides = super: let self = super.pkgs; in {
242 myemacs = import /path/to/emacs.nix { pkgs = self; };
243 };
244}
245+</programlisting>
246+ <para>
247+ In this case, the next
248+ <literal>nix-env -f '<nixpkgs>' -iA myemacs</literal> will
249+ take care of adding your emacs to the <varname>PATH</varname>
250+ environment variable.
251+ </para>
252+ </section>
253+ <section xml:id="module-services-emacs-advanced">
254+ <title>Advanced Emacs Configuration</title>
255+ <para>
256+ If you want, you can tweak the Emacs package itself from your
257+ <filename>emacs.nix</filename>. For example, if you want to have
258+ a GTK 3-based Emacs instead of the default GTK 2-based binary
259+ and remove the automatically generated
260+ <filename>emacs.desktop</filename> (useful if you only use
261+ <command>emacsclient</command>), you can change your file
262+ <filename>emacs.nix</filename> in this way:
263+ </para>
264+ <para>
265+ <anchor xml:id="ex-emacsGtk3Nix" />
266+ </para>
267+ <programlisting>
268+{ pkgs ? import <nixpkgs> {} }:
000269let
270 myEmacs = (pkgs.emacs.override {
271 # Use gtk3 instead of the default gtk2
···274 }).overrideAttrs (attrs: {
275 # I don't want emacs.desktop file because I only use
276 # emacsclient.
277+ postInstall = (attrs.postInstall or "") + ''
278 rm $out/share/applications/emacs.desktop
279 '';
280 });
281in [...]
000000000000000000000000000000000282</programlisting>
283+ <para>
284+ After building this file as shown in
285+ <link linkend="ex-emacsNix">the example above</link>, you will
286+ get an GTK 3-based Emacs binary pre-loaded with your favorite
287+ packages.
288+ </para>
289+ </section>
00000000000000000290 </section>
291+ <section xml:id="module-services-emacs-running">
292+ <title>Running Emacs as a Service</title>
293+ <para>
294+ NixOS provides an optional <command>systemd</command> service
295+ which launches
296+ <link xlink:href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Emacs-Server.html">Emacs
297+ daemon</link> with the user’s login session.
298+ </para>
299+ <para>
300+ <emphasis>Source:</emphasis>
301+ <filename>modules/services/editors/emacs.nix</filename>
302+ </para>
303+ <section xml:id="module-services-emacs-enabling">
304+ <title>Enabling the Service</title>
305+ <para>
306+ To install and enable the <command>systemd</command> user
307+ service for Emacs daemon, add the following to your
308+ <filename>configuration.nix</filename>:
309+ </para>
310+ <programlisting>
311+services.emacs.enable = true;
312+services.emacs.package = import /home/cassou/.emacs.d { pkgs = pkgs; };
313+</programlisting>
314+ <para>
315+ The <varname>services.emacs.package</varname> option allows a
316+ custom derivation to be used, for example, one created by
317+ <literal>emacsWithPackages</literal>.
318+ </para>
319+ <para>
320+ Ensure that the Emacs server is enabled for your user’s Emacs
321+ configuration, either by customizing the
322+ <varname>server-mode</varname> variable, or by adding
323+ <literal>(server-start)</literal> to
324+ <filename>~/.emacs.d/init.el</filename>.
325+ </para>
326+ <para>
327+ To start the daemon, execute the following:
328+ </para>
329+ <programlisting>
330+$ nixos-rebuild switch # to activate the new configuration.nix
331+$ systemctl --user daemon-reload # to force systemd reload
332+$ systemctl --user start emacs.service # to start the Emacs daemon
333+</programlisting>
334+ <para>
335+ The server should now be ready to serve Emacs clients.
336+ </para>
337+ </section>
338+ <section xml:id="module-services-emacs-starting-client">
339+ <title>Starting the client</title>
340+ <para>
341+ Ensure that the emacs server is enabled, either by customizing
342+ the <varname>server-mode</varname> variable, or by adding
343+ <literal>(server-start)</literal> to
344+ <filename>~/.emacs</filename>.
345+ </para>
346+ <para>
347+ To connect to the emacs daemon, run one of the following:
348+ </para>
349+ <programlisting>
350emacsclient FILENAME
351emacsclient --create-frame # opens a new frame (window)
352emacsclient --create-frame --tty # opens a new frame on the current terminal
000000000000000000000000000000000000000000353</programlisting>
354+ </section>
355+ <section xml:id="module-services-emacs-editor-variable">
356+ <title>Configuring the <varname>EDITOR</varname> variable</title>
357+ <para>
358+ If <xref linkend="opt-services.emacs.defaultEditor" /> is
359+ <literal>true</literal>, the <varname>EDITOR</varname> variable
360+ will be set to a wrapper script which launches
361+ <command>emacsclient</command>.
362+ </para>
363+ <para>
364+ Any setting of <varname>EDITOR</varname> in the shell config
365+ files will override
366+ <varname>services.emacs.defaultEditor</varname>. To make sure
367+ <varname>EDITOR</varname> refers to the Emacs wrapper script,
368+ remove any existing <varname>EDITOR</varname> assignment from
369+ <filename>.profile</filename>, <filename>.bashrc</filename>,
370+ <filename>.zshenv</filename> or any other shell config file.
371+ </para>
372+ <para>
373+ If you have formed certain bad habits when editing files, these
374+ can be corrected with a shell alias to the wrapper script:
375+ </para>
376+ <programlisting>
377+alias vi=$EDITOR
378+</programlisting>
379+ </section>
380+ <section xml:id="module-services-emacs-per-user">
381+ <title>Per-User Enabling of the Service</title>
382+ <para>
383+ In general, <command>systemd</command> user services are
384+ globally enabled by symlinks in
385+ <filename>/etc/systemd/user</filename>. In the case where Emacs
386+ daemon is not wanted for all users, it is possible to install
387+ the service but not globally enable it:
388+ </para>
389+ <programlisting>
390+services.emacs.enable = false;
391+services.emacs.install = true;
392+</programlisting>
393+ <para>
394+ To enable the <command>systemd</command> user service for just
395+ the currently logged in user, run:
396+ </para>
397+ <programlisting>
398+systemctl --user enable emacs
399+</programlisting>
400+ <para>
401+ This will add the symlink
402+ <filename>~/.config/systemd/user/emacs.service</filename>.
403+ </para>
404+ </section>
405 </section>
406+ <section xml:id="module-services-emacs-configuring">
407+ <title>Configuring Emacs</title>
408+ <para>
409+ The Emacs init file should be changed to load the extension
410+ packages at startup:
411+ <anchor xml:id="module-services-emacs-package-initialisation" />
412+ </para>
413+ <programlisting>
00414(require 'package)
415416;; optional. makes unpure packages archives unavailable
···418419(setq package-enable-at-startup nil)
420(package-initialize)
421+</programlisting>
422+ <para>
423+ After the declarative emacs package configuration has been tested,
424+ previously downloaded packages can be cleaned up by removing
425+ <filename>~/.emacs.d/elpa</filename> (do make a backup first, in
426+ case you forgot a package).
427+ </para>
428+ <section xml:id="module-services-emacs-major-mode">
429+ <title>A Major Mode for Nix Expressions</title>
430+ <para>
431+ Of interest may be <varname>melpaPackages.nix-mode</varname>,
432+ which provides syntax highlighting for the Nix language. This is
433+ particularly convenient if you regularly edit Nix files.
434+ </para>
435+ </section>
436+ <section xml:id="module-services-emacs-man-pages">
437+ <title>Accessing man pages</title>
438+ <para>
439+ You can use <literal>woman</literal> to get completion of all
440+ available man pages. For example, type
441+ <literal>M-x woman <RET> nixos-rebuild <RET>.</literal>
442+ </para>
443+ </section>
444+ <section xml:id="sec-emacs-docbook-xml">
445+ <title>Editing DocBook 5 XML Documents</title>
446+ <para>
447+ Emacs includes
448+ <link xlink:href="https://www.gnu.org/software/emacs/manual/html_node/nxml-mode/Introduction.html">nXML</link>,
449+ a major-mode for validating and editing XML documents. When
450+ editing DocBook 5.0 documents, such as
451+ <link linkend="book-nixos-manual">this one</link>, nXML needs to
452+ be configured with the relevant schema, which is not included.
453+ </para>
454+ <para>
455+ To install the DocBook 5.0 schemas, either add
456+ <varname>pkgs.docbook5</varname> to
457+ <xref linkend="opt-environment.systemPackages" />
458+ (<link linkend="sec-declarative-package-mgmt">NixOS</link>), or
459+ run <literal>nix-env -f '<nixpkgs>' -iA docbook5</literal>
460+ (<link linkend="sec-ad-hoc-packages">Nix</link>).
461+ </para>
462+ <para>
463+ Then customize the variable
464+ <varname>rng-schema-locating-files</varname> to include
465+ <filename>~/.emacs.d/schemas.xml</filename> and put the
466+ following text into that file:
467+ <anchor xml:id="ex-emacs-docbook-xml" />
468+ </para>
469+ <programlisting language="xml">
470+<?xml version="1.0"?>
471+<!--
00000000000000000472 To let emacs find this file, evaluate:
473+ (add-to-list 'rng-schema-locating-files "~/.emacs.d/schemas.xml")
474+-->
475+<locatingRules xmlns="http://thaiopensource.com/ns/locating-rules/1.0">
476+ <!--
477 Use this variation if pkgs.docbook5 is added to environment.systemPackages
478+ -->
479+ <namespace ns="http://docbook.org/ns/docbook"
480+ uri="/run/current-system/sw/share/xml/docbook-5.0/rng/docbookxi.rnc"/>
481+ <!--
482+ Use this variation if installing schema with "nix-env -iA pkgs.docbook5".
483+ <namespace ns="http://docbook.org/ns/docbook"
484+ uri="../.nix-profile/share/xml/docbook-5.0/rng/docbookxi.rnc"/>
485+ -->
486+</locatingRules>
487+</programlisting>
488+ </section>
0489 </section>
0490</chapter>
+17
nixos/modules/services/hardware/trezord.md
···00000000000000000
···1+# Trezor {#trezor}
2+3+Trezor is an open-source cryptocurrency hardware wallet and security token
4+allowing secure storage of private keys.
5+6+It offers advanced features such U2F two-factor authorization, SSH login
7+through
8+[Trezor SSH agent](https://wiki.trezor.io/Apps:SSH_agent),
9+[GPG](https://wiki.trezor.io/GPG) and a
10+[password manager](https://wiki.trezor.io/Trezor_Password_Manager).
11+For more information, guides and documentation, see <https://wiki.trezor.io>.
12+13+To enable Trezor support, add the following to your {file}`configuration.nix`:
14+15+ services.trezord.enable = true;
16+17+This will add all necessary udev rules and start Trezor Bridge.
+27-24
nixos/modules/services/hardware/trezord.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="trezor">
6- <title>Trezor</title>
7- <para>
8- Trezor is an open-source cryptocurrency hardware wallet and security token
9- allowing secure storage of private keys.
10- </para>
11- <para>
12- It offers advanced features such U2F two-factor authorization, SSH login
13- through
14- <link xlink:href="https://wiki.trezor.io/Apps:SSH_agent">Trezor SSH agent</link>,
15- <link xlink:href="https://wiki.trezor.io/GPG">GPG</link> and a
16- <link xlink:href="https://wiki.trezor.io/Trezor_Password_Manager">password manager</link>.
17- For more information, guides and documentation, see <link xlink:href="https://wiki.trezor.io"/>.
18- </para>
19- <para>
20- To enable Trezor support, add the following to your <filename>configuration.nix</filename>:
21-<programlisting>
22-<xref linkend="opt-services.trezord.enable"/> = true;
0023</programlisting>
24- This will add all necessary udev rules and start Trezor Bridge.
25- </para>
026</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="trezor">
4+ <title>Trezor</title>
5+ <para>
6+ Trezor is an open-source cryptocurrency hardware wallet and security
7+ token allowing secure storage of private keys.
8+ </para>
9+ <para>
10+ It offers advanced features such U2F two-factor authorization, SSH
11+ login through
12+ <link xlink:href="https://wiki.trezor.io/Apps:SSH_agent">Trezor SSH
13+ agent</link>,
14+ <link xlink:href="https://wiki.trezor.io/GPG">GPG</link> and a
15+ <link xlink:href="https://wiki.trezor.io/Trezor_Password_Manager">password
16+ manager</link>. For more information, guides and documentation, see
17+ <link xlink:href="https://wiki.trezor.io">https://wiki.trezor.io</link>.
18+ </para>
19+ <para>
20+ To enable Trezor support, add the following to your
21+ <filename>configuration.nix</filename>:
22+ </para>
23+ <programlisting>
24+services.trezord.enable = true;
25</programlisting>
26+ <para>
27+ This will add all necessary udev rules and start Trezor Bridge.
28+ </para>
29</chapter>
···1+# Mailman {#module-services-mailman}
2+3+[Mailman](https://www.list.org) is free
4+software for managing electronic mail discussion and e-newsletter
5+lists. Mailman and its web interface can be configured using the
6+corresponding NixOS module. Note that this service is best used with
7+an existing, securely configured Postfix setup, as it does not automatically configure this.
8+9+## Basic usage with Postfix {#module-services-mailman-basic-usage}
10+11+For a basic configuration with Postfix as the MTA, the following settings are suggested:
12+```
13+{ config, ... }: {
14+ services.postfix = {
15+ enable = true;
16+ relayDomains = ["hash:/var/lib/mailman/data/postfix_domains"];
17+ sslCert = config.security.acme.certs."lists.example.org".directory + "/full.pem";
18+ sslKey = config.security.acme.certs."lists.example.org".directory + "/key.pem";
19+ config = {
20+ transport_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"];
21+ local_recipient_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"];
22+ };
23+ };
24+ services.mailman = {
25+ enable = true;
26+ serve.enable = true;
27+ hyperkitty.enable = true;
28+ webHosts = ["lists.example.org"];
29+ siteOwner = "mailman@example.org";
30+ };
31+ services.nginx.virtualHosts."lists.example.org".enableACME = true;
32+ networking.firewall.allowedTCPPorts = [ 25 80 443 ];
33+}
34+```
35+36+DNS records will also be required:
37+38+ - `AAAA` and `A` records pointing to the host in question, in order for browsers to be able to discover the address of the web server;
39+ - An `MX` record pointing to a domain name at which the host is reachable, in order for other mail servers to be able to deliver emails to the mailing lists it hosts.
40+41+After this has been done and appropriate DNS records have been
42+set up, the Postorius mailing list manager and the Hyperkitty
43+archive browser will be available at
44+https://lists.example.org/. Note that this setup is not
45+sufficient to deliver emails to most email providers nor to
46+avoid spam -- a number of additional measures for authenticating
47+incoming and outgoing mails, such as SPF, DMARC and DKIM are
48+necessary, but outside the scope of the Mailman module.
49+50+## Using with other MTAs {#module-services-mailman-other-mtas}
51+52+Mailman also supports other MTA, though with a little bit more configuration. For example, to use Mailman with Exim, you can use the following settings:
53+```
54+{ config, ... }: {
55+ services = {
56+ mailman = {
57+ enable = true;
58+ siteOwner = "mailman@example.org";
59+ enablePostfix = false;
60+ settings.mta = {
61+ incoming = "mailman.mta.exim4.LMTP";
62+ outgoing = "mailman.mta.deliver.deliver";
63+ lmtp_host = "localhost";
64+ lmtp_port = "8024";
65+ smtp_host = "localhost";
66+ smtp_port = "25";
67+ configuration = "python:mailman.config.exim4";
68+ };
69+ };
70+ exim = {
71+ enable = true;
72+ # You can configure Exim in a separate file to reduce configuration.nix clutter
73+ config = builtins.readFile ./exim.conf;
74+ };
75+ };
76+}
77+```
78+79+The exim config needs some special additions to work with Mailman. Currently
80+NixOS can't manage Exim config with such granularity. Please refer to
81+[Mailman documentation](https://mailman.readthedocs.io/en/latest/src/mailman/docs/mta.html)
82+for more info on configuring Mailman for working with Exim.
+70-52
nixos/modules/services/mail/mailman.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-mailman">
6 <title>Mailman</title>
7 <para>
8 <link xlink:href="https://www.list.org">Mailman</link> is free
9 software for managing electronic mail discussion and e-newsletter
10 lists. Mailman and its web interface can be configured using the
11 corresponding NixOS module. Note that this service is best used with
12- an existing, securely configured Postfix setup, as it does not automatically configure this.
013 </para>
14-15 <section xml:id="module-services-mailman-basic-usage">
16 <title>Basic usage with Postfix</title>
17 <para>
18- For a basic configuration with Postfix as the MTA, the following settings are suggested:
19- <programlisting>{ config, ... }: {
00020 services.postfix = {
21 enable = true;
22- relayDomains = ["hash:/var/lib/mailman/data/postfix_domains"];
23- sslCert = config.security.acme.certs."lists.example.org".directory + "/full.pem";
24- sslKey = config.security.acme.certs."lists.example.org".directory + "/key.pem";
25 config = {
26- transport_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"];
27- local_recipient_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"];
28 };
29 };
30 services.mailman = {
31- <link linkend="opt-services.mailman.enable">enable</link> = true;
32- <link linkend="opt-services.mailman.serve.enable">serve.enable</link> = true;
33- <link linkend="opt-services.mailman.hyperkitty.enable">hyperkitty.enable</link> = true;
34- <link linkend="opt-services.mailman.webHosts">webHosts</link> = ["lists.example.org"];
35- <link linkend="opt-services.mailman.siteOwner">siteOwner</link> = "mailman@example.org";
36 };
37- <link linkend="opt-services.nginx.virtualHosts._name_.enableACME">services.nginx.virtualHosts."lists.example.org".enableACME</link> = true;
38- <link linkend="opt-networking.firewall.allowedTCPPorts">networking.firewall.allowedTCPPorts</link> = [ 25 80 443 ];
39-}</programlisting>
40- </para>
41 <para>
42 DNS records will also be required:
43- <itemizedlist>
44- <listitem><para><literal>AAAA</literal> and <literal>A</literal> records pointing to the host in question, in order for browsers to be able to discover the address of the web server;</para></listitem>
45- <listitem><para>An <literal>MX</literal> record pointing to a domain name at which the host is reachable, in order for other mail servers to be able to deliver emails to the mailing lists it hosts.</para></listitem>
46- </itemizedlist>
47 </para>
000000000000000048 <para>
49- After this has been done and appropriate DNS records have been
50- set up, the Postorius mailing list manager and the Hyperkitty
51- archive browser will be available at
52- https://lists.example.org/. Note that this setup is not
53- sufficient to deliver emails to most email providers nor to
54- avoid spam -- a number of additional measures for authenticating
55- incoming and outgoing mails, such as SPF, DMARC and DKIM are
56- necessary, but outside the scope of the Mailman module.
57 </para>
58 </section>
59 <section xml:id="module-services-mailman-other-mtas">
60 <title>Using with other MTAs</title>
61 <para>
62- Mailman also supports other MTA, though with a little bit more configuration. For example, to use Mailman with Exim, you can use the following settings:
63- <programlisting>{ config, ... }: {
000064 services = {
65 mailman = {
66 enable = true;
67- siteOwner = "mailman@example.org";
68- <link linkend="opt-services.mailman.enablePostfix">enablePostfix</link> = false;
69 settings.mta = {
70- incoming = "mailman.mta.exim4.LMTP";
71- outgoing = "mailman.mta.deliver.deliver";
72- lmtp_host = "localhost";
73- lmtp_port = "8024";
74- smtp_host = "localhost";
75- smtp_port = "25";
76- configuration = "python:mailman.config.exim4";
77 };
78 };
79 exim = {
···82 config = builtins.readFile ./exim.conf;
83 };
84 };
85-}</programlisting>
86- </para>
87 <para>
88- The exim config needs some special additions to work with Mailman. Currently
89- NixOS can't manage Exim config with such granularity. Please refer to
90- <link xlink:href="https://mailman.readthedocs.io/en/latest/src/mailman/docs/mta.html">Mailman documentation</link>
91- for more info on configuring Mailman for working with Exim.
0092 </para>
93 </section>
94</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-mailman">
004 <title>Mailman</title>
5 <para>
6 <link xlink:href="https://www.list.org">Mailman</link> is free
7 software for managing electronic mail discussion and e-newsletter
8 lists. Mailman and its web interface can be configured using the
9 corresponding NixOS module. Note that this service is best used with
10+ an existing, securely configured Postfix setup, as it does not
11+ automatically configure this.
12 </para>
013 <section xml:id="module-services-mailman-basic-usage">
14 <title>Basic usage with Postfix</title>
15 <para>
16+ For a basic configuration with Postfix as the MTA, the following
17+ settings are suggested:
18+ </para>
19+ <programlisting>
20+{ config, ... }: {
21 services.postfix = {
22 enable = true;
23+ relayDomains = ["hash:/var/lib/mailman/data/postfix_domains"];
24+ sslCert = config.security.acme.certs."lists.example.org".directory + "/full.pem";
25+ sslKey = config.security.acme.certs."lists.example.org".directory + "/key.pem";
26 config = {
27+ transport_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"];
28+ local_recipient_maps = ["hash:/var/lib/mailman/data/postfix_lmtp"];
29 };
30 };
31 services.mailman = {
32+ enable = true;
33+ serve.enable = true;
34+ hyperkitty.enable = true;
35+ webHosts = ["lists.example.org"];
36+ siteOwner = "mailman@example.org";
37 };
38+ services.nginx.virtualHosts."lists.example.org".enableACME = true;
39+ networking.firewall.allowedTCPPorts = [ 25 80 443 ];
40+}
41+</programlisting>
42 <para>
43 DNS records will also be required:
000044 </para>
45+ <itemizedlist spacing="compact">
46+ <listitem>
47+ <para>
48+ <literal>AAAA</literal> and <literal>A</literal> records
49+ pointing to the host in question, in order for browsers to be
50+ able to discover the address of the web server;
51+ </para>
52+ </listitem>
53+ <listitem>
54+ <para>
55+ An <literal>MX</literal> record pointing to a domain name at
56+ which the host is reachable, in order for other mail servers
57+ to be able to deliver emails to the mailing lists it hosts.
58+ </para>
59+ </listitem>
60+ </itemizedlist>
61 <para>
62+ After this has been done and appropriate DNS records have been set
63+ up, the Postorius mailing list manager and the Hyperkitty archive
64+ browser will be available at https://lists.example.org/. Note that
65+ this setup is not sufficient to deliver emails to most email
66+ providers nor to avoid spam – a number of additional measures for
67+ authenticating incoming and outgoing mails, such as SPF, DMARC and
68+ DKIM are necessary, but outside the scope of the Mailman module.
069 </para>
70 </section>
71 <section xml:id="module-services-mailman-other-mtas">
72 <title>Using with other MTAs</title>
73 <para>
74+ Mailman also supports other MTA, though with a little bit more
75+ configuration. For example, to use Mailman with Exim, you can use
76+ the following settings:
77+ </para>
78+ <programlisting>
79+{ config, ... }: {
80 services = {
81 mailman = {
82 enable = true;
83+ siteOwner = "mailman@example.org";
84+ enablePostfix = false;
85 settings.mta = {
86+ incoming = "mailman.mta.exim4.LMTP";
87+ outgoing = "mailman.mta.deliver.deliver";
88+ lmtp_host = "localhost";
89+ lmtp_port = "8024";
90+ smtp_host = "localhost";
91+ smtp_port = "25";
92+ configuration = "python:mailman.config.exim4";
93 };
94 };
95 exim = {
···98 config = builtins.readFile ./exim.conf;
99 };
100 };
101+}
102+</programlisting>
103 <para>
104+ The exim config needs some special additions to work with Mailman.
105+ Currently NixOS can’t manage Exim config with such granularity.
106+ Please refer to
107+ <link xlink:href="https://mailman.readthedocs.io/en/latest/src/mailman/docs/mta.html">Mailman
108+ documentation</link> for more info on configuring Mailman for
109+ working with Exim.
110 </para>
111 </section>
112</chapter>
···1+# Mjolnir (Matrix Moderation Tool) {#module-services-mjolnir}
2+3+This chapter will show you how to set up your own, self-hosted
4+[Mjolnir](https://github.com/matrix-org/mjolnir) instance.
5+6+As an all-in-one moderation tool, it can protect your server from
7+malicious invites, spam messages, and whatever else you don't want.
8+In addition to server-level protection, Mjolnir is great for communities
9+wanting to protect their rooms without having to use their personal
10+accounts for moderation.
11+12+The bot by default includes support for bans, redactions, anti-spam,
13+server ACLs, room directory changes, room alias transfers, account
14+deactivation, room shutdown, and more.
15+16+See the [README](https://github.com/matrix-org/mjolnir#readme)
17+page and the [Moderator's guide](https://github.com/matrix-org/mjolnir/blob/main/docs/moderators.md)
18+for additional instructions on how to setup and use Mjolnir.
19+20+For [additional settings](#opt-services.mjolnir.settings)
21+see [the default configuration](https://github.com/matrix-org/mjolnir/blob/main/config/default.yaml).
22+23+## Mjolnir Setup {#module-services-mjolnir-setup}
24+25+First create a new Room which will be used as a management room for Mjolnir. In
26+this room, Mjolnir will log possible errors and debugging information. You'll
27+need to set this Room-ID in [services.mjolnir.managementRoom](#opt-services.mjolnir.managementRoom).
28+29+Next, create a new user for Mjolnir on your homeserver, if not present already.
30+31+The Mjolnir Matrix user expects to be free of any rate limiting.
32+See [Synapse #6286](https://github.com/matrix-org/synapse/issues/6286)
33+for an example on how to achieve this.
34+35+If you want Mjolnir to be able to deactivate users, move room aliases, shutdown rooms, etc.
36+you'll need to make the Mjolnir user a Matrix server admin.
37+38+Now invite the Mjolnir user to the management room.
39+40+It is recommended to use [Pantalaimon](https://github.com/matrix-org/pantalaimon),
41+so your management room can be encrypted. This also applies if you are looking to moderate an encrypted room.
42+43+To enable the Pantalaimon E2E Proxy for mjolnir, enable
44+[services.mjolnir.pantalaimon](#opt-services.mjolnir.pantalaimon.enable). This will
45+autoconfigure a new Pantalaimon instance, which will connect to the homeserver
46+set in [services.mjolnir.homeserverUrl](#opt-services.mjolnir.homeserverUrl) and Mjolnir itself
47+will be configured to connect to the new Pantalaimon instance.
48+49+```
50+{
51+ services.mjolnir = {
52+ enable = true;
53+ homeserverUrl = "https://matrix.domain.tld";
54+ pantalaimon = {
55+ enable = true;
56+ username = "mjolnir";
57+ passwordFile = "/run/secrets/mjolnir-password";
58+ };
59+ protectedRooms = [
60+ "https://matrix.to/#/!xxx:domain.tld"
61+ ];
62+ managementRoom = "!yyy:domain.tld";
63+ };
64+}
65+```
66+67+### Element Matrix Services (EMS) {#module-services-mjolnir-setup-ems}
68+69+If you are using a managed ["Element Matrix Services (EMS)"](https://ems.element.io/)
70+server, you will need to consent to the terms and conditions. Upon startup, an error
71+log entry with a URL to the consent page will be generated.
72+73+## Synapse Antispam Module {#module-services-mjolnir-matrix-synapse-antispam}
74+75+A Synapse module is also available to apply the same rulesets the bot
76+uses across an entire homeserver.
77+78+To use the Antispam Module, add `matrix-synapse-plugins.matrix-synapse-mjolnir-antispam`
79+to the Synapse plugin list and enable the `mjolnir.Module` module.
80+81+```
82+{
83+ services.matrix-synapse = {
84+ plugins = with pkgs; [
85+ matrix-synapse-plugins.matrix-synapse-mjolnir-antispam
86+ ];
87+ extraConfig = ''
88+ modules:
89+ - module: mjolnir.Module
90+ config:
91+ # Prevent servers/users in the ban lists from inviting users on this
92+ # server to rooms. Default true.
93+ block_invites: true
94+ # Flag messages sent by servers/users in the ban lists as spam. Currently
95+ # this means that spammy messages will appear as empty to users. Default
96+ # false.
97+ block_messages: false
98+ # Remove users from the user directory search by filtering matrix IDs and
99+ # display names by the entries in the user ban list. Default false.
100+ block_usernames: false
101+ # The room IDs of the ban lists to honour. Unlike other parts of Mjolnir,
102+ # this list cannot be room aliases or permalinks. This server is expected
103+ # to already be joined to the room - Mjolnir will not automatically join
104+ # these rooms.
105+ ban_lists:
106+ - "!roomid:example.org"
107+ '';
108+ };
109+}
110+```
+101-87
nixos/modules/services/matrix/mjolnir.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-mjolnir">
6- <title>Mjolnir (Matrix Moderation Tool)</title>
7- <para>
8- This chapter will show you how to set up your own, self-hosted
9- <link xlink:href="https://github.com/matrix-org/mjolnir">Mjolnir</link>
10- instance.
11- </para>
12- <para>
13- As an all-in-one moderation tool, it can protect your server from
14- malicious invites, spam messages, and whatever else you don't want.
15- In addition to server-level protection, Mjolnir is great for communities
16- wanting to protect their rooms without having to use their personal
17- accounts for moderation.
18- </para>
19- <para>
20- The bot by default includes support for bans, redactions, anti-spam,
21- server ACLs, room directory changes, room alias transfers, account
22- deactivation, room shutdown, and more.
23- </para>
24- <para>
25- See the <link xlink:href="https://github.com/matrix-org/mjolnir#readme">README</link>
26- page and the <link xlink:href="https://github.com/matrix-org/mjolnir/blob/main/docs/moderators.md">Moderator's guide</link>
27- for additional instructions on how to setup and use Mjolnir.
28- </para>
29- <para>
30- For <link linkend="opt-services.mjolnir.settings">additional settings</link>
31- see <link xlink:href="https://github.com/matrix-org/mjolnir/blob/main/config/default.yaml">the default configuration</link>.
32- </para>
33- <section xml:id="module-services-mjolnir-setup">
34- <title>Mjolnir Setup</title>
35 <para>
36- First create a new Room which will be used as a management room for Mjolnir. In
37- this room, Mjolnir will log possible errors and debugging information. You'll
38- need to set this Room-ID in <link linkend="opt-services.mjolnir.managementRoom">services.mjolnir.managementRoom</link>.
39- </para>
40- <para>
41- Next, create a new user for Mjolnir on your homeserver, if not present already.
42- </para>
43- <para>
44- The Mjolnir Matrix user expects to be free of any rate limiting.
45- See <link xlink:href="https://github.com/matrix-org/synapse/issues/6286">Synapse #6286</link>
46- for an example on how to achieve this.
47 </para>
48 <para>
49- If you want Mjolnir to be able to deactivate users, move room aliases, shutdown rooms, etc.
50- you'll need to make the Mjolnir user a Matrix server admin.
00051 </para>
52 <para>
53- Now invite the Mjolnir user to the management room.
0054 </para>
55 <para>
56- It is recommended to use <link xlink:href="https://github.com/matrix-org/pantalaimon">Pantalaimon</link>,
57- so your management room can be encrypted. This also applies if you are looking to moderate an encrypted room.
000058 </para>
59 <para>
60- To enable the Pantalaimon E2E Proxy for mjolnir, enable
61- <link linkend="opt-services.mjolnir.pantalaimon.enable">services.mjolnir.pantalaimon</link>. This will
62- autoconfigure a new Pantalaimon instance, which will connect to the homeserver
63- set in <link linkend="opt-services.mjolnir.homeserverUrl">services.mjolnir.homeserverUrl</link> and Mjolnir itself
64- will be configured to connect to the new Pantalaimon instance.
65 </para>
66-<programlisting>
0000000000000000000000000000000000000000067{
68 services.mjolnir = {
69 enable = true;
70- <link linkend="opt-services.mjolnir.homeserverUrl">homeserverUrl</link> = "https://matrix.domain.tld";
71- <link linkend="opt-services.mjolnir.pantalaimon">pantalaimon</link> = {
72- <link linkend="opt-services.mjolnir.pantalaimon.enable">enable</link> = true;
73- <link linkend="opt-services.mjolnir.pantalaimon.username">username</link> = "mjolnir";
74- <link linkend="opt-services.mjolnir.pantalaimon.passwordFile">passwordFile</link> = "/run/secrets/mjolnir-password";
75 };
76- <link linkend="opt-services.mjolnir.protectedRooms">protectedRooms</link> = [
77- "https://matrix.to/#/!xxx:domain.tld"
78 ];
79- <link linkend="opt-services.mjolnir.managementRoom">managementRoom</link> = "!yyy:domain.tld";
80 };
81}
82</programlisting>
83- <section xml:id="module-services-mjolnir-setup-ems">
84- <title>Element Matrix Services (EMS)</title>
85- <para>
86- If you are using a managed <link xlink:href="https://ems.element.io/">"Element Matrix Services (EMS)"</link>
87- server, you will need to consent to the terms and conditions. Upon startup, an error
88- log entry with a URL to the consent page will be generated.
89- </para>
90- </section>
91- </section>
92-93- <section xml:id="module-services-mjolnir-matrix-synapse-antispam">
94- <title>Synapse Antispam Module</title>
95- <para>
96- A Synapse module is also available to apply the same rulesets the bot
97- uses across an entire homeserver.
98- </para>
99- <para>
100- To use the Antispam Module, add <package>matrix-synapse-plugins.matrix-synapse-mjolnir-antispam</package>
101- to the Synapse plugin list and enable the <literal>mjolnir.Module</literal> module.
102- </para>
103-<programlisting>
000104{
105 services.matrix-synapse = {
106 plugins = with pkgs; [
···125 # to already be joined to the room - Mjolnir will not automatically join
126 # these rooms.
127 ban_lists:
128- - "!roomid:example.org"
129 '';
130 };
131}
132</programlisting>
133- </section>
134</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-mjolnir">
4+ <title>Mjolnir (Matrix Moderation Tool)</title>
0000000000000000000000000000005 <para>
6+ This chapter will show you how to set up your own, self-hosted
7+ <link xlink:href="https://github.com/matrix-org/mjolnir">Mjolnir</link>
8+ instance.
000000009 </para>
10 <para>
11+ As an all-in-one moderation tool, it can protect your server from
12+ malicious invites, spam messages, and whatever else you don’t want.
13+ In addition to server-level protection, Mjolnir is great for
14+ communities wanting to protect their rooms without having to use
15+ their personal accounts for moderation.
16 </para>
17 <para>
18+ The bot by default includes support for bans, redactions, anti-spam,
19+ server ACLs, room directory changes, room alias transfers, account
20+ deactivation, room shutdown, and more.
21 </para>
22 <para>
23+ See the
24+ <link xlink:href="https://github.com/matrix-org/mjolnir#readme">README</link>
25+ page and the
26+ <link xlink:href="https://github.com/matrix-org/mjolnir/blob/main/docs/moderators.md">Moderator’s
27+ guide</link> for additional instructions on how to setup and use
28+ Mjolnir.
29 </para>
30 <para>
31+ For <link linkend="opt-services.mjolnir.settings">additional
32+ settings</link> see
33+ <link xlink:href="https://github.com/matrix-org/mjolnir/blob/main/config/default.yaml">the
34+ default configuration</link>.
035 </para>
36+ <section xml:id="module-services-mjolnir-setup">
37+ <title>Mjolnir Setup</title>
38+ <para>
39+ First create a new Room which will be used as a management room
40+ for Mjolnir. In this room, Mjolnir will log possible errors and
41+ debugging information. You’ll need to set this Room-ID in
42+ <link linkend="opt-services.mjolnir.managementRoom">services.mjolnir.managementRoom</link>.
43+ </para>
44+ <para>
45+ Next, create a new user for Mjolnir on your homeserver, if not
46+ present already.
47+ </para>
48+ <para>
49+ The Mjolnir Matrix user expects to be free of any rate limiting.
50+ See
51+ <link xlink:href="https://github.com/matrix-org/synapse/issues/6286">Synapse
52+ #6286</link> for an example on how to achieve this.
53+ </para>
54+ <para>
55+ If you want Mjolnir to be able to deactivate users, move room
56+ aliases, shutdown rooms, etc. you’ll need to make the Mjolnir user
57+ a Matrix server admin.
58+ </para>
59+ <para>
60+ Now invite the Mjolnir user to the management room.
61+ </para>
62+ <para>
63+ It is recommended to use
64+ <link xlink:href="https://github.com/matrix-org/pantalaimon">Pantalaimon</link>,
65+ so your management room can be encrypted. This also applies if you
66+ are looking to moderate an encrypted room.
67+ </para>
68+ <para>
69+ To enable the Pantalaimon E2E Proxy for mjolnir, enable
70+ <link linkend="opt-services.mjolnir.pantalaimon.enable">services.mjolnir.pantalaimon</link>.
71+ This will autoconfigure a new Pantalaimon instance, which will
72+ connect to the homeserver set in
73+ <link linkend="opt-services.mjolnir.homeserverUrl">services.mjolnir.homeserverUrl</link>
74+ and Mjolnir itself will be configured to connect to the new
75+ Pantalaimon instance.
76+ </para>
77+ <programlisting>
78{
79 services.mjolnir = {
80 enable = true;
81+ homeserverUrl = "https://matrix.domain.tld";
82+ pantalaimon = {
83+ enable = true;
84+ username = "mjolnir";
85+ passwordFile = "/run/secrets/mjolnir-password";
86 };
87+ protectedRooms = [
88+ "https://matrix.to/#/!xxx:domain.tld"
89 ];
90+ managementRoom = "!yyy:domain.tld";
91 };
92}
93</programlisting>
94+ <section xml:id="module-services-mjolnir-setup-ems">
95+ <title>Element Matrix Services (EMS)</title>
96+ <para>
97+ If you are using a managed
98+ <link xlink:href="https://ems.element.io/"><quote>Element Matrix
99+ Services (EMS)</quote></link> server, you will need to consent
100+ to the terms and conditions. Upon startup, an error log entry
101+ with a URL to the consent page will be generated.
102+ </para>
103+ </section>
104+ </section>
105+ <section xml:id="module-services-mjolnir-matrix-synapse-antispam">
106+ <title>Synapse Antispam Module</title>
107+ <para>
108+ A Synapse module is also available to apply the same rulesets the
109+ bot uses across an entire homeserver.
110+ </para>
111+ <para>
112+ To use the Antispam Module, add
113+ <literal>matrix-synapse-plugins.matrix-synapse-mjolnir-antispam</literal>
114+ to the Synapse plugin list and enable the
115+ <literal>mjolnir.Module</literal> module.
116+ </para>
117+ <programlisting>
118{
119 services.matrix-synapse = {
120 plugins = with pkgs; [
···139 # to already be joined to the room - Mjolnir will not automatically join
140 # these rooms.
141 ban_lists:
142+ - "!roomid:example.org"
143 '';
144 };
145}
146</programlisting>
147+ </section>
148</chapter>
···1+# Matrix {#module-services-matrix}
2+3+[Matrix](https://matrix.org/) is an open standard for
4+interoperable, decentralised, real-time communication over IP. It can be used
5+to power Instant Messaging, VoIP/WebRTC signalling, Internet of Things
6+communication - or anywhere you need a standard HTTP API for publishing and
7+subscribing to data whilst tracking the conversation history.
8+9+This chapter will show you how to set up your own, self-hosted Matrix
10+homeserver using the Synapse reference homeserver, and how to serve your own
11+copy of the Element web client. See the
12+[Try Matrix Now!](https://matrix.org/docs/projects/try-matrix-now.html)
13+overview page for links to Element Apps for Android and iOS,
14+desktop clients, as well as bridges to other networks and other projects
15+around Matrix.
16+17+## Synapse Homeserver {#module-services-matrix-synapse}
18+19+[Synapse](https://github.com/matrix-org/synapse) is
20+the reference homeserver implementation of Matrix from the core development
21+team at matrix.org. The following configuration example will set up a
22+synapse server for the `example.org` domain, served from
23+the host `myhostname.example.org`. For more information,
24+please refer to the
25+[installation instructions of Synapse](https://matrix-org.github.io/synapse/latest/setup/installation.html) .
26+```
27+{ pkgs, lib, config, ... }:
28+let
29+ fqdn = "${config.networking.hostName}.${config.networking.domain}";
30+ clientConfig = {
31+ "m.homeserver".base_url = "https://${fqdn}";
32+ "m.identity_server" = {};
33+ };
34+ serverConfig."m.server" = "${config.services.matrix-synapse.settings.server_name}:443";
35+ mkWellKnown = data: ''
36+ add_header Content-Type application/json;
37+ add_header Access-Control-Allow-Origin *;
38+ return 200 '${builtins.toJSON data}';
39+ '';
40+in {
41+ networking.hostName = "myhostname";
42+ networking.domain = "example.org";
43+ networking.firewall.allowedTCPPorts = [ 80 443 ];
44+45+ services.postgresql.enable = true;
46+ services.postgresql.initialScript = pkgs.writeText "synapse-init.sql" ''
47+ CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse';
48+ CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
49+ TEMPLATE template0
50+ LC_COLLATE = "C"
51+ LC_CTYPE = "C";
52+ '';
53+54+ services.nginx = {
55+ enable = true;
56+ recommendedTlsSettings = true;
57+ recommendedOptimisation = true;
58+ recommendedGzipSettings = true;
59+ recommendedProxySettings = true;
60+ virtualHosts = {
61+ # If the A and AAAA DNS records on example.org do not point on the same host as the
62+ # records for myhostname.example.org, you can easily move the /.well-known
63+ # virtualHost section of the code to the host that is serving example.org, while
64+ # the rest stays on myhostname.example.org with no other changes required.
65+ # This pattern also allows to seamlessly move the homeserver from
66+ # myhostname.example.org to myotherhost.example.org by only changing the
67+ # /.well-known redirection target.
68+ "${config.networking.domain}" = {
69+ enableACME = true;
70+ forceSSL = true;
71+ # This section is not needed if the server_name of matrix-synapse is equal to
72+ # the domain (i.e. example.org from @foo:example.org) and the federation port
73+ # is 8448.
74+ # Further reference can be found in the docs about delegation under
75+ # https://matrix-org.github.io/synapse/latest/delegate.html
76+ locations."= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig;
77+ # This is usually needed for homeserver discovery (from e.g. other Matrix clients).
78+ # Further reference can be found in the upstream docs at
79+ # https://spec.matrix.org/latest/client-server-api/#getwell-knownmatrixclient
80+ locations."= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig;
81+ };
82+ "${fqdn}" = {
83+ enableACME = true;
84+ forceSSL = true;
85+ # It's also possible to do a redirect here or something else, this vhost is not
86+ # needed for Matrix. It's recommended though to *not put* element
87+ # here, see also the section about Element.
88+ locations."/".extraConfig = ''
89+ return 404;
90+ '';
91+ # Forward all Matrix API calls to the synapse Matrix homeserver. A trailing slash
92+ # *must not* be used here.
93+ locations."/_matrix".proxyPass = "http://[::1]:8008";
94+ # Forward requests for e.g. SSO and password-resets.
95+ locations."/_synapse/client".proxyPass = "http://[::1]:8008";
96+ };
97+ };
98+ };
99+100+ services.matrix-synapse = {
101+ enable = true;
102+ settings.server_name = config.networking.domain;
103+ settings.listeners = [
104+ { port = 8008;
105+ bind_addresses = [ "::1" ];
106+ type = "http";
107+ tls = false;
108+ x_forwarded = true;
109+ resources = [ {
110+ names = [ "client" "federation" ];
111+ compress = true;
112+ } ];
113+ }
114+ ];
115+ };
116+}
117+```
118+119+## Registering Matrix users {#module-services-matrix-register-users}
120+121+If you want to run a server with public registration by anybody, you can
122+then enable `services.matrix-synapse.settings.enable_registration = true;`.
123+Otherwise, or you can generate a registration secret with
124+{command}`pwgen -s 64 1` and set it with
125+[](#opt-services.matrix-synapse.settings.registration_shared_secret).
126+To create a new user or admin, run the following after you have set the secret
127+and have rebuilt NixOS:
128+```ShellSession
129+$ nix-shell -p matrix-synapse
130+$ register_new_matrix_user -k your-registration-shared-secret http://localhost:8008
131+New user localpart: your-username
132+Password:
133+Confirm password:
134+Make admin [no]:
135+Success!
136+```
137+In the example, this would create a user with the Matrix Identifier
138+`@your-username:example.org`.
139+140+::: {.warning}
141+When using [](#opt-services.matrix-synapse.settings.registration_shared_secret), the secret
142+will end up in the world-readable store. Instead it's recommended to deploy the secret
143+in an additional file like this:
144+145+ - Create a file with the following contents:
146+147+ ```
148+ registration_shared_secret: your-very-secret-secret
149+ ```
150+ - Deploy the file with a secret-manager such as
151+ [{option}`deployment.keys`](https://nixops.readthedocs.io/en/latest/overview.html#managing-keys)
152+ from {manpage}`nixops(1)` or [sops-nix](https://github.com/Mic92/sops-nix/) to
153+ e.g. {file}`/run/secrets/matrix-shared-secret` and ensure that it's readable
154+ by `matrix-synapse`.
155+ - Include the file like this in your configuration:
156+157+ ```
158+ {
159+ services.matrix-synapse.extraConfigFiles = [
160+ "/run/secrets/matrix-shared-secret"
161+ ];
162+ }
163+ ```
164+:::
165+166+::: {.note}
167+It's also possible to user alternative authentication mechanism such as
168+[LDAP (via `matrix-synapse-ldap3`)](https://github.com/matrix-org/matrix-synapse-ldap3)
169+or [OpenID](https://matrix-org.github.io/synapse/latest/openid.html).
170+:::
171+172+## Element (formerly known as Riot) Web Client {#module-services-matrix-element-web}
173+174+[Element Web](https://github.com/vector-im/riot-web/) is
175+the reference web client for Matrix and developed by the core team at
176+matrix.org. Element was formerly known as Riot.im, see the
177+[Element introductory blog post](https://element.io/blog/welcome-to-element/)
178+for more information. The following snippet can be optionally added to the code before
179+to complete the synapse installation with a web client served at
180+`https://element.myhostname.example.org` and
181+`https://element.example.org`. Alternatively, you can use the hosted
182+copy at <https://app.element.io/>,
183+or use other web clients or native client applications. Due to the
184+`/.well-known` urls set up done above, many clients should
185+fill in the required connection details automatically when you enter your
186+Matrix Identifier. See
187+[Try Matrix Now!](https://matrix.org/docs/projects/try-matrix-now.html)
188+for a list of existing clients and their supported featureset.
189+```
190+{
191+ services.nginx.virtualHosts."element.${fqdn}" = {
192+ enableACME = true;
193+ forceSSL = true;
194+ serverAliases = [
195+ "element.${config.networking.domain}"
196+ ];
197+198+ root = pkgs.element-web.override {
199+ conf = {
200+ default_server_config = clientConfig; # see `clientConfig` from the snippet above.
201+ };
202+ };
203+ };
204+}
205+```
206+207+::: {.note}
208+The Element developers do not recommend running Element and your Matrix
209+homeserver on the same fully-qualified domain name for security reasons. In
210+the example, this means that you should not reuse the
211+`myhostname.example.org` virtualHost to also serve Element,
212+but instead serve it on a different subdomain, like
213+`element.example.org` in the example. See the
214+[Element Important Security Notes](https://github.com/vector-im/element-web/tree/v1.10.0#important-security-notes)
215+for more information on this subject.
216+:::
+213-226
nixos/modules/services/matrix/synapse.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-matrix">
6- <title>Matrix</title>
7- <para>
8- <link xlink:href="https://matrix.org/">Matrix</link> is an open standard for
9- interoperable, decentralised, real-time communication over IP. It can be used
10- to power Instant Messaging, VoIP/WebRTC signalling, Internet of Things
11- communication - or anywhere you need a standard HTTP API for publishing and
12- subscribing to data whilst tracking the conversation history.
13- </para>
14- <para>
15- This chapter will show you how to set up your own, self-hosted Matrix
16- homeserver using the Synapse reference homeserver, and how to serve your own
17- copy of the Element web client. See the
18- <link xlink:href="https://matrix.org/docs/projects/try-matrix-now.html">Try
19- Matrix Now!</link> overview page for links to Element Apps for Android and iOS,
20- desktop clients, as well as bridges to other networks and other projects
21- around Matrix.
22- </para>
23- <section xml:id="module-services-matrix-synapse">
24- <title>Synapse Homeserver</title>
25-26 <para>
27- <link xlink:href="https://github.com/matrix-org/synapse">Synapse</link> is
28- the reference homeserver implementation of Matrix from the core development
29- team at matrix.org. The following configuration example will set up a
30- synapse server for the <literal>example.org</literal> domain, served from
31- the host <literal>myhostname.example.org</literal>. For more information,
32- please refer to the
33- <link xlink:href="https://matrix-org.github.io/synapse/latest/setup/installation.html">
34- installation instructions of Synapse </link>.
35-<programlisting>
000000000000036{ pkgs, lib, config, ... }:
37let
38- fqdn = "${config.networking.hostName}.${config.networking.domain}";
39 clientConfig = {
40- "m.homeserver".base_url = "https://${fqdn}";
41- "m.identity_server" = {};
42 };
43- serverConfig."m.server" = "${config.services.matrix-synapse.settings.server_name}:443";
44 mkWellKnown = data: ''
45 add_header Content-Type application/json;
46 add_header Access-Control-Allow-Origin *;
47 return 200 '${builtins.toJSON data}';
48 '';
49in {
50- <xref linkend="opt-networking.hostName" /> = "myhostname";
51- <xref linkend="opt-networking.domain" /> = "example.org";
52- <xref linkend="opt-networking.firewall.allowedTCPPorts" /> = [ 80 443 ];
5354- <xref linkend="opt-services.postgresql.enable" /> = true;
55- <xref linkend="opt-services.postgresql.initialScript" /> = pkgs.writeText "synapse-init.sql" ''
56- CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse';
57- CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
58 TEMPLATE template0
59- LC_COLLATE = "C"
60- LC_CTYPE = "C";
61 '';
6263 services.nginx = {
64- <link linkend="opt-services.nginx.enable">enable</link> = true;
65- <link linkend="opt-services.nginx.recommendedTlsSettings">recommendedTlsSettings</link> = true;
66- <link linkend="opt-services.nginx.recommendedOptimisation">recommendedOptimisation</link> = true;
67- <link linkend="opt-services.nginx.recommendedGzipSettings">recommendedGzipSettings</link> = true;
68- <link linkend="opt-services.nginx.recommendedProxySettings">recommendedProxySettings</link> = true;
69- <link linkend="opt-services.nginx.virtualHosts">virtualHosts</link> = {
70- "${config.networking.domain}" = { <co xml:id='ex-matrix-synapse-dns' />
71- <link linkend="opt-services.nginx.virtualHosts._name_.enableACME">enableACME</link> = true;
72- <link linkend="opt-services.nginx.virtualHosts._name_.forceSSL">forceSSL</link> = true;
73- <link linkend="opt-services.nginx.virtualHosts._name_.locations._name_.extraConfig">locations."= /.well-known/matrix/server".extraConfig</link> = mkWellKnown serverConfig; <co xml:id='ex-matrix-synapse-well-known-server' />
74- <link linkend="opt-services.nginx.virtualHosts._name_.locations._name_.extraConfig">locations."= /.well-known/matrix/client".extraConfig</link> = mkWellKnown clientConfig; <co xml:id='ex-matrix-synapse-well-known-client' />
00000000000000075 };
76- "${fqdn}" = {
77- <link linkend="opt-services.nginx.virtualHosts._name_.enableACME">enableACME</link> = true;
78- <link linkend="opt-services.nginx.virtualHosts._name_.forceSSL">forceSSL</link> = true;
79- <link linkend="opt-services.nginx.virtualHosts._name_.locations._name_.extraConfig">locations."/".extraConfig</link> = '' <co xml:id='ex-matrix-synapse-rev-default' />
00080 return 404;
81 '';
82- <link linkend="opt-services.nginx.virtualHosts._name_.locations._name_.proxyPass">locations."/_matrix".proxyPass</link> = "http://[::1]:8008"; <co xml:id='ex-matrix-synapse-rev-proxy-pass' />
83- <link linkend="opt-services.nginx.virtualHosts._name_.locations._name_.proxyPass">locations."/_synapse/client".proxyPass</link> = "http://[::1]:8008"; <co xml:id='ex-matrix-synapse-rev-client' />
00084 };
85 };
86 };
8788 services.matrix-synapse = {
89- <link linkend="opt-services.matrix-synapse.enable">enable</link> = true;
90- <link linkend="opt-services.matrix-synapse.settings.server_name">settings.server_name</link> = config.networking.domain;
91- <link linkend="opt-services.matrix-synapse.settings.listeners">settings.listeners</link> = [
92- { <link linkend="opt-services.matrix-synapse.settings.listeners._.port">port</link> = 8008;
93- <link linkend="opt-services.matrix-synapse.settings.listeners._.bind_addresses">bind_addresses</link> = [ "::1" ];
94- <link linkend="opt-services.matrix-synapse.settings.listeners._.type">type</link> = "http";
95- <link linkend="opt-services.matrix-synapse.settings.listeners._.tls">tls</link> = false;
96- <link linkend="opt-services.matrix-synapse.settings.listeners._.x_forwarded">x_forwarded</link> = true;
97- <link linkend="opt-services.matrix-synapse.settings.listeners._.resources">resources</link> = [ {
98- <link linkend="opt-services.matrix-synapse.settings.listeners._.resources._.names">names</link> = [ "client" "federation" ];
99- <link linkend="opt-services.matrix-synapse.settings.listeners._.resources._.compress">compress</link> = true;
100 } ];
101 }
102 ];
103 };
104}
105</programlisting>
106- </para>
107- <calloutlist>
108- <callout arearefs='ex-matrix-synapse-dns'>
109 <para>
110- If the <code>A</code> and <code>AAAA</code> DNS records on
111- <literal>example.org</literal> do not point on the same host as the records
112- for <code>myhostname.example.org</code>, you can easily move the
113- <code>/.well-known</code> virtualHost section of the code to the host that
114- is serving <literal>example.org</literal>, while the rest stays on
115- <literal>myhostname.example.org</literal> with no other changes required.
116- This pattern also allows to seamlessly move the homeserver from
117- <literal>myhostname.example.org</literal> to
118- <literal>myotherhost.example.org</literal> by only changing the
119- <code>/.well-known</code> redirection target.
120 </para>
121- </callout>
122- <callout arearefs='ex-matrix-synapse-well-known-server'>
0000000123 <para>
124- This section is not needed if the <link linkend="opt-services.matrix-synapse.settings.server_name">server_name</link>
125- of <package>matrix-synapse</package> is equal to the domain (i.e.
126- <literal>example.org</literal> from <literal>@foo:example.org</literal>)
127- and the federation port is 8448.
128- Further reference can be found in the <link xlink:href="https://matrix-org.github.io/synapse/latest/delegate.html">docs
129- about delegation</link>.
130 </para>
131- </callout>
132- <callout arearefs='ex-matrix-synapse-well-known-client'>
133- <para>
134- This is usually needed for homeserver discovery (from e.g. other Matrix clients).
135- Further reference can be found in the <link xlink:href="https://spec.matrix.org/latest/client-server-api/#getwell-knownmatrixclient">upstream docs</link>
136- </para>
137- </callout>
138- <callout arearefs='ex-matrix-synapse-rev-default'>
139- <para>
140- It's also possible to do a redirect here or something else, this vhost is not
141- needed for Matrix. It's recommended though to <emphasis>not put</emphasis> element
142- here, see also the <link linkend='ex-matrix-synapse-rev-default'>section about Element</link>.
143- </para>
144- </callout>
145- <callout arearefs='ex-matrix-synapse-rev-proxy-pass'>
146- <para>
147- Forward all Matrix API calls to the synapse Matrix homeserver. A trailing slash
148- <emphasis>must not</emphasis> be used here.
149- </para>
150- </callout>
151- <callout arearefs='ex-matrix-synapse-rev-client'>
152- <para>
153- Forward requests for e.g. SSO and password-resets.
154- </para>
155- </callout>
156- </calloutlist>
157- </section>
158- <section xml:id="module-services-matrix-register-users">
159- <title>Registering Matrix users</title>
160- <para>
161- If you want to run a server with public registration by anybody, you can
162- then enable <literal><link linkend="opt-services.matrix-synapse.settings.enable_registration">services.matrix-synapse.settings.enable_registration</link> =
163- true;</literal>. Otherwise, or you can generate a registration secret with
164- <command>pwgen -s 64 1</command> and set it with
165- <option><link linkend="opt-services.matrix-synapse.settings.registration_shared_secret">services.matrix-synapse.settings.registration_shared_secret</link></option>.
166- To create a new user or admin, run the following after you have set the secret
167- and have rebuilt NixOS:
168-<screen>
169-<prompt>$ </prompt>nix-shell -p matrix-synapse
170-<prompt>$ </prompt>register_new_matrix_user -k <replaceable>your-registration-shared-secret</replaceable> http://localhost:8008
171-<prompt>New user localpart: </prompt><replaceable>your-username</replaceable>
172-<prompt>Password:</prompt>
173-<prompt>Confirm password:</prompt>
174-<prompt>Make admin [no]:</prompt>
175-Success!
176-</screen>
177- In the example, this would create a user with the Matrix Identifier
178- <literal>@your-username:example.org</literal>.
179- <warning>
180- <para>
181- When using <xref linkend="opt-services.matrix-synapse.settings.registration_shared_secret" />, the secret
182- will end up in the world-readable store. Instead it's recommended to deploy the secret
183- in an additional file like this:
184- <itemizedlist>
185- <listitem>
186- <para>
187- Create a file with the following contents:
188-<programlisting>registration_shared_secret: your-very-secret-secret</programlisting>
189- </para>
190- </listitem>
191- <listitem>
192- <para>
193- Deploy the file with a secret-manager such as <link xlink:href="https://nixops.readthedocs.io/en/latest/overview.html#managing-keys"><option>deployment.keys</option></link>
194- from <citerefentry><refentrytitle>nixops</refentrytitle><manvolnum>1</manvolnum></citerefentry>
195- or <link xlink:href="https://github.com/Mic92/sops-nix/">sops-nix</link> to
196- e.g. <filename>/run/secrets/matrix-shared-secret</filename> and ensure that it's readable
197- by <package>matrix-synapse</package>.
198- </para>
199- </listitem>
200- <listitem>
201- <para>
202- Include the file like this in your configuration:
203-<programlisting>
204{
205- <xref linkend="opt-services.matrix-synapse.extraConfigFiles" /> = [
206- "/run/secrets/matrix-shared-secret"
207 ];
208}
209</programlisting>
210- </para>
211- </listitem>
212- </itemizedlist>
00000000000000000000000000000000213 </para>
214- </warning>
215- </para>
216- <note>
217- <para>
218- It's also possible to user alternative authentication mechanism such as
219- <link xlink:href="https://github.com/matrix-org/matrix-synapse-ldap3">LDAP (via <literal>matrix-synapse-ldap3</literal>)</link>
220- or <link xlink:href="https://matrix-org.github.io/synapse/latest/openid.html">OpenID</link>.
221- </para>
222- </note>
223- </section>
224- <section xml:id="module-services-matrix-element-web">
225- <title>Element (formerly known as Riot) Web Client</title>
226-227- <para>
228- <link xlink:href="https://github.com/vector-im/riot-web/">Element Web</link> is
229- the reference web client for Matrix and developed by the core team at
230- matrix.org. Element was formerly known as Riot.im, see the
231- <link xlink:href="https://element.io/blog/welcome-to-element/">Element introductory blog post</link>
232- for more information. The following snippet can be optionally added to the code before
233- to complete the synapse installation with a web client served at
234- <code>https://element.myhostname.example.org</code> and
235- <code>https://element.example.org</code>. Alternatively, you can use the hosted
236- copy at <link xlink:href="https://app.element.io/">https://app.element.io/</link>,
237- or use other web clients or native client applications. Due to the
238- <literal>/.well-known</literal> urls set up done above, many clients should
239- fill in the required connection details automatically when you enter your
240- Matrix Identifier. See
241- <link xlink:href="https://matrix.org/docs/projects/try-matrix-now.html">Try
242- Matrix Now!</link> for a list of existing clients and their supported
243- featureset.
244-<programlisting>
245{
246- services.nginx.virtualHosts."element.${fqdn}" = {
247- <link linkend="opt-services.nginx.virtualHosts._name_.enableACME">enableACME</link> = true;
248- <link linkend="opt-services.nginx.virtualHosts._name_.forceSSL">forceSSL</link> = true;
249- <link linkend="opt-services.nginx.virtualHosts._name_.serverAliases">serverAliases</link> = [
250- "element.${config.networking.domain}"
251 ];
252253- <link linkend="opt-services.nginx.virtualHosts._name_.root">root</link> = pkgs.element-web.override {
254 conf = {
255 default_server_config = clientConfig; # see `clientConfig` from the snippet above.
256 };
···258 };
259}
260</programlisting>
261- </para>
262-263- <note>
264- <para>
265- The Element developers do not recommend running Element and your Matrix
266- homeserver on the same fully-qualified domain name for security reasons. In
267- the example, this means that you should not reuse the
268- <literal>myhostname.example.org</literal> virtualHost to also serve Element,
269- but instead serve it on a different subdomain, like
270- <literal>element.example.org</literal> in the example. See the
271- <link xlink:href="https://github.com/vector-im/element-web/tree/v1.10.0#important-security-notes">Element
272- Important Security Notes</link> for more information on this subject.
273- </para>
274- </note>
275- </section>
276</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-matrix">
4+ <title>Matrix</title>
5+ <para>
6+ <link xlink:href="https://matrix.org/">Matrix</link> is an open
7+ standard for interoperable, decentralised, real-time communication
8+ over IP. It can be used to power Instant Messaging, VoIP/WebRTC
9+ signalling, Internet of Things communication - or anywhere you need
10+ a standard HTTP API for publishing and subscribing to data whilst
11+ tracking the conversation history.
12+ </para>
000000000000013 <para>
14+ This chapter will show you how to set up your own, self-hosted
15+ Matrix homeserver using the Synapse reference homeserver, and how to
16+ serve your own copy of the Element web client. See the
17+ <link xlink:href="https://matrix.org/docs/projects/try-matrix-now.html">Try
18+ Matrix Now!</link> overview page for links to Element Apps for
19+ Android and iOS, desktop clients, as well as bridges to other
20+ networks and other projects around Matrix.
21+ </para>
22+ <section xml:id="module-services-matrix-synapse">
23+ <title>Synapse Homeserver</title>
24+ <para>
25+ <link xlink:href="https://github.com/matrix-org/synapse">Synapse</link>
26+ is the reference homeserver implementation of Matrix from the core
27+ development team at matrix.org. The following configuration
28+ example will set up a synapse server for the
29+ <literal>example.org</literal> domain, served from the host
30+ <literal>myhostname.example.org</literal>. For more information,
31+ please refer to the
32+ <link xlink:href="https://matrix-org.github.io/synapse/latest/setup/installation.html">installation
33+ instructions of Synapse</link> .
34+ </para>
35+ <programlisting>
36{ pkgs, lib, config, ... }:
37let
38+ fqdn = "${config.networking.hostName}.${config.networking.domain}";
39 clientConfig = {
40+ "m.homeserver".base_url = "https://${fqdn}";
41+ "m.identity_server" = {};
42 };
43+ serverConfig."m.server" = "${config.services.matrix-synapse.settings.server_name}:443";
44 mkWellKnown = data: ''
45 add_header Content-Type application/json;
46 add_header Access-Control-Allow-Origin *;
47 return 200 '${builtins.toJSON data}';
48 '';
49in {
50+ networking.hostName = "myhostname";
51+ networking.domain = "example.org";
52+ networking.firewall.allowedTCPPorts = [ 80 443 ];
5354+ services.postgresql.enable = true;
55+ services.postgresql.initialScript = pkgs.writeText "synapse-init.sql" ''
56+ CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse';
57+ CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
58 TEMPLATE template0
59+ LC_COLLATE = "C"
60+ LC_CTYPE = "C";
61 '';
6263 services.nginx = {
64+ enable = true;
65+ recommendedTlsSettings = true;
66+ recommendedOptimisation = true;
67+ recommendedGzipSettings = true;
68+ recommendedProxySettings = true;
69+ virtualHosts = {
70+ # If the A and AAAA DNS records on example.org do not point on the same host as the
71+ # records for myhostname.example.org, you can easily move the /.well-known
72+ # virtualHost section of the code to the host that is serving example.org, while
73+ # the rest stays on myhostname.example.org with no other changes required.
74+ # This pattern also allows to seamlessly move the homeserver from
75+ # myhostname.example.org to myotherhost.example.org by only changing the
76+ # /.well-known redirection target.
77+ "${config.networking.domain}" = {
78+ enableACME = true;
79+ forceSSL = true;
80+ # This section is not needed if the server_name of matrix-synapse is equal to
81+ # the domain (i.e. example.org from @foo:example.org) and the federation port
82+ # is 8448.
83+ # Further reference can be found in the docs about delegation under
84+ # https://matrix-org.github.io/synapse/latest/delegate.html
85+ locations."= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig;
86+ # This is usually needed for homeserver discovery (from e.g. other Matrix clients).
87+ # Further reference can be found in the upstream docs at
88+ # https://spec.matrix.org/latest/client-server-api/#getwell-knownmatrixclient
89+ locations."= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig;
90 };
91+ "${fqdn}" = {
92+ enableACME = true;
93+ forceSSL = true;
94+ # It's also possible to do a redirect here or something else, this vhost is not
95+ # needed for Matrix. It's recommended though to *not put* element
96+ # here, see also the section about Element.
97+ locations."/".extraConfig = ''
98 return 404;
99 '';
100+ # Forward all Matrix API calls to the synapse Matrix homeserver. A trailing slash
101+ # *must not* be used here.
102+ locations."/_matrix".proxyPass = "http://[::1]:8008";
103+ # Forward requests for e.g. SSO and password-resets.
104+ locations."/_synapse/client".proxyPass = "http://[::1]:8008";
105 };
106 };
107 };
108109 services.matrix-synapse = {
110+ enable = true;
111+ settings.server_name = config.networking.domain;
112+ settings.listeners = [
113+ { port = 8008;
114+ bind_addresses = [ "::1" ];
115+ type = "http";
116+ tls = false;
117+ x_forwarded = true;
118+ resources = [ {
119+ names = [ "client" "federation" ];
120+ compress = true;
121 } ];
122 }
123 ];
124 };
125}
126</programlisting>
127+ </section>
128+ <section xml:id="module-services-matrix-register-users">
129+ <title>Registering Matrix users</title>
130 <para>
131+ If you want to run a server with public registration by anybody,
132+ you can then enable
133+ <literal>services.matrix-synapse.settings.enable_registration = true;</literal>.
134+ Otherwise, or you can generate a registration secret with
135+ <command>pwgen -s 64 1</command> and set it with
136+ <xref linkend="opt-services.matrix-synapse.settings.registration_shared_secret" />.
137+ To create a new user or admin, run the following after you have
138+ set the secret and have rebuilt NixOS:
00139 </para>
140+ <programlisting>
141+$ nix-shell -p matrix-synapse
142+$ register_new_matrix_user -k your-registration-shared-secret http://localhost:8008
143+New user localpart: your-username
144+Password:
145+Confirm password:
146+Make admin [no]:
147+Success!
148+</programlisting>
149 <para>
150+ In the example, this would create a user with the Matrix
151+ Identifier <literal>@your-username:example.org</literal>.
0000152 </para>
153+ <warning>
154+ <para>
155+ When using
156+ <xref linkend="opt-services.matrix-synapse.settings.registration_shared_secret" />,
157+ the secret will end up in the world-readable store. Instead it’s
158+ recommended to deploy the secret in an additional file like
159+ this:
160+ </para>
161+ <itemizedlist>
162+ <listitem>
163+ <para>
164+ Create a file with the following contents:
165+ </para>
166+ <programlisting>
167+registration_shared_secret: your-very-secret-secret
168+</programlisting>
169+ </listitem>
170+ <listitem>
171+ <para>
172+ Deploy the file with a secret-manager such as
173+ <link xlink:href="https://nixops.readthedocs.io/en/latest/overview.html#managing-keys"><option>deployment.keys</option></link>
174+ from
175+ <citerefentry><refentrytitle>nixops</refentrytitle><manvolnum>1</manvolnum></citerefentry>
176+ or
177+ <link xlink:href="https://github.com/Mic92/sops-nix/">sops-nix</link>
178+ to e.g.
179+ <filename>/run/secrets/matrix-shared-secret</filename> and
180+ ensure that it’s readable by
181+ <literal>matrix-synapse</literal>.
182+ </para>
183+ </listitem>
184+ <listitem>
185+ <para>
186+ Include the file like this in your configuration:
187+ </para>
188+ <programlisting>
0000000000000000000000000000000000000189{
190+ services.matrix-synapse.extraConfigFiles = [
191+ "/run/secrets/matrix-shared-secret"
192 ];
193}
194</programlisting>
195+ </listitem>
196+ </itemizedlist>
197+ </warning>
198+ <note>
199+ <para>
200+ It’s also possible to user alternative authentication mechanism
201+ such as
202+ <link xlink:href="https://github.com/matrix-org/matrix-synapse-ldap3">LDAP
203+ (via <literal>matrix-synapse-ldap3</literal>)</link> or
204+ <link xlink:href="https://matrix-org.github.io/synapse/latest/openid.html">OpenID</link>.
205+ </para>
206+ </note>
207+ </section>
208+ <section xml:id="module-services-matrix-element-web">
209+ <title>Element (formerly known as Riot) Web Client</title>
210+ <para>
211+ <link xlink:href="https://github.com/vector-im/riot-web/">Element
212+ Web</link> is the reference web client for Matrix and developed by
213+ the core team at matrix.org. Element was formerly known as
214+ Riot.im, see the
215+ <link xlink:href="https://element.io/blog/welcome-to-element/">Element
216+ introductory blog post</link> for more information. The following
217+ snippet can be optionally added to the code before to complete the
218+ synapse installation with a web client served at
219+ <literal>https://element.myhostname.example.org</literal> and
220+ <literal>https://element.example.org</literal>. Alternatively, you
221+ can use the hosted copy at
222+ <link xlink:href="https://app.element.io/">https://app.element.io/</link>,
223+ or use other web clients or native client applications. Due to the
224+ <literal>/.well-known</literal> urls set up done above, many
225+ clients should fill in the required connection details
226+ automatically when you enter your Matrix Identifier. See
227+ <link xlink:href="https://matrix.org/docs/projects/try-matrix-now.html">Try
228+ Matrix Now!</link> for a list of existing clients and their
229+ supported featureset.
230 </para>
231+ <programlisting>
000000000000000000000000000000232{
233+ services.nginx.virtualHosts."element.${fqdn}" = {
234+ enableACME = true;
235+ forceSSL = true;
236+ serverAliases = [
237+ "element.${config.networking.domain}"
238 ];
239240+ root = pkgs.element-web.override {
241 conf = {
242 default_server_config = clientConfig; # see `clientConfig` from the snippet above.
243 };
···245 };
246}
247</programlisting>
248+ <note>
249+ <para>
250+ The Element developers do not recommend running Element and your
251+ Matrix homeserver on the same fully-qualified domain name for
252+ security reasons. In the example, this means that you should not
253+ reuse the <literal>myhostname.example.org</literal> virtualHost
254+ to also serve Element, but instead serve it on a different
255+ subdomain, like <literal>element.example.org</literal> in the
256+ example. See the
257+ <link xlink:href="https://github.com/vector-im/element-web/tree/v1.10.0#important-security-notes">Element
258+ Important Security Notes</link> for more information on this
259+ subject.
260+ </para>
261+ </note>
262+ </section>
263</chapter>
···1+# GitLab {#module-services-gitlab}
2+3+GitLab is a feature-rich git hosting service.
4+5+## Prerequisites {#module-services-gitlab-prerequisites}
6+7+The `gitlab` service exposes only an Unix socket at
8+`/run/gitlab/gitlab-workhorse.socket`. You need to
9+configure a webserver to proxy HTTP requests to the socket.
10+11+For instance, the following configuration could be used to use nginx as
12+frontend proxy:
13+```
14+services.nginx = {
15+ enable = true;
16+ recommendedGzipSettings = true;
17+ recommendedOptimisation = true;
18+ recommendedProxySettings = true;
19+ recommendedTlsSettings = true;
20+ virtualHosts."git.example.com" = {
21+ enableACME = true;
22+ forceSSL = true;
23+ locations."/".proxyPass = "http://unix:/run/gitlab/gitlab-workhorse.socket";
24+ };
25+};
26+```
27+28+## Configuring {#module-services-gitlab-configuring}
29+30+GitLab depends on both PostgreSQL and Redis and will automatically enable
31+both services. In the case of PostgreSQL, a database and a role will be
32+created.
33+34+The default state dir is `/var/gitlab/state`. This is where
35+all data like the repositories and uploads will be stored.
36+37+A basic configuration with some custom settings could look like this:
38+```
39+services.gitlab = {
40+ enable = true;
41+ databasePasswordFile = "/var/keys/gitlab/db_password";
42+ initialRootPasswordFile = "/var/keys/gitlab/root_password";
43+ https = true;
44+ host = "git.example.com";
45+ port = 443;
46+ user = "git";
47+ group = "git";
48+ smtp = {
49+ enable = true;
50+ address = "localhost";
51+ port = 25;
52+ };
53+ secrets = {
54+ dbFile = "/var/keys/gitlab/db";
55+ secretFile = "/var/keys/gitlab/secret";
56+ otpFile = "/var/keys/gitlab/otp";
57+ jwsFile = "/var/keys/gitlab/jws";
58+ };
59+ extraConfig = {
60+ gitlab = {
61+ email_from = "gitlab-no-reply@example.com";
62+ email_display_name = "Example GitLab";
63+ email_reply_to = "gitlab-no-reply@example.com";
64+ default_projects_features = { builds = false; };
65+ };
66+ };
67+};
68+```
69+70+If you're setting up a new GitLab instance, generate new
71+secrets. You for instance use
72+`tr -dc A-Za-z0-9 < /dev/urandom | head -c 128 > /var/keys/gitlab/db` to
73+generate a new db secret. Make sure the files can be read by, and
74+only by, the user specified by
75+[services.gitlab.user](#opt-services.gitlab.user). GitLab
76+encrypts sensitive data stored in the database. If you're restoring
77+an existing GitLab instance, you must specify the secrets secret
78+from `config/secrets.yml` located in your GitLab
79+state folder.
80+81+When `incoming_mail.enabled` is set to `true`
82+in [extraConfig](#opt-services.gitlab.extraConfig) an additional
83+service called `gitlab-mailroom` is enabled for fetching incoming mail.
84+85+Refer to [](#ch-options) for all available configuration
86+options for the [services.gitlab](#opt-services.gitlab.enable) module.
87+88+## Maintenance {#module-services-gitlab-maintenance}
89+90+### Backups {#module-services-gitlab-maintenance-backups}
91+92+Backups can be configured with the options in
93+[services.gitlab.backup](#opt-services.gitlab.backup.keepTime). Use
94+the [services.gitlab.backup.startAt](#opt-services.gitlab.backup.startAt)
95+option to configure regular backups.
96+97+To run a manual backup, start the `gitlab-backup` service:
98+```ShellSession
99+$ systemctl start gitlab-backup.service
100+```
101+102+### Rake tasks {#module-services-gitlab-maintenance-rake}
103+104+You can run GitLab's rake tasks with `gitlab-rake`
105+which will be available on the system when GitLab is enabled. You
106+will have to run the command as the user that you configured to run
107+GitLab with.
108+109+A list of all available rake tasks can be obtained by running:
110+```ShellSession
111+$ sudo -u git -H gitlab-rake -T
112+```
+124-132
nixos/modules/services/misc/gitlab.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-gitlab">
6- <title>GitLab</title>
7- <para>
8- GitLab is a feature-rich git hosting service.
9- </para>
10- <section xml:id="module-services-gitlab-prerequisites">
11- <title>Prerequisites</title>
12-13 <para>
14- The <literal>gitlab</literal> service exposes only an Unix socket at
15- <literal>/run/gitlab/gitlab-workhorse.socket</literal>. You need to
16- configure a webserver to proxy HTTP requests to the socket.
17 </para>
18-19- <para>
20- For instance, the following configuration could be used to use nginx as
21- frontend proxy:
22-<programlisting>
23-<link linkend="opt-services.nginx.enable">services.nginx</link> = {
24- <link linkend="opt-services.nginx.enable">enable</link> = true;
25- <link linkend="opt-services.nginx.recommendedGzipSettings">recommendedGzipSettings</link> = true;
26- <link linkend="opt-services.nginx.recommendedOptimisation">recommendedOptimisation</link> = true;
27- <link linkend="opt-services.nginx.recommendedProxySettings">recommendedProxySettings</link> = true;
28- <link linkend="opt-services.nginx.recommendedTlsSettings">recommendedTlsSettings</link> = true;
29- <link linkend="opt-services.nginx.virtualHosts">virtualHosts</link>."git.example.com" = {
30- <link linkend="opt-services.nginx.virtualHosts._name_.enableACME">enableACME</link> = true;
31- <link linkend="opt-services.nginx.virtualHosts._name_.forceSSL">forceSSL</link> = true;
32- <link linkend="opt-services.nginx.virtualHosts._name_.locations._name_.proxyPass">locations."/".proxyPass</link> = "http://unix:/run/gitlab/gitlab-workhorse.socket";
0000000033 };
34};
35</programlisting>
36- </para>
37- </section>
38- <section xml:id="module-services-gitlab-configuring">
39- <title>Configuring</title>
40-41- <para>
42- GitLab depends on both PostgreSQL and Redis and will automatically enable
43- both services. In the case of PostgreSQL, a database and a role will be
44- created.
45- </para>
46-47- <para>
48- The default state dir is <literal>/var/gitlab/state</literal>. This is where
49- all data like the repositories and uploads will be stored.
50- </para>
51-52- <para>
53- A basic configuration with some custom settings could look like this:
54-<programlisting>
55services.gitlab = {
56- <link linkend="opt-services.gitlab.enable">enable</link> = true;
57- <link linkend="opt-services.gitlab.databasePasswordFile">databasePasswordFile</link> = "/var/keys/gitlab/db_password";
58- <link linkend="opt-services.gitlab.initialRootPasswordFile">initialRootPasswordFile</link> = "/var/keys/gitlab/root_password";
59- <link linkend="opt-services.gitlab.https">https</link> = true;
60- <link linkend="opt-services.gitlab.host">host</link> = "git.example.com";
61- <link linkend="opt-services.gitlab.port">port</link> = 443;
62- <link linkend="opt-services.gitlab.user">user</link> = "git";
63- <link linkend="opt-services.gitlab.group">group</link> = "git";
64 smtp = {
65- <link linkend="opt-services.gitlab.smtp.enable">enable</link> = true;
66- <link linkend="opt-services.gitlab.smtp.address">address</link> = "localhost";
67- <link linkend="opt-services.gitlab.smtp.port">port</link> = 25;
68 };
69 secrets = {
70- <link linkend="opt-services.gitlab.secrets.dbFile">dbFile</link> = "/var/keys/gitlab/db";
71- <link linkend="opt-services.gitlab.secrets.secretFile">secretFile</link> = "/var/keys/gitlab/secret";
72- <link linkend="opt-services.gitlab.secrets.otpFile">otpFile</link> = "/var/keys/gitlab/otp";
73- <link linkend="opt-services.gitlab.secrets.jwsFile">jwsFile</link> = "/var/keys/gitlab/jws";
74 };
75- <link linkend="opt-services.gitlab.extraConfig">extraConfig</link> = {
76 gitlab = {
77- email_from = "gitlab-no-reply@example.com";
78- email_display_name = "Example GitLab";
79- email_reply_to = "gitlab-no-reply@example.com";
80 default_projects_features = { builds = false; };
81 };
82 };
83};
84</programlisting>
85- </para>
86-87- <para>
88- If you're setting up a new GitLab instance, generate new
89- secrets. You for instance use <literal>tr -dc A-Za-z0-9 <
90- /dev/urandom | head -c 128 > /var/keys/gitlab/db</literal> to
91- generate a new db secret. Make sure the files can be read by, and
92- only by, the user specified by <link
93- linkend="opt-services.gitlab.user">services.gitlab.user</link>. GitLab
94- encrypts sensitive data stored in the database. If you're restoring
95- an existing GitLab instance, you must specify the secrets secret
96- from <literal>config/secrets.yml</literal> located in your GitLab
97- state folder.
98- </para>
99-100- <para>
101- When <literal>incoming_mail.enabled</literal> is set to <literal>true</literal>
102- in <link linkend="opt-services.gitlab.extraConfig">extraConfig</link> an additional
103- service called <literal>gitlab-mailroom</literal> is enabled for fetching incoming mail.
104- </para>
105-106- <para>
107- Refer to <xref linkend="ch-options" /> for all available configuration
108- options for the
109- <link linkend="opt-services.gitlab.enable">services.gitlab</link> module.
110- </para>
111- </section>
112- <section xml:id="module-services-gitlab-maintenance">
113- <title>Maintenance</title>
114-115- <section xml:id="module-services-gitlab-maintenance-backups">
116- <title>Backups</title>
117- <para>
118- Backups can be configured with the options in <link
119- linkend="opt-services.gitlab.backup.keepTime">services.gitlab.backup</link>. Use
120- the <link
121- linkend="opt-services.gitlab.backup.startAt">services.gitlab.backup.startAt</link>
122- option to configure regular backups.
123- </para>
124-125- <para>
126- To run a manual backup, start the <literal>gitlab-backup</literal> service:
127-<screen>
128-<prompt>$ </prompt>systemctl start gitlab-backup.service
129-</screen>
130- </para>
131 </section>
132-133- <section xml:id="module-services-gitlab-maintenance-rake">
134- <title>Rake tasks</title>
135-136- <para>
137- You can run GitLab's rake tasks with <literal>gitlab-rake</literal>
138- which will be available on the system when GitLab is enabled. You
139- will have to run the command as the user that you configured to run
140- GitLab with.
141- </para>
142-143- <para>
144- A list of all available rake tasks can be obtained by running:
145-<screen>
146-<prompt>$ </prompt>sudo -u git -H gitlab-rake -T
147-</screen>
148- </para>
00000000000000000149 </section>
150- </section>
151</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-gitlab">
4+ <title>GitLab</title>
000000005 <para>
6+ GitLab is a feature-rich git hosting service.
007 </para>
8+ <section xml:id="module-services-gitlab-prerequisites">
9+ <title>Prerequisites</title>
10+ <para>
11+ The <literal>gitlab</literal> service exposes only an Unix socket
12+ at <literal>/run/gitlab/gitlab-workhorse.socket</literal>. You
13+ need to configure a webserver to proxy HTTP requests to the
14+ socket.
15+ </para>
16+ <para>
17+ For instance, the following configuration could be used to use
18+ nginx as frontend proxy:
19+ </para>
20+ <programlisting>
21+services.nginx = {
22+ enable = true;
23+ recommendedGzipSettings = true;
24+ recommendedOptimisation = true;
25+ recommendedProxySettings = true;
26+ recommendedTlsSettings = true;
27+ virtualHosts."git.example.com" = {
28+ enableACME = true;
29+ forceSSL = true;
30+ locations."/".proxyPass = "http://unix:/run/gitlab/gitlab-workhorse.socket";
31 };
32};
33</programlisting>
34+ </section>
35+ <section xml:id="module-services-gitlab-configuring">
36+ <title>Configuring</title>
37+ <para>
38+ GitLab depends on both PostgreSQL and Redis and will automatically
39+ enable both services. In the case of PostgreSQL, a database and a
40+ role will be created.
41+ </para>
42+ <para>
43+ The default state dir is <literal>/var/gitlab/state</literal>.
44+ This is where all data like the repositories and uploads will be
45+ stored.
46+ </para>
47+ <para>
48+ A basic configuration with some custom settings could look like
49+ this:
50+ </para>
51+ <programlisting>
052services.gitlab = {
53+ enable = true;
54+ databasePasswordFile = "/var/keys/gitlab/db_password";
55+ initialRootPasswordFile = "/var/keys/gitlab/root_password";
56+ https = true;
57+ host = "git.example.com";
58+ port = 443;
59+ user = "git";
60+ group = "git";
61 smtp = {
62+ enable = true;
63+ address = "localhost";
64+ port = 25;
65 };
66 secrets = {
67+ dbFile = "/var/keys/gitlab/db";
68+ secretFile = "/var/keys/gitlab/secret";
69+ otpFile = "/var/keys/gitlab/otp";
70+ jwsFile = "/var/keys/gitlab/jws";
71 };
72+ extraConfig = {
73 gitlab = {
74+ email_from = "gitlab-no-reply@example.com";
75+ email_display_name = "Example GitLab";
76+ email_reply_to = "gitlab-no-reply@example.com";
77 default_projects_features = { builds = false; };
78 };
79 };
80};
81</programlisting>
82+ <para>
83+ If you’re setting up a new GitLab instance, generate new secrets.
84+ You for instance use
85+ <literal>tr -dc A-Za-z0-9 < /dev/urandom | head -c 128 > /var/keys/gitlab/db</literal>
86+ to generate a new db secret. Make sure the files can be read by,
87+ and only by, the user specified by
88+ <link linkend="opt-services.gitlab.user">services.gitlab.user</link>.
89+ GitLab encrypts sensitive data stored in the database. If you’re
90+ restoring an existing GitLab instance, you must specify the
91+ secrets secret from <literal>config/secrets.yml</literal> located
92+ in your GitLab state folder.
93+ </para>
94+ <para>
95+ When <literal>incoming_mail.enabled</literal> is set to
96+ <literal>true</literal> in
97+ <link linkend="opt-services.gitlab.extraConfig">extraConfig</link>
98+ an additional service called <literal>gitlab-mailroom</literal> is
99+ enabled for fetching incoming mail.
100+ </para>
101+ <para>
102+ Refer to <xref linkend="ch-options" /> for all available
103+ configuration options for the
104+ <link linkend="opt-services.gitlab.enable">services.gitlab</link>
105+ module.
106+ </para>
000000000000000000000107 </section>
108+ <section xml:id="module-services-gitlab-maintenance">
109+ <title>Maintenance</title>
110+ <section xml:id="module-services-gitlab-maintenance-backups">
111+ <title>Backups</title>
112+ <para>
113+ Backups can be configured with the options in
114+ <link linkend="opt-services.gitlab.backup.keepTime">services.gitlab.backup</link>.
115+ Use the
116+ <link linkend="opt-services.gitlab.backup.startAt">services.gitlab.backup.startAt</link>
117+ option to configure regular backups.
118+ </para>
119+ <para>
120+ To run a manual backup, start the
121+ <literal>gitlab-backup</literal> service:
122+ </para>
123+ <programlisting>
124+$ systemctl start gitlab-backup.service
125+</programlisting>
126+ </section>
127+ <section xml:id="module-services-gitlab-maintenance-rake">
128+ <title>Rake tasks</title>
129+ <para>
130+ You can run GitLab’s rake tasks with
131+ <literal>gitlab-rake</literal> which will be available on the
132+ system when GitLab is enabled. You will have to run the command
133+ as the user that you configured to run GitLab with.
134+ </para>
135+ <para>
136+ A list of all available rake tasks can be obtained by running:
137+ </para>
138+ <programlisting>
139+$ sudo -u git -H gitlab-rake -T
140+</programlisting>
141+ </section>
142 </section>
0143</chapter>
···1+# Sourcehut {#module-services-sourcehut}
2+3+[Sourcehut](https://sr.ht.com/) is an open-source,
4+self-hostable software development platform. The server setup can be automated using
5+[services.sourcehut](#opt-services.sourcehut.enable).
6+7+## Basic usage {#module-services-sourcehut-basic-usage}
8+9+Sourcehut is a Python and Go based set of applications.
10+This NixOS module also provides basic configuration integrating Sourcehut into locally running
11+`services.nginx`, `services.redis.servers.sourcehut`, `services.postfix`
12+and `services.postgresql` services.
13+14+A very basic configuration may look like this:
15+```
16+{ pkgs, ... }:
17+let
18+ fqdn =
19+ let
20+ join = hostName: domain: hostName + optionalString (domain != null) ".${domain}";
21+ in join config.networking.hostName config.networking.domain;
22+in {
23+24+ networking = {
25+ hostName = "srht";
26+ domain = "tld";
27+ firewall.allowedTCPPorts = [ 22 80 443 ];
28+ };
29+30+ services.sourcehut = {
31+ enable = true;
32+ git.enable = true;
33+ man.enable = true;
34+ meta.enable = true;
35+ nginx.enable = true;
36+ postfix.enable = true;
37+ postgresql.enable = true;
38+ redis.enable = true;
39+ settings = {
40+ "sr.ht" = {
41+ environment = "production";
42+ global-domain = fqdn;
43+ origin = "https://${fqdn}";
44+ # Produce keys with srht-keygen from sourcehut.coresrht.
45+ network-key = "/run/keys/path/to/network-key";
46+ service-key = "/run/keys/path/to/service-key";
47+ };
48+ webhooks.private-key= "/run/keys/path/to/webhook-key";
49+ };
50+ };
51+52+ security.acme.certs."${fqdn}".extraDomainNames = [
53+ "meta.${fqdn}"
54+ "man.${fqdn}"
55+ "git.${fqdn}"
56+ ];
57+58+ services.nginx = {
59+ enable = true;
60+ # only recommendedProxySettings are strictly required, but the rest make sense as well.
61+ recommendedTlsSettings = true;
62+ recommendedOptimisation = true;
63+ recommendedGzipSettings = true;
64+ recommendedProxySettings = true;
65+66+ # Settings to setup what certificates are used for which endpoint.
67+ virtualHosts = {
68+ "${fqdn}".enableACME = true;
69+ "meta.${fqdn}".useACMEHost = fqdn:
70+ "man.${fqdn}".useACMEHost = fqdn:
71+ "git.${fqdn}".useACMEHost = fqdn:
72+ };
73+ };
74+}
75+```
76+77+ The `hostName` option is used internally to configure the nginx
78+reverse-proxy. The `settings` attribute set is
79+used by the configuration generator and the result is placed in `/etc/sr.ht/config.ini`.
80+81+## Configuration {#module-services-sourcehut-configuration}
82+83+All configuration parameters are also stored in
84+`/etc/sr.ht/config.ini` which is generated by
85+the module and linked from the store to ensure that all values from `config.ini`
86+can be modified by the module.
87+88+## Using an alternative webserver as reverse-proxy (e.g. `httpd`) {#module-services-sourcehut-httpd}
89+90+By default, `nginx` is used as reverse-proxy for `sourcehut`.
91+However, it's possible to use e.g. `httpd` by explicitly disabling
92+`nginx` using [](#opt-services.nginx.enable) and fixing the
93+`settings`.
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-sourcehut">
4+ <title>Sourcehut</title>
5+ <para>
6+ <link xlink:href="https://sr.ht.com/">Sourcehut</link> is an
7+ open-source, self-hostable software development platform. The server
8+ setup can be automated using
9+ <link linkend="opt-services.sourcehut.enable">services.sourcehut</link>.
10+ </para>
11+ <section xml:id="module-services-sourcehut-basic-usage">
12+ <title>Basic usage</title>
13+ <para>
14+ Sourcehut is a Python and Go based set of applications. This NixOS
15+ module also provides basic configuration integrating Sourcehut
16+ into locally running <literal>services.nginx</literal>,
17+ <literal>services.redis.servers.sourcehut</literal>,
18+ <literal>services.postfix</literal> and
19+ <literal>services.postgresql</literal> services.
20+ </para>
21+ <para>
22+ A very basic configuration may look like this:
23+ </para>
24+ <programlisting>
25+{ pkgs, ... }:
26+let
27+ fqdn =
28+ let
29+ join = hostName: domain: hostName + optionalString (domain != null) ".${domain}";
30+ in join config.networking.hostName config.networking.domain;
31+in {
32+33+ networking = {
34+ hostName = "srht";
35+ domain = "tld";
36+ firewall.allowedTCPPorts = [ 22 80 443 ];
37+ };
38+39+ services.sourcehut = {
40+ enable = true;
41+ git.enable = true;
42+ man.enable = true;
43+ meta.enable = true;
44+ nginx.enable = true;
45+ postfix.enable = true;
46+ postgresql.enable = true;
47+ redis.enable = true;
48+ settings = {
49+ "sr.ht" = {
50+ environment = "production";
51+ global-domain = fqdn;
52+ origin = "https://${fqdn}";
53+ # Produce keys with srht-keygen from sourcehut.coresrht.
54+ network-key = "/run/keys/path/to/network-key";
55+ service-key = "/run/keys/path/to/service-key";
56+ };
57+ webhooks.private-key= "/run/keys/path/to/webhook-key";
58+ };
59+ };
60+61+ security.acme.certs."${fqdn}".extraDomainNames = [
62+ "meta.${fqdn}"
63+ "man.${fqdn}"
64+ "git.${fqdn}"
65+ ];
66+67+ services.nginx = {
68+ enable = true;
69+ # only recommendedProxySettings are strictly required, but the rest make sense as well.
70+ recommendedTlsSettings = true;
71+ recommendedOptimisation = true;
72+ recommendedGzipSettings = true;
73+ recommendedProxySettings = true;
74+75+ # Settings to setup what certificates are used for which endpoint.
76+ virtualHosts = {
77+ "${fqdn}".enableACME = true;
78+ "meta.${fqdn}".useACMEHost = fqdn:
79+ "man.${fqdn}".useACMEHost = fqdn:
80+ "git.${fqdn}".useACMEHost = fqdn:
81+ };
82+ };
83+}
84+</programlisting>
85+ <para>
86+ The <literal>hostName</literal> option is used internally to
87+ configure the nginx reverse-proxy. The <literal>settings</literal>
88+ attribute set is used by the configuration generator and the
89+ result is placed in <literal>/etc/sr.ht/config.ini</literal>.
90+ </para>
91+ </section>
92+ <section xml:id="module-services-sourcehut-configuration">
93+ <title>Configuration</title>
94+ <para>
95+ All configuration parameters are also stored in
96+ <literal>/etc/sr.ht/config.ini</literal> which is generated by the
97+ module and linked from the store to ensure that all values from
98+ <literal>config.ini</literal> can be modified by the module.
99+ </para>
100+ </section>
101+ <section xml:id="module-services-sourcehut-httpd">
102+ <title>Using an alternative webserver as reverse-proxy (e.g.
103+ <literal>httpd</literal>)</title>
104+ <para>
105+ By default, <literal>nginx</literal> is used as reverse-proxy for
106+ <literal>sourcehut</literal>. However, it’s possible to use e.g.
107+ <literal>httpd</literal> by explicitly disabling
108+ <literal>nginx</literal> using
109+ <xref linkend="opt-services.nginx.enable" /> and fixing the
110+ <literal>settings</literal>.
111+ </para>
112+ </section>
113+</chapter>
···1+# Taskserver {#module-services-taskserver}
2+3+Taskserver is the server component of
4+[Taskwarrior](https://taskwarrior.org/), a free and
5+open source todo list application.
6+7+*Upstream documentation:* <https://taskwarrior.org/docs/#taskd>
8+9+## Configuration {#module-services-taskserver-configuration}
10+11+Taskserver does all of its authentication via TLS using client certificates,
12+so you either need to roll your own CA or purchase a certificate from a
13+known CA, which allows creation of client certificates. These certificates
14+are usually advertised as "server certificates".
15+16+So in order to make it easier to handle your own CA, there is a helper tool
17+called {command}`nixos-taskserver` which manages the custom CA along
18+with Taskserver organisations, users and groups.
19+20+While the client certificates in Taskserver only authenticate whether a user
21+is allowed to connect, every user has its own UUID which identifies it as an
22+entity.
23+24+With {command}`nixos-taskserver` the client certificate is created
25+along with the UUID of the user, so it handles all of the credentials needed
26+in order to setup the Taskwarrior client to work with a Taskserver.
27+28+## The nixos-taskserver tool {#module-services-taskserver-nixos-taskserver-tool}
29+30+Because Taskserver by default only provides scripts to setup users
31+imperatively, the {command}`nixos-taskserver` tool is used for
32+addition and deletion of organisations along with users and groups defined
33+by [](#opt-services.taskserver.organisations) and as well for
34+imperative set up.
35+36+The tool is designed to not interfere if the command is used to manually set
37+up some organisations, users or groups.
38+39+For example if you add a new organisation using {command}`nixos-taskserver
40+org add foo`, the organisation is not modified and deleted no
41+matter what you define in
42+{option}`services.taskserver.organisations`, even if you're adding
43+the same organisation in that option.
44+45+The tool is modelled to imitate the official {command}`taskd`
46+command, documentation for each subcommand can be shown by using the
47+{option}`--help` switch.
48+49+## Declarative/automatic CA management {#module-services-taskserver-declarative-ca-management}
50+51+Everything is done according to what you specify in the module options,
52+however in order to set up a Taskwarrior client for synchronisation with a
53+Taskserver instance, you have to transfer the keys and certificates to the
54+client machine.
55+56+This is done using {command}`nixos-taskserver user export $orgname
57+$username` which is printing a shell script fragment to stdout
58+which can either be used verbatim or adjusted to import the user on the
59+client machine.
60+61+For example, let's say you have the following configuration:
62+```ShellSession
63+{
64+ services.taskserver.enable = true;
65+ services.taskserver.fqdn = "server";
66+ services.taskserver.listenHost = "::";
67+ services.taskserver.organisations.my-company.users = [ "alice" ];
68+}
69+```
70+This creates an organisation called `my-company` with the
71+user `alice`.
72+73+Now in order to import the `alice` user to another machine
74+`alicebox`, all we need to do is something like this:
75+```ShellSession
76+$ ssh server nixos-taskserver user export my-company alice | sh
77+```
78+Of course, if no SSH daemon is available on the server you can also copy
79+& paste it directly into a shell.
80+81+After this step the user should be set up and you can start synchronising
82+your tasks for the first time with {command}`task sync init` on
83+`alicebox`.
84+85+Subsequent synchronisation requests merely require the command {command}`task
86+sync` after that stage.
87+88+## Manual CA management {#module-services-taskserver-manual-ca-management}
89+90+If you set any options within
91+[service.taskserver.pki.manual](#opt-services.taskserver.pki.manual.ca.cert).*,
92+{command}`nixos-taskserver` won't issue certificates, but you can
93+still use it for adding or removing user accounts.
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-taskserver">
4+ <title>Taskserver</title>
5+ <para>
6+ Taskserver is the server component of
7+ <link xlink:href="https://taskwarrior.org/">Taskwarrior</link>, a
8+ free and open source todo list application.
9+ </para>
10+ <para>
11+ <emphasis>Upstream documentation:</emphasis>
12+ <link xlink:href="https://taskwarrior.org/docs/#taskd">https://taskwarrior.org/docs/#taskd</link>
13+ </para>
14+ <section xml:id="module-services-taskserver-configuration">
15+ <title>Configuration</title>
16+ <para>
17+ Taskserver does all of its authentication via TLS using client
18+ certificates, so you either need to roll your own CA or purchase a
19+ certificate from a known CA, which allows creation of client
20+ certificates. These certificates are usually advertised as
21+ <quote>server certificates</quote>.
22+ </para>
23+ <para>
24+ So in order to make it easier to handle your own CA, there is a
25+ helper tool called <command>nixos-taskserver</command> which
26+ manages the custom CA along with Taskserver organisations, users
27+ and groups.
28+ </para>
29+ <para>
30+ While the client certificates in Taskserver only authenticate
31+ whether a user is allowed to connect, every user has its own UUID
32+ which identifies it as an entity.
33+ </para>
34+ <para>
35+ With <command>nixos-taskserver</command> the client certificate is
36+ created along with the UUID of the user, so it handles all of the
37+ credentials needed in order to setup the Taskwarrior client to
38+ work with a Taskserver.
39+ </para>
40+ </section>
41+ <section xml:id="module-services-taskserver-nixos-taskserver-tool">
42+ <title>The nixos-taskserver tool</title>
43+ <para>
44+ Because Taskserver by default only provides scripts to setup users
45+ imperatively, the <command>nixos-taskserver</command> tool is used
46+ for addition and deletion of organisations along with users and
47+ groups defined by
48+ <xref linkend="opt-services.taskserver.organisations" /> and as
49+ well for imperative set up.
50+ </para>
51+ <para>
52+ The tool is designed to not interfere if the command is used to
53+ manually set up some organisations, users or groups.
54+ </para>
55+ <para>
56+ For example if you add a new organisation using
57+ <command>nixos-taskserver org add foo</command>, the organisation
58+ is not modified and deleted no matter what you define in
59+ <option>services.taskserver.organisations</option>, even if you’re
60+ adding the same organisation in that option.
61+ </para>
62+ <para>
63+ The tool is modelled to imitate the official
64+ <command>taskd</command> command, documentation for each
65+ subcommand can be shown by using the <option>--help</option>
66+ switch.
67+ </para>
68+ </section>
69+ <section xml:id="module-services-taskserver-declarative-ca-management">
70+ <title>Declarative/automatic CA management</title>
71+ <para>
72+ Everything is done according to what you specify in the module
73+ options, however in order to set up a Taskwarrior client for
74+ synchronisation with a Taskserver instance, you have to transfer
75+ the keys and certificates to the client machine.
76+ </para>
77+ <para>
78+ This is done using
79+ <command>nixos-taskserver user export $orgname $username</command>
80+ which is printing a shell script fragment to stdout which can
81+ either be used verbatim or adjusted to import the user on the
82+ client machine.
83+ </para>
84+ <para>
85+ For example, let’s say you have the following configuration:
86+ </para>
87+ <programlisting>
88+{
89+ services.taskserver.enable = true;
90+ services.taskserver.fqdn = "server";
91+ services.taskserver.listenHost = "::";
92+ services.taskserver.organisations.my-company.users = [ "alice" ];
93+}
94+</programlisting>
95+ <para>
96+ This creates an organisation called <literal>my-company</literal>
97+ with the user <literal>alice</literal>.
98+ </para>
99+ <para>
100+ Now in order to import the <literal>alice</literal> user to
101+ another machine <literal>alicebox</literal>, all we need to do is
102+ something like this:
103+ </para>
104+ <programlisting>
105+$ ssh server nixos-taskserver user export my-company alice | sh
106+</programlisting>
107+ <para>
108+ Of course, if no SSH daemon is available on the server you can
109+ also copy & paste it directly into a shell.
110+ </para>
111+ <para>
112+ After this step the user should be set up and you can start
113+ synchronising your tasks for the first time with
114+ <command>task sync init</command> on <literal>alicebox</literal>.
115+ </para>
116+ <para>
117+ Subsequent synchronisation requests merely require the command
118+ <command>task sync</command> after that stage.
119+ </para>
120+ </section>
121+ <section xml:id="module-services-taskserver-manual-ca-management">
122+ <title>Manual CA management</title>
123+ <para>
124+ If you set any options within
125+ <link linkend="opt-services.taskserver.pki.manual.ca.cert">service.taskserver.pki.manual</link>.*,
126+ <command>nixos-taskserver</command> won’t issue certificates, but
127+ you can still use it for adding or removing user accounts.
128+ </para>
129+ </section>
130+</chapter>
-135
nixos/modules/services/misc/taskserver/doc.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- version="5.0"
4- xml:id="module-services-taskserver">
5- <title>Taskserver</title>
6- <para>
7- Taskserver is the server component of
8- <link xlink:href="https://taskwarrior.org/">Taskwarrior</link>, a free and
9- open source todo list application.
10- </para>
11- <para>
12- <emphasis>Upstream documentation:</emphasis>
13- <link xlink:href="https://taskwarrior.org/docs/#taskd"/>
14- </para>
15- <section xml:id="module-services-taskserver-configuration">
16- <title>Configuration</title>
17-18- <para>
19- Taskserver does all of its authentication via TLS using client certificates,
20- so you either need to roll your own CA or purchase a certificate from a
21- known CA, which allows creation of client certificates. These certificates
22- are usually advertised as <quote>server certificates</quote>.
23- </para>
24-25- <para>
26- So in order to make it easier to handle your own CA, there is a helper tool
27- called <command>nixos-taskserver</command> which manages the custom CA along
28- with Taskserver organisations, users and groups.
29- </para>
30-31- <para>
32- While the client certificates in Taskserver only authenticate whether a user
33- is allowed to connect, every user has its own UUID which identifies it as an
34- entity.
35- </para>
36-37- <para>
38- With <command>nixos-taskserver</command> the client certificate is created
39- along with the UUID of the user, so it handles all of the credentials needed
40- in order to setup the Taskwarrior client to work with a Taskserver.
41- </para>
42- </section>
43- <section xml:id="module-services-taskserver-nixos-taskserver-tool">
44- <title>The nixos-taskserver tool</title>
45-46- <para>
47- Because Taskserver by default only provides scripts to setup users
48- imperatively, the <command>nixos-taskserver</command> tool is used for
49- addition and deletion of organisations along with users and groups defined
50- by <xref linkend="opt-services.taskserver.organisations"/> and as well for
51- imperative set up.
52- </para>
53-54- <para>
55- The tool is designed to not interfere if the command is used to manually set
56- up some organisations, users or groups.
57- </para>
58-59- <para>
60- For example if you add a new organisation using <command>nixos-taskserver
61- org add foo</command>, the organisation is not modified and deleted no
62- matter what you define in
63- <option>services.taskserver.organisations</option>, even if you're adding
64- the same organisation in that option.
65- </para>
66-67- <para>
68- The tool is modelled to imitate the official <command>taskd</command>
69- command, documentation for each subcommand can be shown by using the
70- <option>--help</option> switch.
71- </para>
72- </section>
73- <section xml:id="module-services-taskserver-declarative-ca-management">
74- <title>Declarative/automatic CA management</title>
75-76- <para>
77- Everything is done according to what you specify in the module options,
78- however in order to set up a Taskwarrior client for synchronisation with a
79- Taskserver instance, you have to transfer the keys and certificates to the
80- client machine.
81- </para>
82-83- <para>
84- This is done using <command>nixos-taskserver user export $orgname
85- $username</command> which is printing a shell script fragment to stdout
86- which can either be used verbatim or adjusted to import the user on the
87- client machine.
88- </para>
89-90- <para>
91- For example, let's say you have the following configuration:
92-<screen>
93-{
94- <xref linkend="opt-services.taskserver.enable"/> = true;
95- <xref linkend="opt-services.taskserver.fqdn"/> = "server";
96- <xref linkend="opt-services.taskserver.listenHost"/> = "::";
97- <link linkend="opt-services.taskserver.organisations._name_.users">services.taskserver.organisations.my-company.users</link> = [ "alice" ];
98-}
99-</screen>
100- This creates an organisation called <literal>my-company</literal> with the
101- user <literal>alice</literal>.
102- </para>
103-104- <para>
105- Now in order to import the <literal>alice</literal> user to another machine
106- <literal>alicebox</literal>, all we need to do is something like this:
107-<screen>
108-<prompt>$ </prompt>ssh server nixos-taskserver user export my-company alice | sh
109-</screen>
110- Of course, if no SSH daemon is available on the server you can also copy
111- & paste it directly into a shell.
112- </para>
113-114- <para>
115- After this step the user should be set up and you can start synchronising
116- your tasks for the first time with <command>task sync init</command> on
117- <literal>alicebox</literal>.
118- </para>
119-120- <para>
121- Subsequent synchronisation requests merely require the command <command>task
122- sync</command> after that stage.
123- </para>
124- </section>
125- <section xml:id="module-services-taskserver-manual-ca-management">
126- <title>Manual CA management</title>
127-128- <para>
129- If you set any options within
130- <link linkend="opt-services.taskserver.pki.manual.ca.cert">service.taskserver.pki.manual</link>.*,
131- <command>nixos-taskserver</command> won't issue certificates, but you can
132- still use it for adding or removing user accounts.
133- </para>
134- </section>
135-</chapter>
···1+# WeeChat {#module-services-weechat}
2+3+[WeeChat](https://weechat.org/) is a fast and
4+extensible IRC client.
5+6+## Basic Usage {#module-services-weechat-basic-usage}
7+8+By default, the module creates a
9+[`systemd`](https://www.freedesktop.org/wiki/Software/systemd/)
10+unit which runs the chat client in a detached
11+[`screen`](https://www.gnu.org/software/screen/)
12+session.
13+14+This can be done by enabling the `weechat` service:
15+```
16+{ ... }:
17+18+{
19+ services.weechat.enable = true;
20+}
21+```
22+23+The service is managed by a dedicated user named `weechat`
24+in the state directory `/var/lib/weechat`.
25+26+## Re-attaching to WeeChat {#module-services-weechat-reattach}
27+28+WeeChat runs in a screen session owned by a dedicated user. To explicitly
29+allow your another user to attach to this session, the
30+`screenrc` needs to be tweaked by adding
31+[multiuser](https://www.gnu.org/software/screen/manual/html_node/Multiuser.html#Multiuser)
32+support:
33+```
34+{
35+ programs.screen.screenrc = ''
36+ multiuser on
37+ acladd normal_user
38+ '';
39+}
40+```
41+Now, the session can be re-attached like this:
42+```
43+screen -x weechat/weechat-screen
44+```
45+46+*The session name can be changed using [services.weechat.sessionName.](options.html#opt-services.weechat.sessionName)*
+47-50
nixos/modules/services/misc/weechat.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-weechat">
6- <title>WeeChat</title>
7- <para>
8- <link xlink:href="https://weechat.org/">WeeChat</link> is a fast and
9- extensible IRC client.
10- </para>
11- <section xml:id="module-services-weechat-basic-usage">
12- <title>Basic Usage</title>
13-14 <para>
15- By default, the module creates a
16- <literal><link xlink:href="https://www.freedesktop.org/wiki/Software/systemd/">systemd</link></literal>
17- unit which runs the chat client in a detached
18- <literal><link xlink:href="https://www.gnu.org/software/screen/">screen</link></literal>
19- session.
20 </para>
21-22- <para>
23- This can be done by enabling the <literal>weechat</literal> service:
24-<programlisting>
000000000025{ ... }:
2627{
28- <link linkend="opt-services.weechat.enable">services.weechat.enable</link> = true;
29}
30</programlisting>
31- </para>
32-33- <para>
34- The service is managed by a dedicated user named <literal>weechat</literal>
35- in the state directory <literal>/var/lib/weechat</literal>.
36- </para>
37- </section>
38- <section xml:id="module-services-weechat-reattach">
39- <title>Re-attaching to WeeChat</title>
40-41- <para>
42- WeeChat runs in a screen session owned by a dedicated user. To explicitly
43- allow your another user to attach to this session, the
44- <literal>screenrc</literal> needs to be tweaked by adding
45- <link xlink:href="https://www.gnu.org/software/screen/manual/html_node/Multiuser.html#Multiuser">multiuser</link>
46- support:
47-<programlisting>
48{
49- <link linkend="opt-programs.screen.screenrc">programs.screen.screenrc</link> = ''
50 multiuser on
51 acladd normal_user
52 '';
53}
54</programlisting>
55- Now, the session can be re-attached like this:
56-<programlisting>
0057screen -x weechat/weechat-screen
58</programlisting>
59- </para>
60-61- <para>
62- <emphasis>The session name can be changed using
63- <link linkend="opt-services.weechat.sessionName">services.weechat.sessionName.</link></emphasis>
64- </para>
65- </section>
66</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-weechat">
4+ <title>WeeChat</title>
0000000005 <para>
6+ <link xlink:href="https://weechat.org/">WeeChat</link> is a fast and
7+ extensible IRC client.
0008 </para>
9+ <section xml:id="module-services-weechat-basic-usage">
10+ <title>Basic Usage</title>
11+ <para>
12+ By default, the module creates a
13+ <link xlink:href="https://www.freedesktop.org/wiki/Software/systemd/"><literal>systemd</literal></link>
14+ unit which runs the chat client in a detached
15+ <link xlink:href="https://www.gnu.org/software/screen/"><literal>screen</literal></link>
16+ session.
17+ </para>
18+ <para>
19+ This can be done by enabling the <literal>weechat</literal>
20+ service:
21+ </para>
22+ <programlisting>
23{ ... }:
2425{
26+ services.weechat.enable = true;
27}
28</programlisting>
29+ <para>
30+ The service is managed by a dedicated user named
31+ <literal>weechat</literal> in the state directory
32+ <literal>/var/lib/weechat</literal>.
33+ </para>
34+ </section>
35+ <section xml:id="module-services-weechat-reattach">
36+ <title>Re-attaching to WeeChat</title>
37+ <para>
38+ WeeChat runs in a screen session owned by a dedicated user. To
39+ explicitly allow your another user to attach to this session, the
40+ <literal>screenrc</literal> needs to be tweaked by adding
41+ <link xlink:href="https://www.gnu.org/software/screen/manual/html_node/Multiuser.html#Multiuser">multiuser</link>
42+ support:
43+ </para>
44+ <programlisting>
045{
46+ programs.screen.screenrc = ''
47 multiuser on
48 acladd normal_user
49 '';
50}
51</programlisting>
52+ <para>
53+ Now, the session can be re-attached like this:
54+ </para>
55+ <programlisting>
56screen -x weechat/weechat-screen
57</programlisting>
58+ <para>
59+ <emphasis>The session name can be changed using
60+ <link xlink:href="options.html#opt-services.weechat.sessionName">services.weechat.sessionName.</link></emphasis>
61+ </para>
62+ </section>
0063</chapter>
+2-2
nixos/modules/services/monitoring/parsedmarc.md
···25Note that GeoIP provisioning is disabled in the example for
26simplicity, but should be turned on for fully functional reports.
2728-## Local mail
29Instead of watching an external inbox, a local inbox can be
30automatically provisioned. The recipient's name is by default set to
31`dmarc`, but can be configured in
···49};
50```
5152-## Grafana and GeoIP
53The reports can be visualized and summarized with parsedmarc's
54official Grafana dashboard. For all views to work, and for the data to
55be complete, GeoIP databases are also required. The following example
···25Note that GeoIP provisioning is disabled in the example for
26simplicity, but should be turned on for fully functional reports.
2728+## Local mail {#module-services-parsedmarc-local-mail}
29Instead of watching an external inbox, a local inbox can be
30automatically provisioned. The recipient's name is by default set to
31`dmarc`, but can be configured in
···49};
50```
5152+## Grafana and GeoIP {#module-services-parsedmarc-grafana-geoip}
53The reports can be visualized and summarized with parsedmarc's
54official Grafana dashboard. For all views to work, and for the data to
55be complete, GeoIP databases are also required. The following example
···001<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-parsedmarc">
2 <title>parsedmarc</title>
3 <para>
···15 email address and saves them to a local Elasticsearch instance
16 looks like this:
17 </para>
18- <programlisting>
19services.parsedmarc = {
20 enable = true;
21 settings.imap = {
···31 simplicity, but should be turned on for fully functional reports.
32 </para>
33 </section>
34- <section xml:id="local-mail">
35 <title>Local mail</title>
36 <para>
37 Instead of watching an external inbox, a local inbox can be
···44 email address that should be configured in the domain’s dmarc
45 policy is <literal>dmarc@monitoring.example.com</literal>.
46 </para>
47- <programlisting>
48services.parsedmarc = {
49 enable = true;
50 provision = {
···57};
58</programlisting>
59 </section>
60- <section xml:id="grafana-and-geoip">
61 <title>Grafana and GeoIP</title>
62 <para>
63 The reports can be visualized and summarized with parsedmarc’s
···67 Elasticsearch instance is automatically added as a Grafana
68 datasource, and the dashboard is added to Grafana as well.
69 </para>
70- <programlisting>
71services.parsedmarc = {
72 enable = true;
73 provision = {
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-parsedmarc">
4 <title>parsedmarc</title>
5 <para>
···17 email address and saves them to a local Elasticsearch instance
18 looks like this:
19 </para>
20+ <programlisting language="nix">
21services.parsedmarc = {
22 enable = true;
23 settings.imap = {
···33 simplicity, but should be turned on for fully functional reports.
34 </para>
35 </section>
36+ <section xml:id="module-services-parsedmarc-local-mail">
37 <title>Local mail</title>
38 <para>
39 Instead of watching an external inbox, a local inbox can be
···46 email address that should be configured in the domain’s dmarc
47 policy is <literal>dmarc@monitoring.example.com</literal>.
48 </para>
49+ <programlisting language="nix">
50services.parsedmarc = {
51 enable = true;
52 provision = {
···59};
60</programlisting>
61 </section>
62+ <section xml:id="module-services-parsedmarc-grafana-geoip">
63 <title>Grafana and GeoIP</title>
64 <para>
65 The reports can be visualized and summarized with parsedmarc’s
···69 Elasticsearch instance is automatically added as a Grafana
70 datasource, and the dashboard is added to Grafana as well.
71 </para>
72+ <programlisting language="nix">
73services.parsedmarc = {
74 enable = true;
75 provision = {
···1+# Prometheus exporters {#module-services-prometheus-exporters}
2+3+Prometheus exporters provide metrics for the
4+[prometheus monitoring system](https://prometheus.io).
5+6+## Configuration {#module-services-prometheus-exporters-configuration}
7+8+One of the most common exporters is the
9+[node exporter](https://github.com/prometheus/node_exporter),
10+it provides hardware and OS metrics from the host it's
11+running on. The exporter could be configured as follows:
12+```
13+ services.prometheus.exporters.node = {
14+ enable = true;
15+ port = 9100;
16+ enabledCollectors = [
17+ "logind"
18+ "systemd"
19+ ];
20+ disabledCollectors = [
21+ "textfile"
22+ ];
23+ openFirewall = true;
24+ firewallFilter = "-i br0 -p tcp -m tcp --dport 9100";
25+ };
26+```
27+It should now serve all metrics from the collectors that are explicitly
28+enabled and the ones that are
29+[enabled by default](https://github.com/prometheus/node_exporter#enabled-by-default),
30+via http under `/metrics`. In this
31+example the firewall should just allow incoming connections to the
32+exporter's port on the bridge interface `br0` (this would
33+have to be configured separately of course). For more information about
34+configuration see `man configuration.nix` or search through
35+the [available options](https://nixos.org/nixos/options.html#prometheus.exporters).
36+37+Prometheus can now be configured to consume the metrics produced by the exporter:
38+```
39+ services.prometheus = {
40+ # ...
41+42+ scrapeConfigs = [
43+ {
44+ job_name = "node";
45+ static_configs = [{
46+ targets = [ "localhost:${toString config.services.prometheus.exporters.node.port}" ];
47+ }];
48+ }
49+ ];
50+51+ # ...
52+ }
53+```
54+55+## Adding a new exporter {#module-services-prometheus-exporters-new-exporter}
56+57+To add a new exporter, it has to be packaged first (see
58+`nixpkgs/pkgs/servers/monitoring/prometheus/` for
59+examples), then a module can be added. The postfix exporter is used in this
60+example:
61+62+ - Some default options for all exporters are provided by
63+ `nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix`:
64+65+ - `enable`
66+ - `port`
67+ - `listenAddress`
68+ - `extraFlags`
69+ - `openFirewall`
70+ - `firewallFilter`
71+ - `user`
72+ - `group`
73+ - As there is already a package available, the module can now be added. This
74+ is accomplished by adding a new file to the
75+ `nixos/modules/services/monitoring/prometheus/exporters/`
76+ directory, which will be called postfix.nix and contains all exporter
77+ specific options and configuration:
78+ ```
79+ # nixpgs/nixos/modules/services/prometheus/exporters/postfix.nix
80+ { config, lib, pkgs, options }:
81+82+ with lib;
83+84+ let
85+ # for convenience we define cfg here
86+ cfg = config.services.prometheus.exporters.postfix;
87+ in
88+ {
89+ port = 9154; # The postfix exporter listens on this port by default
90+91+ # `extraOpts` is an attribute set which contains additional options
92+ # (and optional overrides for default options).
93+ # Note that this attribute is optional.
94+ extraOpts = {
95+ telemetryPath = mkOption {
96+ type = types.str;
97+ default = "/metrics";
98+ description = ''
99+ Path under which to expose metrics.
100+ '';
101+ };
102+ logfilePath = mkOption {
103+ type = types.path;
104+ default = /var/log/postfix_exporter_input.log;
105+ example = /var/log/mail.log;
106+ description = ''
107+ Path where Postfix writes log entries.
108+ This file will be truncated by this exporter!
109+ '';
110+ };
111+ showqPath = mkOption {
112+ type = types.path;
113+ default = /var/spool/postfix/public/showq;
114+ example = /var/lib/postfix/queue/public/showq;
115+ description = ''
116+ Path at which Postfix places its showq socket.
117+ '';
118+ };
119+ };
120+121+ # `serviceOpts` is an attribute set which contains configuration
122+ # for the exporter's systemd service. One of
123+ # `serviceOpts.script` and `serviceOpts.serviceConfig.ExecStart`
124+ # has to be specified here. This will be merged with the default
125+ # service configuration.
126+ # Note that by default 'DynamicUser' is 'true'.
127+ serviceOpts = {
128+ serviceConfig = {
129+ DynamicUser = false;
130+ ExecStart = ''
131+ ${pkgs.prometheus-postfix-exporter}/bin/postfix_exporter \
132+ --web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
133+ --web.telemetry-path ${cfg.telemetryPath} \
134+ ${concatStringsSep " \\\n " cfg.extraFlags}
135+ '';
136+ };
137+ };
138+ }
139+ ```
140+ - This should already be enough for the postfix exporter. Additionally one
141+ could now add assertions and conditional default values. This can be done
142+ in the 'meta-module' that combines all exporter definitions and generates
143+ the submodules:
144+ `nixpkgs/nixos/modules/services/prometheus/exporters.nix`
145+146+## Updating an exporter module {#module-services-prometheus-exporters-update-exporter-module}
147+148+Should an exporter option change at some point, it is possible to add
149+information about the change to the exporter definition similar to
150+`nixpkgs/nixos/modules/rename.nix`:
151+```
152+{ config, lib, pkgs, options }:
153+154+with lib;
155+156+let
157+ cfg = config.services.prometheus.exporters.nginx;
158+in
159+{
160+ port = 9113;
161+ extraOpts = {
162+ # additional module options
163+ # ...
164+ };
165+ serviceOpts = {
166+ # service configuration
167+ # ...
168+ };
169+ imports = [
170+ # 'services.prometheus.exporters.nginx.telemetryEndpoint' -> 'services.prometheus.exporters.nginx.telemetryPath'
171+ (mkRenamedOptionModule [ "telemetryEndpoint" ] [ "telemetryPath" ])
172+173+ # removed option 'services.prometheus.exporters.nginx.insecure'
174+ (mkRemovedOptionModule [ "insecure" ] ''
175+ This option was replaced by 'prometheus.exporters.nginx.sslVerify' which defaults to true.
176+ '')
177+ ({ options.warnings = options.warnings; })
178+ ];
179+}
180+```
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-prometheus-exporters">
6- <title>Prometheus exporters</title>
7- <para>
8- Prometheus exporters provide metrics for the
9- <link xlink:href="https://prometheus.io">prometheus monitoring system</link>.
10- </para>
11- <section xml:id="module-services-prometheus-exporters-configuration">
12- <title>Configuration</title>
13-14 <para>
15- One of the most common exporters is the
16- <link xlink:href="https://github.com/prometheus/node_exporter">node
17- exporter</link>, it provides hardware and OS metrics from the host it's
18- running on. The exporter could be configured as follows:
19-<programlisting>
0000000020 services.prometheus.exporters.node = {
21 enable = true;
22 port = 9100;
23 enabledCollectors = [
24- "logind"
25- "systemd"
26 ];
27 disabledCollectors = [
28- "textfile"
29 ];
30 openFirewall = true;
31- firewallFilter = "-i br0 -p tcp -m tcp --dport 9100";
32 };
33</programlisting>
34- It should now serve all metrics from the collectors that are explicitly
35- enabled and the ones that are
36- <link xlink:href="https://github.com/prometheus/node_exporter#enabled-by-default">enabled
37- by default</link>, via http under <literal>/metrics</literal>. In this
38- example the firewall should just allow incoming connections to the
39- exporter's port on the bridge interface <literal>br0</literal> (this would
40- have to be configured separately of course). For more information about
41- configuration see <literal>man configuration.nix</literal> or search through
42- the
43- <link xlink:href="https://nixos.org/nixos/options.html#prometheus.exporters">available
44- options</link>.
45- </para>
46-47- <para>
48- Prometheus can now be configured to consume the metrics produced by the exporter:
0049 <programlisting>
50 services.prometheus = {
51 # ...
5253 scrapeConfigs = [
54 {
55- job_name = "node";
56 static_configs = [{
57- targets = [ "localhost:${toString config.services.prometheus.exporters.node.port}" ];
58 }];
59 }
60 ];
6162 # ...
63 }
64- </programlisting>
65- </para>
66- </section>
67- <section xml:id="module-services-prometheus-exporters-new-exporter">
68- <title>Adding a new exporter</title>
69-70- <para>
71- To add a new exporter, it has to be packaged first (see
72- <literal>nixpkgs/pkgs/servers/monitoring/prometheus/</literal> for
73- examples), then a module can be added. The postfix exporter is used in this
74- example:
75- </para>
76-77- <itemizedlist>
78- <listitem>
79 <para>
80- Some default options for all exporters are provided by
81- <literal>nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix</literal>:
0082 </para>
83- </listitem>
84- <listitem override='none'>
85 <itemizedlist>
86- <listitem>
87- <para>
88- <literal>enable</literal>
89- </para>
90- </listitem>
91- <listitem>
92- <para>
93- <literal>port</literal>
94- </para>
95- </listitem>
96- <listitem>
97- <para>
98- <literal>listenAddress</literal>
99- </para>
100- </listitem>
101- <listitem>
102- <para>
103- <literal>extraFlags</literal>
104- </para>
105- </listitem>
106- <listitem>
107- <para>
108- <literal>openFirewall</literal>
109- </para>
110- </listitem>
111- <listitem>
112- <para>
113- <literal>firewallFilter</literal>
114- </para>
115- </listitem>
116- <listitem>
117- <para>
118- <literal>user</literal>
119- </para>
120- </listitem>
121- <listitem>
122- <para>
123- <literal>group</literal>
124- </para>
125- </listitem>
126- </itemizedlist>
127- </listitem>
128- <listitem>
129- <para>
130- As there is already a package available, the module can now be added. This
131- is accomplished by adding a new file to the
132- <literal>nixos/modules/services/monitoring/prometheus/exporters/</literal>
133- directory, which will be called postfix.nix and contains all exporter
134- specific options and configuration:
135-<programlisting>
0000000136# nixpgs/nixos/modules/services/prometheus/exporters/postfix.nix
137{ config, lib, pkgs, options }:
138···151 extraOpts = {
152 telemetryPath = mkOption {
153 type = types.str;
154- default = "/metrics";
155 description = ''
156 Path under which to expose metrics.
157 '';
···188 ${pkgs.prometheus-postfix-exporter}/bin/postfix_exporter \
189 --web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
190 --web.telemetry-path ${cfg.telemetryPath} \
191- ${concatStringsSep " \\\n " cfg.extraFlags}
192 '';
193 };
194 };
195}
196</programlisting>
197- </para>
198- </listitem>
199- <listitem>
000000000000200 <para>
201- This should already be enough for the postfix exporter. Additionally one
202- could now add assertions and conditional default values. This can be done
203- in the 'meta-module' that combines all exporter definitions and generates
204- the submodules:
205- <literal>nixpkgs/nixos/modules/services/prometheus/exporters.nix</literal>
206 </para>
207- </listitem>
208- </itemizedlist>
209- </section>
210- <section xml:id="module-services-prometheus-exporters-update-exporter-module">
211- <title>Updating an exporter module</title>
212- <para>
213- Should an exporter option change at some point, it is possible to add
214- information about the change to the exporter definition similar to
215- <literal>nixpkgs/nixos/modules/rename.nix</literal>:
216-<programlisting>
217{ config, lib, pkgs, options }:
218219with lib;
···232 # ...
233 };
234 imports = [
235- # 'services.prometheus.exporters.nginx.telemetryEndpoint' -> 'services.prometheus.exporters.nginx.telemetryPath'
236- (mkRenamedOptionModule [ "telemetryEndpoint" ] [ "telemetryPath" ])
237238 # removed option 'services.prometheus.exporters.nginx.insecure'
239- (mkRemovedOptionModule [ "insecure" ] ''
240 This option was replaced by 'prometheus.exporters.nginx.sslVerify' which defaults to true.
241 '')
242 ({ options.warnings = options.warnings; })
243 ];
244}
245</programlisting>
246- </para>
247 </section>
248</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-prometheus-exporters">
4+ <title>Prometheus exporters</title>
0000000005 <para>
6+ Prometheus exporters provide metrics for the
7+ <link xlink:href="https://prometheus.io">prometheus monitoring
8+ system</link>.
9+ </para>
10+ <section xml:id="module-services-prometheus-exporters-configuration">
11+ <title>Configuration</title>
12+ <para>
13+ One of the most common exporters is the
14+ <link xlink:href="https://github.com/prometheus/node_exporter">node
15+ exporter</link>, it provides hardware and OS metrics from the host
16+ it’s running on. The exporter could be configured as follows:
17+ </para>
18+ <programlisting>
19 services.prometheus.exporters.node = {
20 enable = true;
21 port = 9100;
22 enabledCollectors = [
23+ "logind"
24+ "systemd"
25 ];
26 disabledCollectors = [
27+ "textfile"
28 ];
29 openFirewall = true;
30+ firewallFilter = "-i br0 -p tcp -m tcp --dport 9100";
31 };
32</programlisting>
33+ <para>
34+ It should now serve all metrics from the collectors that are
35+ explicitly enabled and the ones that are
36+ <link xlink:href="https://github.com/prometheus/node_exporter#enabled-by-default">enabled
37+ by default</link>, via http under <literal>/metrics</literal>. In
38+ this example the firewall should just allow incoming connections
39+ to the exporter’s port on the bridge interface
40+ <literal>br0</literal> (this would have to be configured
41+ separately of course). For more information about configuration
42+ see <literal>man configuration.nix</literal> or search through the
43+ <link xlink:href="https://nixos.org/nixos/options.html#prometheus.exporters">available
44+ options</link>.
45+ </para>
46+ <para>
47+ Prometheus can now be configured to consume the metrics produced
48+ by the exporter:
49+ </para>
50 <programlisting>
51 services.prometheus = {
52 # ...
5354 scrapeConfigs = [
55 {
56+ job_name = "node";
57 static_configs = [{
58+ targets = [ "localhost:${toString config.services.prometheus.exporters.node.port}" ];
59 }];
60 }
61 ];
6263 # ...
64 }
65+</programlisting>
66+ </section>
67+ <section xml:id="module-services-prometheus-exporters-new-exporter">
68+ <title>Adding a new exporter</title>
0000000000069 <para>
70+ To add a new exporter, it has to be packaged first (see
71+ <literal>nixpkgs/pkgs/servers/monitoring/prometheus/</literal> for
72+ examples), then a module can be added. The postfix exporter is
73+ used in this example:
74 </para>
0075 <itemizedlist>
76+ <listitem>
77+ <para>
78+ Some default options for all exporters are provided by
79+ <literal>nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix</literal>:
80+ </para>
81+ <itemizedlist spacing="compact">
82+ <listitem>
83+ <para>
84+ <literal>enable</literal>
85+ </para>
86+ </listitem>
87+ <listitem>
88+ <para>
89+ <literal>port</literal>
90+ </para>
91+ </listitem>
92+ <listitem>
93+ <para>
94+ <literal>listenAddress</literal>
95+ </para>
96+ </listitem>
97+ <listitem>
98+ <para>
99+ <literal>extraFlags</literal>
100+ </para>
101+ </listitem>
102+ <listitem>
103+ <para>
104+ <literal>openFirewall</literal>
105+ </para>
106+ </listitem>
107+ <listitem>
108+ <para>
109+ <literal>firewallFilter</literal>
110+ </para>
111+ </listitem>
112+ <listitem>
113+ <para>
114+ <literal>user</literal>
115+ </para>
116+ </listitem>
117+ <listitem>
118+ <para>
119+ <literal>group</literal>
120+ </para>
121+ </listitem>
122+ </itemizedlist>
123+ </listitem>
124+ <listitem>
125+ <para>
126+ As there is already a package available, the module can now be
127+ added. This is accomplished by adding a new file to the
128+ <literal>nixos/modules/services/monitoring/prometheus/exporters/</literal>
129+ directory, which will be called postfix.nix and contains all
130+ exporter specific options and configuration:
131+ </para>
132+ <programlisting>
133# nixpgs/nixos/modules/services/prometheus/exporters/postfix.nix
134{ config, lib, pkgs, options }:
135···148 extraOpts = {
149 telemetryPath = mkOption {
150 type = types.str;
151+ default = "/metrics";
152 description = ''
153 Path under which to expose metrics.
154 '';
···185 ${pkgs.prometheus-postfix-exporter}/bin/postfix_exporter \
186 --web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
187 --web.telemetry-path ${cfg.telemetryPath} \
188+ ${concatStringsSep " \\\n " cfg.extraFlags}
189 '';
190 };
191 };
192}
193</programlisting>
194+ </listitem>
195+ <listitem>
196+ <para>
197+ This should already be enough for the postfix exporter.
198+ Additionally one could now add assertions and conditional
199+ default values. This can be done in the
200+ <quote>meta-module</quote> that combines all exporter
201+ definitions and generates the submodules:
202+ <literal>nixpkgs/nixos/modules/services/prometheus/exporters.nix</literal>
203+ </para>
204+ </listitem>
205+ </itemizedlist>
206+ </section>
207+ <section xml:id="module-services-prometheus-exporters-update-exporter-module">
208+ <title>Updating an exporter module</title>
209 <para>
210+ Should an exporter option change at some point, it is possible to
211+ add information about the change to the exporter definition
212+ similar to <literal>nixpkgs/nixos/modules/rename.nix</literal>:
00213 </para>
214+ <programlisting>
000000000215{ config, lib, pkgs, options }:
216217with lib;
···230 # ...
231 };
232 imports = [
233+ # 'services.prometheus.exporters.nginx.telemetryEndpoint' -> 'services.prometheus.exporters.nginx.telemetryPath'
234+ (mkRenamedOptionModule [ "telemetryEndpoint" ] [ "telemetryPath" ])
235236 # removed option 'services.prometheus.exporters.nginx.insecure'
237+ (mkRemovedOptionModule [ "insecure" ] ''
238 This option was replaced by 'prometheus.exporters.nginx.sslVerify' which defaults to true.
239 '')
240 ({ options.warnings = options.warnings; })
241 ];
242}
243</programlisting>
0244 </section>
245</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-firefox-syncserver">
4 <title>Firefox Sync server</title>
5 <para>
-2
nixos/modules/services/networking/mosquitto.nix
···671672 meta = {
673 maintainers = with lib.maintainers; [ pennae ];
674- # Don't edit the docbook xml directly, edit the md and generate it:
675- # `pandoc mosquitto.md -t docbook --top-level-division=chapter --extract-media=media -f markdown+smart > mosquitto.xml`
676 doc = ./mosquitto.xml;
677 };
678}
···671672 meta = {
673 maintainers = with lib.maintainers; [ pennae ];
00674 doc = ./mosquitto.xml;
675 };
676}
+5-3
nixos/modules/services/networking/mosquitto.xml
···001<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-mosquitto">
2 <title>Mosquitto</title>
3 <para>
···9 <para>
10 A minimal configuration for Mosquitto is
11 </para>
12- <programlisting language="bash">
13services.mosquitto = {
14 enable = true;
15 listeners = [ {
···31 restricted write access to a user <literal>service</literal> could
32 look like
33 </para>
34- <programlisting language="bash">
35services.mosquitto = {
36 enable = true;
37 listeners = [ {
···52 TLS authentication is configured by setting TLS-related options of
53 the listener:
54 </para>
55- <programlisting language="bash">
56services.mosquitto = {
57 enable = true;
58 listeners = [ {
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-mosquitto">
4 <title>Mosquitto</title>
5 <para>
···11 <para>
12 A minimal configuration for Mosquitto is
13 </para>
14+ <programlisting language="nix">
15services.mosquitto = {
16 enable = true;
17 listeners = [ {
···33 restricted write access to a user <literal>service</literal> could
34 look like
35 </para>
36+ <programlisting language="nix">
37services.mosquitto = {
38 enable = true;
39 listeners = [ {
···54 TLS authentication is configured by setting TLS-related options of
55 the listener:
56 </para>
57+ <programlisting language="nix">
58services.mosquitto = {
59 enable = true;
60 listeners = [ {
···1+# Pleroma {#module-services-pleroma}
2+3+[Pleroma](https://pleroma.social/) is a lightweight activity pub server.
4+5+## Generating the Pleroma config {#module-services-pleroma-generate-config}
6+7+The `pleroma_ctl` CLI utility will prompt you some questions and it will generate an initial config file. This is an example of usage
8+```ShellSession
9+$ mkdir tmp-pleroma
10+$ cd tmp-pleroma
11+$ nix-shell -p pleroma-otp
12+$ pleroma_ctl instance gen --output config.exs --output-psql setup.psql
13+```
14+15+The `config.exs` file can be further customized following the instructions on the [upstream documentation](https://docs-develop.pleroma.social/backend/configuration/cheatsheet/). Many refinements can be applied also after the service is running.
16+17+## Initializing the database {#module-services-pleroma-initialize-db}
18+19+First, the Postgresql service must be enabled in the NixOS configuration
20+```
21+services.postgresql = {
22+ enable = true;
23+ package = pkgs.postgresql_13;
24+};
25+```
26+and activated with the usual
27+```ShellSession
28+$ nixos-rebuild switch
29+```
30+31+Then you can create and seed the database, using the `setup.psql` file that you generated in the previous section, by running
32+```ShellSession
33+$ sudo -u postgres psql -f setup.psql
34+```
35+36+## Enabling the Pleroma service locally {#module-services-pleroma-enable}
37+38+In this section we will enable the Pleroma service only locally, so its configurations can be improved incrementally.
39+40+This is an example of configuration, where [](#opt-services.pleroma.configs) option contains the content of the file `config.exs`, generated [in the first section](#module-services-pleroma-generate-config), but with the secrets (database password, endpoint secret key, salts, etc.) removed. Removing secrets is important, because otherwise they will be stored publicly in the Nix store.
41+```
42+services.pleroma = {
43+ enable = true;
44+ secretConfigFile = "/var/lib/pleroma/secrets.exs";
45+ configs = [
46+ ''
47+ import Config
48+49+ config :pleroma, Pleroma.Web.Endpoint,
50+ url: [host: "pleroma.example.net", scheme: "https", port: 443],
51+ http: [ip: {127, 0, 0, 1}, port: 4000]
52+53+ config :pleroma, :instance,
54+ name: "Test",
55+ email: "admin@example.net",
56+ notify_email: "admin@example.net",
57+ limit: 5000,
58+ registrations_open: true
59+60+ config :pleroma, :media_proxy,
61+ enabled: false,
62+ redirect_on_failure: true
63+64+ config :pleroma, Pleroma.Repo,
65+ adapter: Ecto.Adapters.Postgres,
66+ username: "pleroma",
67+ database: "pleroma",
68+ hostname: "localhost"
69+70+ # Configure web push notifications
71+ config :web_push_encryption, :vapid_details,
72+ subject: "mailto:admin@example.net"
73+74+ # ... TO CONTINUE ...
75+ ''
76+ ];
77+};
78+```
79+80+Secrets must be moved into a file pointed by [](#opt-services.pleroma.secretConfigFile), in our case `/var/lib/pleroma/secrets.exs`. This file can be created copying the previously generated `config.exs` file and then removing all the settings, except the secrets. This is an example
81+```
82+# Pleroma instance passwords
83+84+import Config
85+86+config :pleroma, Pleroma.Web.Endpoint,
87+ secret_key_base: "<the secret generated by pleroma_ctl>",
88+ signing_salt: "<the secret generated by pleroma_ctl>"
89+90+config :pleroma, Pleroma.Repo,
91+ password: "<the secret generated by pleroma_ctl>"
92+93+# Configure web push notifications
94+config :web_push_encryption, :vapid_details,
95+ public_key: "<the secret generated by pleroma_ctl>",
96+ private_key: "<the secret generated by pleroma_ctl>"
97+98+# ... TO CONTINUE ...
99+```
100+Note that the lines of the same configuration group are comma separated (i.e. all the lines end with a comma, except the last one), so when the lines with passwords are added or removed, commas must be adjusted accordingly.
101+102+The service can be enabled with the usual
103+```ShellSession
104+$ nixos-rebuild switch
105+```
106+107+The service is accessible only from the local `127.0.0.1:4000` port. It can be tested using a port forwarding like this
108+```ShellSession
109+$ ssh -L 4000:localhost:4000 myuser@example.net
110+```
111+and then accessing <http://localhost:4000> from a web browser.
112+113+## Creating the admin user {#module-services-pleroma-admin-user}
114+115+After Pleroma service is running, all [Pleroma administration utilities](https://docs-develop.pleroma.social/) can be used. In particular an admin user can be created with
116+```ShellSession
117+$ pleroma_ctl user new <nickname> <email> --admin --moderator --password <password>
118+```
119+120+## Configuring Nginx {#module-services-pleroma-nginx}
121+122+In this configuration, Pleroma is listening only on the local port 4000. Nginx can be configured as a Reverse Proxy, for forwarding requests from public ports to the Pleroma service. This is an example of configuration, using
123+[Let's Encrypt](https://letsencrypt.org/) for the TLS certificates
124+```
125+security.acme = {
126+ email = "root@example.net";
127+ acceptTerms = true;
128+};
129+130+services.nginx = {
131+ enable = true;
132+ addSSL = true;
133+134+ recommendedTlsSettings = true;
135+ recommendedOptimisation = true;
136+ recommendedGzipSettings = true;
137+138+ recommendedProxySettings = false;
139+ # NOTE: if enabled, the NixOS proxy optimizations will override the Pleroma
140+ # specific settings, and they will enter in conflict.
141+142+ virtualHosts = {
143+ "pleroma.example.net" = {
144+ http2 = true;
145+ enableACME = true;
146+ forceSSL = true;
147+148+ locations."/" = {
149+ proxyPass = "http://127.0.0.1:4000";
150+151+ extraConfig = ''
152+ etag on;
153+ gzip on;
154+155+ add_header 'Access-Control-Allow-Origin' '*' always;
156+ add_header 'Access-Control-Allow-Methods' 'POST, PUT, DELETE, GET, PATCH, OPTIONS' always;
157+ add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Idempotency-Key' always;
158+ add_header 'Access-Control-Expose-Headers' 'Link, X-RateLimit-Reset, X-RateLimit-Limit, X-RateLimit-Remaining, X-Request-Id' always;
159+ if ($request_method = OPTIONS) {
160+ return 204;
161+ }
162+ add_header X-XSS-Protection "1; mode=block";
163+ add_header X-Permitted-Cross-Domain-Policies none;
164+ add_header X-Frame-Options DENY;
165+ add_header X-Content-Type-Options nosniff;
166+ add_header Referrer-Policy same-origin;
167+ add_header X-Download-Options noopen;
168+ proxy_http_version 1.1;
169+ proxy_set_header Upgrade $http_upgrade;
170+ proxy_set_header Connection "upgrade";
171+ proxy_set_header Host $host;
172+173+ client_max_body_size 16m;
174+ # NOTE: increase if users need to upload very big files
175+ '';
176+ };
177+ };
178+ };
179+};
180+```
+141-85
nixos/modules/services/networking/pleroma.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-pleroma">
6- <title>Pleroma</title>
7- <para>
8- <link xlink:href="https://pleroma.social/">Pleroma</link> is a lightweight activity pub server.</para>
9- <section xml:id="module-services-pleroma-generate-config">
10- <title>Generating the Pleroma config</title>
11- <para>The <literal>pleroma_ctl</literal> CLI utility will prompt you some questions and it will generate an initial config file. This is an example of usage
12-<programlisting>
13-<prompt>$ </prompt>mkdir tmp-pleroma
14-<prompt>$ </prompt>cd tmp-pleroma
15-<prompt>$ </prompt>nix-shell -p pleroma-otp
16-<prompt>$ </prompt>pleroma_ctl instance gen --output config.exs --output-psql setup.psql
000017</programlisting>
18- </para>
19- <para>The <literal>config.exs</literal> file can be further customized following the instructions on the <link xlink:href="https://docs-develop.pleroma.social/backend/configuration/cheatsheet/">upstream documentation</link>. Many refinements can be applied also after the service is running.</para>
20- </section>
21- <section xml:id="module-services-pleroma-initialize-db">
22- <title>Initializing the database</title>
23- <para>First, the Postgresql service must be enabled in the NixOS configuration
24-<programlisting>
0000000025services.postgresql = {
26 enable = true;
27 package = pkgs.postgresql_13;
28};
29</programlisting>
30-and activated with the usual
31-<programlisting>
32-<prompt>$ </prompt>nixos-rebuild switch
0033</programlisting>
34- </para>
35- <para>Then you can create and seed the database, using the <literal>setup.psql</literal> file that you generated in the previous section, by running
36-<programlisting>
37-<prompt>$ </prompt>sudo -u postgres psql -f setup.psql
00038</programlisting>
39- </para>
40- </section>
41- <section xml:id="module-services-pleroma-enable">
42- <title>Enabling the Pleroma service locally</title>
43- <para>In this section we will enable the Pleroma service only locally, so its configurations can be improved incrementally.</para>
44- <para>This is an example of configuration, where <link linkend="opt-services.pleroma.configs">services.pleroma.configs</link> option contains the content of the file <literal>config.exs</literal>, generated <link linkend="module-services-pleroma-generate-config">in the first section</link>, but with the secrets (database password, endpoint secret key, salts, etc.) removed. Removing secrets is important, because otherwise they will be stored publicly in the Nix store.
45-<programlisting>
0000000000046services.pleroma = {
47 enable = true;
48- secretConfigFile = "/var/lib/pleroma/secrets.exs";
49 configs = [
50 ''
51 import Config
5253 config :pleroma, Pleroma.Web.Endpoint,
54- url: [host: "pleroma.example.net", scheme: "https", port: 443],
55 http: [ip: {127, 0, 0, 1}, port: 4000]
5657 config :pleroma, :instance,
58- name: "Test",
59- email: "admin@example.net",
60- notify_email: "admin@example.net",
61 limit: 5000,
62 registrations_open: true
63···6768 config :pleroma, Pleroma.Repo,
69 adapter: Ecto.Adapters.Postgres,
70- username: "pleroma",
71- database: "pleroma",
72- hostname: "localhost"
7374 # Configure web push notifications
75 config :web_push_encryption, :vapid_details,
76- subject: "mailto:admin@example.net"
7778 # ... TO CONTINUE ...
79 ''
80 ];
81};
82</programlisting>
83- </para>
84- <para>Secrets must be moved into a file pointed by <link linkend="opt-services.pleroma.secretConfigFile">services.pleroma.secretConfigFile</link>, in our case <literal>/var/lib/pleroma/secrets.exs</literal>. This file can be created copying the previously generated <literal>config.exs</literal> file and then removing all the settings, except the secrets. This is an example
85-<programlisting>
00000086# Pleroma instance passwords
8788import Config
8990config :pleroma, Pleroma.Web.Endpoint,
91- secret_key_base: "<the secret generated by pleroma_ctl>",
92- signing_salt: "<the secret generated by pleroma_ctl>"
9394config :pleroma, Pleroma.Repo,
95- password: "<the secret generated by pleroma_ctl>"
9697# Configure web push notifications
98config :web_push_encryption, :vapid_details,
99- public_key: "<the secret generated by pleroma_ctl>",
100- private_key: "<the secret generated by pleroma_ctl>"
101102# ... TO CONTINUE ...
103</programlisting>
104- Note that the lines of the same configuration group are comma separated (i.e. all the lines end with a comma, except the last one), so when the lines with passwords are added or removed, commas must be adjusted accordingly.</para>
105-106- <para>The service can be enabled with the usual
107-<programlisting>
108-<prompt>$ </prompt>nixos-rebuild switch
000000109</programlisting>
110- </para>
111- <para>The service is accessible only from the local <literal>127.0.0.1:4000</literal> port. It can be tested using a port forwarding like this
112-<programlisting>
113-<prompt>$ </prompt>ssh -L 4000:localhost:4000 myuser@example.net
000114</programlisting>
115-and then accessing <link xlink:href="http://localhost:4000">http://localhost:4000</link> from a web browser.</para>
116- </section>
117- <section xml:id="module-services-pleroma-admin-user">
118- <title>Creating the admin user</title>
119- <para>After Pleroma service is running, all <link xlink:href="https://docs-develop.pleroma.social/">Pleroma administration utilities</link> can be used. In particular an admin user can be created with
120-<programlisting>
121-<prompt>$ </prompt>pleroma_ctl user new <nickname> <email> --admin --moderator --password <password>
000000000122</programlisting>
123- </para>
124- </section>
125- <section xml:id="module-services-pleroma-nginx">
126- <title>Configuring Nginx</title>
127- <para>In this configuration, Pleroma is listening only on the local port 4000. Nginx can be configured as a Reverse Proxy, for forwarding requests from public ports to the Pleroma service. This is an example of configuration, using
128-<link xlink:href="https://letsencrypt.org/">Let's Encrypt</link> for the TLS certificates
129-<programlisting>
00000130security.acme = {
131- email = "root@example.net";
132 acceptTerms = true;
133};
134···145 # specific settings, and they will enter in conflict.
146147 virtualHosts = {
148- "pleroma.example.net" = {
149 http2 = true;
150 enableACME = true;
151 forceSSL = true;
152153- locations."/" = {
154- proxyPass = "http://127.0.0.1:4000";
155156 extraConfig = ''
157 etag on;
···164 if ($request_method = OPTIONS) {
165 return 204;
166 }
167- add_header X-XSS-Protection "1; mode=block";
168 add_header X-Permitted-Cross-Domain-Policies none;
169 add_header X-Frame-Options DENY;
170 add_header X-Content-Type-Options nosniff;
···172 add_header X-Download-Options noopen;
173 proxy_http_version 1.1;
174 proxy_set_header Upgrade $http_upgrade;
175- proxy_set_header Connection "upgrade";
176 proxy_set_header Host $host;
177178 client_max_body_size 16m;
···183 };
184};
185</programlisting>
186- </para>
187- </section>
188</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-pleroma">
4+ <title>Pleroma</title>
5+ <para>
6+ <link xlink:href="https://pleroma.social/">Pleroma</link> is a
7+ lightweight activity pub server.
8+ </para>
9+ <section xml:id="module-services-pleroma-generate-config">
10+ <title>Generating the Pleroma config</title>
11+ <para>
12+ The <literal>pleroma_ctl</literal> CLI utility will prompt you
13+ some questions and it will generate an initial config file. This
14+ is an example of usage
15+ </para>
16+ <programlisting>
17+$ mkdir tmp-pleroma
18+$ cd tmp-pleroma
19+$ nix-shell -p pleroma-otp
20+$ pleroma_ctl instance gen --output config.exs --output-psql setup.psql
21</programlisting>
22+ <para>
23+ The <literal>config.exs</literal> file can be further customized
24+ following the instructions on the
25+ <link xlink:href="https://docs-develop.pleroma.social/backend/configuration/cheatsheet/">upstream
26+ documentation</link>. Many refinements can be applied also after
27+ the service is running.
28+ </para>
29+ </section>
30+ <section xml:id="module-services-pleroma-initialize-db">
31+ <title>Initializing the database</title>
32+ <para>
33+ First, the Postgresql service must be enabled in the NixOS
34+ configuration
35+ </para>
36+ <programlisting>
37services.postgresql = {
38 enable = true;
39 package = pkgs.postgresql_13;
40};
41</programlisting>
42+ <para>
43+ and activated with the usual
44+ </para>
45+ <programlisting>
46+$ nixos-rebuild switch
47</programlisting>
48+ <para>
49+ Then you can create and seed the database, using the
50+ <literal>setup.psql</literal> file that you generated in the
51+ previous section, by running
52+ </para>
53+ <programlisting>
54+$ sudo -u postgres psql -f setup.psql
55</programlisting>
56+ </section>
57+ <section xml:id="module-services-pleroma-enable">
58+ <title>Enabling the Pleroma service locally</title>
59+ <para>
60+ In this section we will enable the Pleroma service only locally,
61+ so its configurations can be improved incrementally.
62+ </para>
63+ <para>
64+ This is an example of configuration, where
65+ <xref linkend="opt-services.pleroma.configs" /> option contains
66+ the content of the file <literal>config.exs</literal>, generated
67+ <link linkend="module-services-pleroma-generate-config">in the
68+ first section</link>, but with the secrets (database password,
69+ endpoint secret key, salts, etc.) removed. Removing secrets is
70+ important, because otherwise they will be stored publicly in the
71+ Nix store.
72+ </para>
73+ <programlisting>
74services.pleroma = {
75 enable = true;
76+ secretConfigFile = "/var/lib/pleroma/secrets.exs";
77 configs = [
78 ''
79 import Config
8081 config :pleroma, Pleroma.Web.Endpoint,
82+ url: [host: "pleroma.example.net", scheme: "https", port: 443],
83 http: [ip: {127, 0, 0, 1}, port: 4000]
8485 config :pleroma, :instance,
86+ name: "Test",
87+ email: "admin@example.net",
88+ notify_email: "admin@example.net",
89 limit: 5000,
90 registrations_open: true
91···9596 config :pleroma, Pleroma.Repo,
97 adapter: Ecto.Adapters.Postgres,
98+ username: "pleroma",
99+ database: "pleroma",
100+ hostname: "localhost"
101102 # Configure web push notifications
103 config :web_push_encryption, :vapid_details,
104+ subject: "mailto:admin@example.net"
105106 # ... TO CONTINUE ...
107 ''
108 ];
109};
110</programlisting>
111+ <para>
112+ Secrets must be moved into a file pointed by
113+ <xref linkend="opt-services.pleroma.secretConfigFile" />, in our
114+ case <literal>/var/lib/pleroma/secrets.exs</literal>. This file
115+ can be created copying the previously generated
116+ <literal>config.exs</literal> file and then removing all the
117+ settings, except the secrets. This is an example
118+ </para>
119+ <programlisting>
120# Pleroma instance passwords
121122import Config
123124config :pleroma, Pleroma.Web.Endpoint,
125+ secret_key_base: "<the secret generated by pleroma_ctl>",
126+ signing_salt: "<the secret generated by pleroma_ctl>"
127128config :pleroma, Pleroma.Repo,
129+ password: "<the secret generated by pleroma_ctl>"
130131# Configure web push notifications
132config :web_push_encryption, :vapid_details,
133+ public_key: "<the secret generated by pleroma_ctl>",
134+ private_key: "<the secret generated by pleroma_ctl>"
135136# ... TO CONTINUE ...
137</programlisting>
138+ <para>
139+ Note that the lines of the same configuration group are comma
140+ separated (i.e. all the lines end with a comma, except the last
141+ one), so when the lines with passwords are added or removed,
142+ commas must be adjusted accordingly.
143+ </para>
144+ <para>
145+ The service can be enabled with the usual
146+ </para>
147+ <programlisting>
148+$ nixos-rebuild switch
149</programlisting>
150+ <para>
151+ The service is accessible only from the local
152+ <literal>127.0.0.1:4000</literal> port. It can be tested using a
153+ port forwarding like this
154+ </para>
155+ <programlisting>
156+$ ssh -L 4000:localhost:4000 myuser@example.net
157</programlisting>
158+ <para>
159+ and then accessing
160+ <link xlink:href="http://localhost:4000">http://localhost:4000</link>
161+ from a web browser.
162+ </para>
163+ </section>
164+ <section xml:id="module-services-pleroma-admin-user">
165+ <title>Creating the admin user</title>
166+ <para>
167+ After Pleroma service is running, all
168+ <link xlink:href="https://docs-develop.pleroma.social/">Pleroma
169+ administration utilities</link> can be used. In particular an
170+ admin user can be created with
171+ </para>
172+ <programlisting>
173+$ pleroma_ctl user new <nickname> <email> --admin --moderator --password <password>
174</programlisting>
175+ </section>
176+ <section xml:id="module-services-pleroma-nginx">
177+ <title>Configuring Nginx</title>
178+ <para>
179+ In this configuration, Pleroma is listening only on the local port
180+ 4000. Nginx can be configured as a Reverse Proxy, for forwarding
181+ requests from public ports to the Pleroma service. This is an
182+ example of configuration, using
183+ <link xlink:href="https://letsencrypt.org/">Let’s Encrypt</link>
184+ for the TLS certificates
185+ </para>
186+ <programlisting>
187security.acme = {
188+ email = "root@example.net";
189 acceptTerms = true;
190};
191···202 # specific settings, and they will enter in conflict.
203204 virtualHosts = {
205+ "pleroma.example.net" = {
206 http2 = true;
207 enableACME = true;
208 forceSSL = true;
209210+ locations."/" = {
211+ proxyPass = "http://127.0.0.1:4000";
212213 extraConfig = ''
214 etag on;
···221 if ($request_method = OPTIONS) {
222 return 204;
223 }
224+ add_header X-XSS-Protection "1; mode=block";
225 add_header X-Permitted-Cross-Domain-Policies none;
226 add_header X-Frame-Options DENY;
227 add_header X-Content-Type-Options nosniff;
···229 add_header X-Download-Options noopen;
230 proxy_http_version 1.1;
231 proxy_set_header Upgrade $http_upgrade;
232+ proxy_set_header Connection "upgrade";
233 proxy_set_header Host $host;
234235 client_max_body_size 16m;
···240 };
241};
242</programlisting>
243+ </section>
0244</chapter>
···1+# Prosody {#module-services-prosody}
2+3+[Prosody](https://prosody.im/) is an open-source, modern XMPP server.
4+5+## Basic usage {#module-services-prosody-basic-usage}
6+7+A common struggle for most XMPP newcomers is to find the right set
8+of XMPP Extensions (XEPs) to setup. Forget to activate a few of
9+those and your XMPP experience might turn into a nightmare!
10+11+The XMPP community tackles this problem by creating a meta-XEP
12+listing a decent set of XEPs you should implement. This meta-XEP
13+is issued every year, the 2020 edition being
14+[XEP-0423](https://xmpp.org/extensions/xep-0423.html).
15+16+The NixOS Prosody module will implement most of these recommendend XEPs out of
17+the box. That being said, two components still require some
18+manual configuration: the
19+[Multi User Chat (MUC)](https://xmpp.org/extensions/xep-0045.html)
20+and the [HTTP File Upload](https://xmpp.org/extensions/xep-0363.html) ones.
21+You'll need to create a DNS subdomain for each of those. The current convention is to name your
22+MUC endpoint `conference.example.org` and your HTTP upload domain `upload.example.org`.
23+24+A good configuration to start with, including a
25+[Multi User Chat (MUC)](https://xmpp.org/extensions/xep-0045.html)
26+endpoint as well as a [HTTP File Upload](https://xmpp.org/extensions/xep-0363.html)
27+endpoint will look like this:
28+```
29+services.prosody = {
30+ enable = true;
31+ admins = [ "root@example.org" ];
32+ ssl.cert = "/var/lib/acme/example.org/fullchain.pem";
33+ ssl.key = "/var/lib/acme/example.org/key.pem";
34+ virtualHosts."example.org" = {
35+ enabled = true;
36+ domain = "example.org";
37+ ssl.cert = "/var/lib/acme/example.org/fullchain.pem";
38+ ssl.key = "/var/lib/acme/example.org/key.pem";
39+ };
40+ muc = [ {
41+ domain = "conference.example.org";
42+ } ];
43+ uploadHttp = {
44+ domain = "upload.example.org";
45+ };
46+};
47+```
48+49+## Let's Encrypt Configuration {#module-services-prosody-letsencrypt}
50+51+As you can see in the code snippet from the
52+[previous section](#module-services-prosody-basic-usage),
53+you'll need a single TLS certificate covering your main endpoint,
54+the MUC one as well as the HTTP Upload one. We can generate such a
55+certificate by leveraging the ACME
56+[extraDomainNames](#opt-security.acme.certs._name_.extraDomainNames) module option.
57+58+Provided the setup detailed in the previous section, you'll need the following acme configuration to generate
59+a TLS certificate for the three endponits:
60+```
61+security.acme = {
62+ email = "root@example.org";
63+ acceptTerms = true;
64+ certs = {
65+ "example.org" = {
66+ webroot = "/var/www/example.org";
67+ email = "root@example.org";
68+ extraDomainNames = [ "conference.example.org" "upload.example.org" ];
69+ };
70+ };
71+};
72+```
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-prosody">
6- <title>Prosody</title>
7- <para>
8- <link xlink:href="https://prosody.im/">Prosody</link> is an open-source, modern XMPP server.
9- </para>
10- <section xml:id="module-services-prosody-basic-usage">
11- <title>Basic usage</title>
12-13 <para>
14- A common struggle for most XMPP newcomers is to find the right set
15- of XMPP Extensions (XEPs) to setup. Forget to activate a few of
16- those and your XMPP experience might turn into a nightmare!
17 </para>
18-19- <para>
20- The XMPP community tackles this problem by creating a meta-XEP
21- listing a decent set of XEPs you should implement. This meta-XEP
22- is issued every year, the 2020 edition being
23- <link xlink:href="https://xmpp.org/extensions/xep-0423.html">XEP-0423</link>.
24- </para>
25- <para>
26- The NixOS Prosody module will implement most of these recommendend XEPs out of
27- the box. That being said, two components still require some
28- manual configuration: the
29- <link xlink:href="https://xmpp.org/extensions/xep-0045.html">Multi User Chat (MUC)</link>
30- and the <link xlink:href="https://xmpp.org/extensions/xep-0363.html">HTTP File Upload</link> ones.
31- You'll need to create a DNS subdomain for each of those. The current convention is to name your
32- MUC endpoint <literal>conference.example.org</literal> and your HTTP upload domain <literal>upload.example.org</literal>.
33- </para>
34- <para>
35- A good configuration to start with, including a
36- <link xlink:href="https://xmpp.org/extensions/xep-0045.html">Multi User Chat (MUC)</link>
37- endpoint as well as a <link xlink:href="https://xmpp.org/extensions/xep-0363.html">HTTP File Upload</link>
38- endpoint will look like this:
0000000000039 <programlisting>
40services.prosody = {
41- <link linkend="opt-services.prosody.enable">enable</link> = true;
42- <link linkend="opt-services.prosody.admins">admins</link> = [ "root@example.org" ];
43- <link linkend="opt-services.prosody.ssl.cert">ssl.cert</link> = "/var/lib/acme/example.org/fullchain.pem";
44- <link linkend="opt-services.prosody.ssl.key">ssl.key</link> = "/var/lib/acme/example.org/key.pem";
45- <link linkend="opt-services.prosody.virtualHosts">virtualHosts</link>."example.org" = {
46- <link linkend="opt-services.prosody.virtualHosts._name_.enabled">enabled</link> = true;
47- <link linkend="opt-services.prosody.virtualHosts._name_.domain">domain</link> = "example.org";
48- <link linkend="opt-services.prosody.virtualHosts._name_.ssl.cert">ssl.cert</link> = "/var/lib/acme/example.org/fullchain.pem";
49- <link linkend="opt-services.prosody.virtualHosts._name_.ssl.key">ssl.key</link> = "/var/lib/acme/example.org/key.pem";
50 };
51- <link linkend="opt-services.prosody.muc">muc</link> = [ {
52- <link linkend="opt-services.prosody.muc">domain</link> = "conference.example.org";
53 } ];
54- <link linkend="opt-services.prosody.uploadHttp">uploadHttp</link> = {
55- <link linkend="opt-services.prosody.uploadHttp.domain">domain</link> = "upload.example.org";
56 };
57-};</programlisting>
58- </para>
59- </section>
60- <section xml:id="module-services-prosody-letsencrypt">
61- <title>Let's Encrypt Configuration</title>
62- <para>
63- As you can see in the code snippet from the
64- <link linkend="module-services-prosody-basic-usage">previous section</link>,
65- you'll need a single TLS certificate covering your main endpoint,
66- the MUC one as well as the HTTP Upload one. We can generate such a
67- certificate by leveraging the ACME
68- <link linkend="opt-security.acme.certs._name_.extraDomainNames">extraDomainNames</link> module option.
69- </para>
70- <para>
71- Provided the setup detailed in the previous section, you'll need the following acme configuration to generate
72- a TLS certificate for the three endponits:
00073 <programlisting>
74security.acme = {
75- <link linkend="opt-security.acme.defaults.email">email</link> = "root@example.org";
76- <link linkend="opt-security.acme.acceptTerms">acceptTerms</link> = true;
77- <link linkend="opt-security.acme.certs">certs</link> = {
78- "example.org" = {
79- <link linkend="opt-security.acme.certs._name_.webroot">webroot</link> = "/var/www/example.org";
80- <link linkend="opt-security.acme.certs._name_.email">email</link> = "root@example.org";
81- <link linkend="opt-security.acme.certs._name_.extraDomainNames">extraDomainNames</link> = [ "conference.example.org" "upload.example.org" ];
82 };
83 };
84-};</programlisting>
85- </para>
86-</section>
87</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-prosody">
4+ <title>Prosody</title>
000000005 <para>
6+ <link xlink:href="https://prosody.im/">Prosody</link> is an
7+ open-source, modern XMPP server.
08 </para>
9+ <section xml:id="module-services-prosody-basic-usage">
10+ <title>Basic usage</title>
11+ <para>
12+ A common struggle for most XMPP newcomers is to find the right set
13+ of XMPP Extensions (XEPs) to setup. Forget to activate a few of
14+ those and your XMPP experience might turn into a nightmare!
15+ </para>
16+ <para>
17+ The XMPP community tackles this problem by creating a meta-XEP
18+ listing a decent set of XEPs you should implement. This meta-XEP
19+ is issued every year, the 2020 edition being
20+ <link xlink:href="https://xmpp.org/extensions/xep-0423.html">XEP-0423</link>.
21+ </para>
22+ <para>
23+ The NixOS Prosody module will implement most of these recommendend
24+ XEPs out of the box. That being said, two components still require
25+ some manual configuration: the
26+ <link xlink:href="https://xmpp.org/extensions/xep-0045.html">Multi
27+ User Chat (MUC)</link> and the
28+ <link xlink:href="https://xmpp.org/extensions/xep-0363.html">HTTP
29+ File Upload</link> ones. You’ll need to create a DNS subdomain for
30+ each of those. The current convention is to name your MUC endpoint
31+ <literal>conference.example.org</literal> and your HTTP upload
32+ domain <literal>upload.example.org</literal>.
33+ </para>
34+ <para>
35+ A good configuration to start with, including a
36+ <link xlink:href="https://xmpp.org/extensions/xep-0045.html">Multi
37+ User Chat (MUC)</link> endpoint as well as a
38+ <link xlink:href="https://xmpp.org/extensions/xep-0363.html">HTTP
39+ File Upload</link> endpoint will look like this:
40+ </para>
41 <programlisting>
42services.prosody = {
43+ enable = true;
44+ admins = [ "root@example.org" ];
45+ ssl.cert = "/var/lib/acme/example.org/fullchain.pem";
46+ ssl.key = "/var/lib/acme/example.org/key.pem";
47+ virtualHosts."example.org" = {
48+ enabled = true;
49+ domain = "example.org";
50+ ssl.cert = "/var/lib/acme/example.org/fullchain.pem";
51+ ssl.key = "/var/lib/acme/example.org/key.pem";
52 };
53+ muc = [ {
54+ domain = "conference.example.org";
55 } ];
56+ uploadHttp = {
57+ domain = "upload.example.org";
58 };
59+};
60+</programlisting>
61+ </section>
62+ <section xml:id="module-services-prosody-letsencrypt">
63+ <title>Let’s Encrypt Configuration</title>
64+ <para>
65+ As you can see in the code snippet from the
66+ <link linkend="module-services-prosody-basic-usage">previous
67+ section</link>, you’ll need a single TLS certificate covering your
68+ main endpoint, the MUC one as well as the HTTP Upload one. We can
69+ generate such a certificate by leveraging the ACME
70+ <link linkend="opt-security.acme.certs._name_.extraDomainNames">extraDomainNames</link>
71+ module option.
72+ </para>
73+ <para>
74+ Provided the setup detailed in the previous section, you’ll need
75+ the following acme configuration to generate a TLS certificate for
76+ the three endponits:
77+ </para>
78 <programlisting>
79security.acme = {
80+ email = "root@example.org";
81+ acceptTerms = true;
82+ certs = {
83+ "example.org" = {
84+ webroot = "/var/www/example.org";
85+ email = "root@example.org";
86+ extraDomainNames = [ "conference.example.org" "upload.example.org" ];
87 };
88 };
89+};
90+</programlisting>
91+ </section>
92</chapter>
···1+# Yggdrasil {#module-services-networking-yggdrasil}
2+3+*Source:* {file}`modules/services/networking/yggdrasil/default.nix`
4+5+*Upstream documentation:* <https://yggdrasil-network.github.io/>
6+7+Yggdrasil is an early-stage implementation of a fully end-to-end encrypted,
8+self-arranging IPv6 network.
9+10+## Configuration {#module-services-networking-yggdrasil-configuration}
11+12+### Simple ephemeral node {#module-services-networking-yggdrasil-configuration-simple}
13+14+An annotated example of a simple configuration:
15+```
16+{
17+ services.yggdrasil = {
18+ enable = true;
19+ persistentKeys = false;
20+ # The NixOS module will generate new keys and a new IPv6 address each time
21+ # it is started if persistentKeys is not enabled.
22+23+ settings = {
24+ Peers = [
25+ # Yggdrasil will automatically connect and "peer" with other nodes it
26+ # discovers via link-local multicast announcements. Unless this is the
27+ # case (it probably isn't) a node needs peers within the existing
28+ # network that it can tunnel to.
29+ "tcp://1.2.3.4:1024"
30+ "tcp://1.2.3.5:1024"
31+ # Public peers can be found at
32+ # https://github.com/yggdrasil-network/public-peers
33+ ];
34+ };
35+ };
36+}
37+```
38+39+### Persistent node with prefix {#module-services-networking-yggdrasil-configuration-prefix}
40+41+A node with a fixed address that announces a prefix:
42+```
43+let
44+ address = "210:5217:69c0:9afc:1b95:b9f:8718:c3d2";
45+ prefix = "310:5217:69c0:9afc";
46+ # taken from the output of "yggdrasilctl getself".
47+in {
48+49+ services.yggdrasil = {
50+ enable = true;
51+ persistentKeys = true; # Maintain a fixed public key and IPv6 address.
52+ settings = {
53+ Peers = [ "tcp://1.2.3.4:1024" "tcp://1.2.3.5:1024" ];
54+ NodeInfo = {
55+ # This information is visible to the network.
56+ name = config.networking.hostName;
57+ location = "The North Pole";
58+ };
59+ };
60+ };
61+62+ boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1;
63+ # Forward traffic under the prefix.
64+65+ networking.interfaces.${eth0}.ipv6.addresses = [{
66+ # Set a 300::/8 address on the local physical device.
67+ address = prefix + "::1";
68+ prefixLength = 64;
69+ }];
70+71+ services.radvd = {
72+ # Announce the 300::/8 prefix to eth0.
73+ enable = true;
74+ config = ''
75+ interface eth0
76+ {
77+ AdvSendAdvert on;
78+ prefix ${prefix}::/64 {
79+ AdvOnLink on;
80+ AdvAutonomous on;
81+ };
82+ route 200::/8 {};
83+ };
84+ '';
85+ };
86+}
87+```
88+89+### Yggdrasil attached Container {#module-services-networking-yggdrasil-configuration-container}
90+91+A NixOS container attached to the Yggdrasil network via a node running on the
92+host:
93+```
94+let
95+ yggPrefix64 = "310:5217:69c0:9afc";
96+ # Again, taken from the output of "yggdrasilctl getself".
97+in
98+{
99+ boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1;
100+ # Enable IPv6 forwarding.
101+102+ networking = {
103+ bridges.br0.interfaces = [ ];
104+ # A bridge only to containers…
105+106+ interfaces.br0 = {
107+ # … configured with a prefix address.
108+ ipv6.addresses = [{
109+ address = "${yggPrefix64}::1";
110+ prefixLength = 64;
111+ }];
112+ };
113+ };
114+115+ containers.foo = {
116+ autoStart = true;
117+ privateNetwork = true;
118+ hostBridge = "br0";
119+ # Attach the container to the bridge only.
120+ config = { config, pkgs, ... }: {
121+ networking.interfaces.eth0.ipv6 = {
122+ addresses = [{
123+ # Configure a prefix address.
124+ address = "${yggPrefix64}::2";
125+ prefixLength = 64;
126+ }];
127+ routes = [{
128+ # Configure the prefix route.
129+ address = "200::";
130+ prefixLength = 7;
131+ via = "${yggPrefix64}::1";
132+ }];
133+ };
134+135+ services.httpd.enable = true;
136+ networking.firewall.allowedTCPPorts = [ 80 ];
137+ };
138+ };
139+140+}
141+```
+37-36
nixos/modules/services/networking/yggdrasil.xml
···1-<?xml version="1.0"?>
2-<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude" version="5.0" xml:id="module-services-networking-yggdrasil">
03 <title>Yggdrasil</title>
4 <para>
5 <emphasis>Source:</emphasis>
···7 </para>
8 <para>
9 <emphasis>Upstream documentation:</emphasis>
10- <link xlink:href="https://yggdrasil-network.github.io/"/>
11 </para>
12 <para>
13-Yggdrasil is an early-stage implementation of a fully end-to-end encrypted,
14-self-arranging IPv6 network.
15-</para>
16 <section xml:id="module-services-networking-yggdrasil-configuration">
17 <title>Configuration</title>
18 <section xml:id="module-services-networking-yggdrasil-configuration-simple">
19 <title>Simple ephemeral node</title>
20 <para>
21-An annotated example of a simple configuration:
22-<programlisting>
023{
24 services.yggdrasil = {
25 enable = true;
···2930 settings = {
31 Peers = [
32- # Yggdrasil will automatically connect and "peer" with other nodes it
33 # discovers via link-local multicast announcements. Unless this is the
34 # case (it probably isn't) a node needs peers within the existing
35 # network that it can tunnel to.
36- "tcp://1.2.3.4:1024"
37- "tcp://1.2.3.5:1024"
38 # Public peers can be found at
39 # https://github.com/yggdrasil-network/public-peers
40 ];
···42 };
43}
44</programlisting>
45- </para>
46 </section>
47 <section xml:id="module-services-networking-yggdrasil-configuration-prefix">
48 <title>Persistent node with prefix</title>
49 <para>
50-A node with a fixed address that announces a prefix:
51-<programlisting>
052let
53- address = "210:5217:69c0:9afc:1b95:b9f:8718:c3d2";
54- prefix = "310:5217:69c0:9afc";
55- # taken from the output of "yggdrasilctl getself".
56in {
5758 services.yggdrasil = {
59 enable = true;
60 persistentKeys = true; # Maintain a fixed public key and IPv6 address.
61 settings = {
62- Peers = [ "tcp://1.2.3.4:1024" "tcp://1.2.3.5:1024" ];
63 NodeInfo = {
64 # This information is visible to the network.
65 name = config.networking.hostName;
66- location = "The North Pole";
67 };
68 };
69 };
7071- boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1;
72 # Forward traffic under the prefix.
7374 networking.interfaces.${eth0}.ipv6.addresses = [{
75 # Set a 300::/8 address on the local physical device.
76- address = prefix + "::1";
77 prefixLength = 64;
78 }];
79···94 };
95}
96</programlisting>
97- </para>
98 </section>
99 <section xml:id="module-services-networking-yggdrasil-configuration-container">
100 <title>Yggdrasil attached Container</title>
101 <para>
102-A NixOS container attached to the Yggdrasil network via a node running on the
103-host:
104- <programlisting>
0105let
106- yggPrefix64 = "310:5217:69c0:9afc";
107- # Again, taken from the output of "yggdrasilctl getself".
108in
109{
110- boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1;
111 # Enable IPv6 forwarding.
112113 networking = {
114 bridges.br0.interfaces = [ ];
115- # A bridge only to containers…
116117 interfaces.br0 = {
118- # … configured with a prefix address.
119 ipv6.addresses = [{
120- address = "${yggPrefix64}::1";
121 prefixLength = 64;
122 }];
123 };
···126 containers.foo = {
127 autoStart = true;
128 privateNetwork = true;
129- hostBridge = "br0";
130 # Attach the container to the bridge only.
131 config = { config, pkgs, ... }: {
132 networking.interfaces.eth0.ipv6 = {
133 addresses = [{
134 # Configure a prefix address.
135- address = "${yggPrefix64}::2";
136 prefixLength = 64;
137 }];
138 routes = [{
139 # Configure the prefix route.
140- address = "200::";
141 prefixLength = 7;
142- via = "${yggPrefix64}::1";
143 }];
144 };
145···150151}
152</programlisting>
153- </para>
154 </section>
155 </section>
156</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-networking-yggdrasil">
4 <title>Yggdrasil</title>
5 <para>
6 <emphasis>Source:</emphasis>
···8 </para>
9 <para>
10 <emphasis>Upstream documentation:</emphasis>
11+ <link xlink:href="https://yggdrasil-network.github.io/">https://yggdrasil-network.github.io/</link>
12 </para>
13 <para>
14+ Yggdrasil is an early-stage implementation of a fully end-to-end
15+ encrypted, self-arranging IPv6 network.
16+ </para>
17 <section xml:id="module-services-networking-yggdrasil-configuration">
18 <title>Configuration</title>
19 <section xml:id="module-services-networking-yggdrasil-configuration-simple">
20 <title>Simple ephemeral node</title>
21 <para>
22+ An annotated example of a simple configuration:
23+ </para>
24+ <programlisting>
25{
26 services.yggdrasil = {
27 enable = true;
···3132 settings = {
33 Peers = [
34+ # Yggdrasil will automatically connect and "peer" with other nodes it
35 # discovers via link-local multicast announcements. Unless this is the
36 # case (it probably isn't) a node needs peers within the existing
37 # network that it can tunnel to.
38+ "tcp://1.2.3.4:1024"
39+ "tcp://1.2.3.5:1024"
40 # Public peers can be found at
41 # https://github.com/yggdrasil-network/public-peers
42 ];
···44 };
45}
46</programlisting>
047 </section>
48 <section xml:id="module-services-networking-yggdrasil-configuration-prefix">
49 <title>Persistent node with prefix</title>
50 <para>
51+ A node with a fixed address that announces a prefix:
52+ </para>
53+ <programlisting>
54let
55+ address = "210:5217:69c0:9afc:1b95:b9f:8718:c3d2";
56+ prefix = "310:5217:69c0:9afc";
57+ # taken from the output of "yggdrasilctl getself".
58in {
5960 services.yggdrasil = {
61 enable = true;
62 persistentKeys = true; # Maintain a fixed public key and IPv6 address.
63 settings = {
64+ Peers = [ "tcp://1.2.3.4:1024" "tcp://1.2.3.5:1024" ];
65 NodeInfo = {
66 # This information is visible to the network.
67 name = config.networking.hostName;
68+ location = "The North Pole";
69 };
70 };
71 };
7273+ boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1;
74 # Forward traffic under the prefix.
7576 networking.interfaces.${eth0}.ipv6.addresses = [{
77 # Set a 300::/8 address on the local physical device.
78+ address = prefix + "::1";
79 prefixLength = 64;
80 }];
81···96 };
97}
98</programlisting>
099 </section>
100 <section xml:id="module-services-networking-yggdrasil-configuration-container">
101 <title>Yggdrasil attached Container</title>
102 <para>
103+ A NixOS container attached to the Yggdrasil network via a node
104+ running on the host:
105+ </para>
106+ <programlisting>
107let
108+ yggPrefix64 = "310:5217:69c0:9afc";
109+ # Again, taken from the output of "yggdrasilctl getself".
110in
111{
112+ boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1;
113 # Enable IPv6 forwarding.
114115 networking = {
116 bridges.br0.interfaces = [ ];
117+ # A bridge only to containers…
118119 interfaces.br0 = {
120+ # … configured with a prefix address.
121 ipv6.addresses = [{
122+ address = "${yggPrefix64}::1";
123 prefixLength = 64;
124 }];
125 };
···128 containers.foo = {
129 autoStart = true;
130 privateNetwork = true;
131+ hostBridge = "br0";
132 # Attach the container to the bridge only.
133 config = { config, pkgs, ... }: {
134 networking.interfaces.eth0.ipv6 = {
135 addresses = [{
136 # Configure a prefix address.
137+ address = "${yggPrefix64}::2";
138 prefixLength = 64;
139 }];
140 routes = [{
141 # Configure the prefix route.
142+ address = "200::";
143 prefixLength = 7;
144+ via = "${yggPrefix64}::1";
145 }];
146 };
147···152153}
154</programlisting>
0155 </section>
156 </section>
157</chapter>
+6-6
nixos/modules/services/search/meilisearch.md
···23Meilisearch is a lightweight, fast and powerful search engine. Think elastic search with a much smaller footprint.
45-## Quickstart
67the minimum to start meilisearch is
8···1415test with `curl -X GET 'http://localhost:7700/health'`
1617-## Usage
1819you first need to add documents to an index before you can search for documents.
2021-### Add a documents to the `movies` index
2223`curl -X POST 'http://127.0.0.1:7700/indexes/movies/documents' --data '[{"id": "123", "title": "Superman"}, {"id": 234, "title": "Batman"}]'`
2425-### Search documents in the `movies` index
2627`curl 'http://127.0.0.1:7700/indexes/movies/search' --data '{ "q": "botman" }'` (note the typo is intentional and there to demonstrate the typo tolerant capabilities)
2829-## Defaults
3031- The default nixos package doesn't come with the [dashboard](https://docs.meilisearch.com/learn/getting_started/quick_start.html#search), since the dashboard features makes some assets downloads at compile time.
32···3435- Default deployment is development mode. It doesn't require a secret master key. All routes are not protected and accessible.
3637-## Missing
3839- the snapshot feature is not yet configurable from the module, it's just a matter of adding the relevant environment variables.
···23Meilisearch is a lightweight, fast and powerful search engine. Think elastic search with a much smaller footprint.
45+## Quickstart {#module-services-meilisearch-quickstart}
67the minimum to start meilisearch is
8···1415test with `curl -X GET 'http://localhost:7700/health'`
1617+## Usage {#module-services-meilisearch-usage}
1819you first need to add documents to an index before you can search for documents.
2021+### Add a documents to the `movies` index {#module-services-meilisearch-quickstart-add}
2223`curl -X POST 'http://127.0.0.1:7700/indexes/movies/documents' --data '[{"id": "123", "title": "Superman"}, {"id": 234, "title": "Batman"}]'`
2425+### Search documents in the `movies` index {#module-services-meilisearch-quickstart-search}
2627`curl 'http://127.0.0.1:7700/indexes/movies/search' --data '{ "q": "botman" }'` (note the typo is intentional and there to demonstrate the typo tolerant capabilities)
2829+## Defaults {#module-services-meilisearch-defaults}
3031- The default nixos package doesn't come with the [dashboard](https://docs.meilisearch.com/learn/getting_started/quick_start.html#search), since the dashboard features makes some assets downloads at compile time.
32···3435- Default deployment is development mode. It doesn't require a secret master key. All routes are not protected and accessible.
3637+## Missing {#module-services-meilisearch-missing}
3839- the snapshot feature is not yet configurable from the module, it's just a matter of adding the relevant environment variables.
-2
nixos/modules/services/search/meilisearch.nix
···9{
1011 meta.maintainers = with maintainers; [ Br1ght0ne happysalada ];
12- # Don't edit the docbook xml directly, edit the md and generate it:
13- # `pandoc meilisearch.md -t docbook --top-level-division=chapter --extract-media=media -f markdown+smart > meilisearch.xml`
14 meta.doc = ./meilisearch.xml;
1516 ###### interface
···001<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-akkoma">
2 <title>Akkoma</title>
3 <para>
···371 and
372 <option>services.systemd.akkoma.serviceConfig.BindReadOnlyPaths</option>
373 permit access to outside paths through bind mounts. Refer to
374- <link xlink:href="https://www.freedesktop.org/software/systemd/man/systemd.exec.html#BindPaths="><link xlink:href="https://www.freedesktop.org/software/systemd/man/systemd.exec.html"><citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry></link></link>
375 for details.
376 </para>
377 </section>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-akkoma">
4 <title>Akkoma</title>
5 <para>
···373 and
374 <option>services.systemd.akkoma.serviceConfig.BindReadOnlyPaths</option>
375 permit access to outside paths through bind mounts. Refer to
376+ <link xlink:href="https://www.freedesktop.org/software/systemd/man/systemd.exec.html#BindPaths="><citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry></link>
377 for details.
378 </para>
379 </section>
···1+# Discourse {#module-services-discourse}
2+3+[Discourse](https://www.discourse.org/) is a
4+modern and open source discussion platform.
5+6+## Basic usage {#module-services-discourse-basic-usage}
7+8+A minimal configuration using Let's Encrypt for TLS certificates looks like this:
9+```
10+services.discourse = {
11+ enable = true;
12+ hostname = "discourse.example.com";
13+ admin = {
14+ email = "admin@example.com";
15+ username = "admin";
16+ fullName = "Administrator";
17+ passwordFile = "/path/to/password_file";
18+ };
19+ secretKeyBaseFile = "/path/to/secret_key_base_file";
20+};
21+security.acme.email = "me@example.com";
22+security.acme.acceptTerms = true;
23+```
24+25+Provided a proper DNS setup, you'll be able to connect to the
26+instance at `discourse.example.com` and log in
27+using the credentials provided in
28+`services.discourse.admin`.
29+30+## Using a regular TLS certificate {#module-services-discourse-tls}
31+32+To set up TLS using a regular certificate and key on file, use
33+the [](#opt-services.discourse.sslCertificate)
34+and [](#opt-services.discourse.sslCertificateKey)
35+options:
36+37+```
38+services.discourse = {
39+ enable = true;
40+ hostname = "discourse.example.com";
41+ sslCertificate = "/path/to/ssl_certificate";
42+ sslCertificateKey = "/path/to/ssl_certificate_key";
43+ admin = {
44+ email = "admin@example.com";
45+ username = "admin";
46+ fullName = "Administrator";
47+ passwordFile = "/path/to/password_file";
48+ };
49+ secretKeyBaseFile = "/path/to/secret_key_base_file";
50+};
51+```
52+53+## Database access {#module-services-discourse-database}
54+55+Discourse uses PostgreSQL to store most of its
56+data. A database will automatically be enabled and a database
57+and role created unless [](#opt-services.discourse.database.host) is changed from
58+its default of `null` or [](#opt-services.discourse.database.createLocally) is set
59+to `false`.
60+61+External database access can also be configured by setting
62+[](#opt-services.discourse.database.host),
63+[](#opt-services.discourse.database.username) and
64+[](#opt-services.discourse.database.passwordFile) as
65+appropriate. Note that you need to manually create a database
66+called `discourse` (or the name you chose in
67+[](#opt-services.discourse.database.name)) and
68+allow the configured database user full access to it.
69+70+## Email {#module-services-discourse-mail}
71+72+In addition to the basic setup, you'll want to configure an SMTP
73+server Discourse can use to send user
74+registration and password reset emails, among others. You can
75+also optionally let Discourse receive
76+email, which enables people to reply to threads and conversations
77+via email.
78+79+A basic setup which assumes you want to use your configured
80+[hostname](#opt-services.discourse.hostname) as
81+email domain can be done like this:
82+83+```
84+services.discourse = {
85+ enable = true;
86+ hostname = "discourse.example.com";
87+ sslCertificate = "/path/to/ssl_certificate";
88+ sslCertificateKey = "/path/to/ssl_certificate_key";
89+ admin = {
90+ email = "admin@example.com";
91+ username = "admin";
92+ fullName = "Administrator";
93+ passwordFile = "/path/to/password_file";
94+ };
95+ mail.outgoing = {
96+ serverAddress = "smtp.emailprovider.com";
97+ port = 587;
98+ username = "user@emailprovider.com";
99+ passwordFile = "/path/to/smtp_password_file";
100+ };
101+ mail.incoming.enable = true;
102+ secretKeyBaseFile = "/path/to/secret_key_base_file";
103+};
104+```
105+106+This assumes you have set up an MX record for the address you've
107+set in [hostname](#opt-services.discourse.hostname) and
108+requires proper SPF, DKIM and DMARC configuration to be done for
109+the domain you're sending from, in order for email to be reliably delivered.
110+111+If you want to use a different domain for your outgoing email
112+(for example `example.com` instead of
113+`discourse.example.com`) you should set
114+[](#opt-services.discourse.mail.notificationEmailAddress) and
115+[](#opt-services.discourse.mail.contactEmailAddress) manually.
116+117+::: {.note}
118+Setup of TLS for incoming email is currently only configured
119+automatically when a regular TLS certificate is used, i.e. when
120+[](#opt-services.discourse.sslCertificate) and
121+[](#opt-services.discourse.sslCertificateKey) are
122+set.
123+:::
124+125+## Additional settings {#module-services-discourse-settings}
126+127+Additional site settings and backend settings, for which no
128+explicit NixOS options are provided,
129+can be set in [](#opt-services.discourse.siteSettings) and
130+[](#opt-services.discourse.backendSettings) respectively.
131+132+### Site settings {#module-services-discourse-site-settings}
133+134+"Site settings" are the settings that can be
135+changed through the Discourse
136+UI. Their *default* values can be set using
137+[](#opt-services.discourse.siteSettings).
138+139+Settings are expressed as a Nix attribute set which matches the
140+structure of the configuration in
141+[config/site_settings.yml](https://github.com/discourse/discourse/blob/master/config/site_settings.yml).
142+To find a setting's path, you only need to care about the first
143+two levels; i.e. its category (e.g. `login`)
144+and name (e.g. `invite_only`).
145+146+Settings containing secret data should be set to an attribute
147+set containing the attribute `_secret` - a
148+string pointing to a file containing the value the option
149+should be set to. See the example.
150+151+### Backend settings {#module-services-discourse-backend-settings}
152+153+Settings are expressed as a Nix attribute set which matches the
154+structure of the configuration in
155+[config/discourse.conf](https://github.com/discourse/discourse/blob/stable/config/discourse_defaults.conf).
156+Empty parameters can be defined by setting them to
157+`null`.
158+159+### Example {#module-services-discourse-settings-example}
160+161+The following example sets the title and description of the
162+Discourse instance and enables
163+GitHub login in the site settings,
164+and changes a few request limits in the backend settings:
165+```
166+services.discourse = {
167+ enable = true;
168+ hostname = "discourse.example.com";
169+ sslCertificate = "/path/to/ssl_certificate";
170+ sslCertificateKey = "/path/to/ssl_certificate_key";
171+ admin = {
172+ email = "admin@example.com";
173+ username = "admin";
174+ fullName = "Administrator";
175+ passwordFile = "/path/to/password_file";
176+ };
177+ mail.outgoing = {
178+ serverAddress = "smtp.emailprovider.com";
179+ port = 587;
180+ username = "user@emailprovider.com";
181+ passwordFile = "/path/to/smtp_password_file";
182+ };
183+ mail.incoming.enable = true;
184+ siteSettings = {
185+ required = {
186+ title = "My Cats";
187+ site_description = "Discuss My Cats (and be nice plz)";
188+ };
189+ login = {
190+ enable_github_logins = true;
191+ github_client_id = "a2f6dfe838cb3206ce20";
192+ github_client_secret._secret = /run/keys/discourse_github_client_secret;
193+ };
194+ };
195+ backendSettings = {
196+ max_reqs_per_ip_per_minute = 300;
197+ max_reqs_per_ip_per_10_seconds = 60;
198+ max_asset_reqs_per_ip_per_10_seconds = 250;
199+ max_reqs_per_ip_mode = "warn+block";
200+ };
201+ secretKeyBaseFile = "/path/to/secret_key_base_file";
202+};
203+```
204+205+In the resulting site settings file, the
206+`login.github_client_secret` key will be set
207+to the contents of the
208+{file}`/run/keys/discourse_github_client_secret`
209+file.
210+211+## Plugins {#module-services-discourse-plugins}
212+213+You can install Discourse plugins
214+using the [](#opt-services.discourse.plugins)
215+option. Pre-packaged plugins are provided in
216+`<your_discourse_package_here>.plugins`. If
217+you want the full suite of plugins provided through
218+`nixpkgs`, you can also set the [](#opt-services.discourse.package) option to
219+`pkgs.discourseAllPlugins`.
220+221+Plugins can be built with the
222+`<your_discourse_package_here>.mkDiscoursePlugin`
223+function. Normally, it should suffice to provide a
224+`name` and `src` attribute. If
225+the plugin has Ruby dependencies, however, they need to be
226+packaged in accordance with the [Developing with Ruby](https://nixos.org/manual/nixpkgs/stable/#developing-with-ruby)
227+section of the Nixpkgs manual and the
228+appropriate gem options set in `bundlerEnvArgs`
229+(normally `gemdir` is sufficient). A plugin's
230+Ruby dependencies are listed in its
231+{file}`plugin.rb` file as function calls to
232+`gem`. To construct the corresponding
233+{file}`Gemfile` manually, run {command}`bundle init`, then add the `gem` lines to it
234+verbatim.
235+236+Much of the packaging can be done automatically by the
237+{file}`nixpkgs/pkgs/servers/web-apps/discourse/update.py`
238+script - just add the plugin to the `plugins`
239+list in the `update_plugins` function and run
240+the script:
241+```bash
242+./update.py update-plugins
243+```
244+245+Some plugins provide [site settings](#module-services-discourse-site-settings).
246+Their defaults can be configured using [](#opt-services.discourse.siteSettings), just like
247+regular site settings. To find the names of these settings, look
248+in the `config/settings.yml` file of the plugin
249+repo.
250+251+For example, to add the [discourse-spoiler-alert](https://github.com/discourse/discourse-spoiler-alert)
252+and [discourse-solved](https://github.com/discourse/discourse-solved)
253+plugins, and disable `discourse-spoiler-alert`
254+by default:
255+256+```
257+services.discourse = {
258+ enable = true;
259+ hostname = "discourse.example.com";
260+ sslCertificate = "/path/to/ssl_certificate";
261+ sslCertificateKey = "/path/to/ssl_certificate_key";
262+ admin = {
263+ email = "admin@example.com";
264+ username = "admin";
265+ fullName = "Administrator";
266+ passwordFile = "/path/to/password_file";
267+ };
268+ mail.outgoing = {
269+ serverAddress = "smtp.emailprovider.com";
270+ port = 587;
271+ username = "user@emailprovider.com";
272+ passwordFile = "/path/to/smtp_password_file";
273+ };
274+ mail.incoming.enable = true;
275+ plugins = with config.services.discourse.package.plugins; [
276+ discourse-spoiler-alert
277+ discourse-solved
278+ ];
279+ siteSettings = {
280+ plugins = {
281+ spoiler_enabled = false;
282+ };
283+ };
284+ secretKeyBaseFile = "/path/to/secret_key_base_file";
285+};
286+```
+254-278
nixos/modules/services/web-apps/discourse.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-discourse">
6- <title>Discourse</title>
7- <para>
8- <link xlink:href="https://www.discourse.org/">Discourse</link> is a
9- modern and open source discussion platform.
10- </para>
11-12- <section xml:id="module-services-discourse-basic-usage">
13- <title>Basic usage</title>
14- <para>
15- A minimal configuration using Let's Encrypt for TLS certificates looks like this:
16-<programlisting>
17services.discourse = {
18- <link linkend="opt-services.discourse.enable">enable</link> = true;
19- <link linkend="opt-services.discourse.hostname">hostname</link> = "discourse.example.com";
20 admin = {
21- <link linkend="opt-services.discourse.admin.email">email</link> = "admin@example.com";
22- <link linkend="opt-services.discourse.admin.username">username</link> = "admin";
23- <link linkend="opt-services.discourse.admin.fullName">fullName</link> = "Administrator";
24- <link linkend="opt-services.discourse.admin.passwordFile">passwordFile</link> = "/path/to/password_file";
25 };
26- <link linkend="opt-services.discourse.secretKeyBaseFile">secretKeyBaseFile</link> = "/path/to/secret_key_base_file";
27};
28-<link linkend="opt-security.acme.defaults.email">security.acme.email</link> = "me@example.com";
29-<link linkend="opt-security.acme.acceptTerms">security.acme.acceptTerms</link> = true;
30</programlisting>
31- </para>
32-33- <para>
34- Provided a proper DNS setup, you'll be able to connect to the
35- instance at <literal>discourse.example.com</literal> and log in
36- using the credentials provided in
37- <literal>services.discourse.admin</literal>.
38- </para>
39- </section>
40-41- <section xml:id="module-services-discourse-tls">
42- <title>Using a regular TLS certificate</title>
43- <para>
44- To set up TLS using a regular certificate and key on file, use
45- the <xref linkend="opt-services.discourse.sslCertificate" />
46- and <xref linkend="opt-services.discourse.sslCertificateKey" />
47- options:
48-49-<programlisting>
50services.discourse = {
51- <link linkend="opt-services.discourse.enable">enable</link> = true;
52- <link linkend="opt-services.discourse.hostname">hostname</link> = "discourse.example.com";
53- <link linkend="opt-services.discourse.sslCertificate">sslCertificate</link> = "/path/to/ssl_certificate";
54- <link linkend="opt-services.discourse.sslCertificateKey">sslCertificateKey</link> = "/path/to/ssl_certificate_key";
55 admin = {
56- <link linkend="opt-services.discourse.admin.email">email</link> = "admin@example.com";
57- <link linkend="opt-services.discourse.admin.username">username</link> = "admin";
58- <link linkend="opt-services.discourse.admin.fullName">fullName</link> = "Administrator";
59- <link linkend="opt-services.discourse.admin.passwordFile">passwordFile</link> = "/path/to/password_file";
60 };
61- <link linkend="opt-services.discourse.secretKeyBaseFile">secretKeyBaseFile</link> = "/path/to/secret_key_base_file";
62};
63</programlisting>
64-65- </para>
66- </section>
67-68- <section xml:id="module-services-discourse-database">
69- <title>Database access</title>
70- <para>
71- <productname>Discourse</productname> uses
72- <productname>PostgreSQL</productname> to store most of its
73- data. A database will automatically be enabled and a database
74- and role created unless <xref
75- linkend="opt-services.discourse.database.host" /> is changed from
76- its default of <literal>null</literal> or <xref
77- linkend="opt-services.discourse.database.createLocally" /> is set
78- to <literal>false</literal>.
79- </para>
80-81- <para>
82- External database access can also be configured by setting
83- <xref linkend="opt-services.discourse.database.host" />, <xref
84- linkend="opt-services.discourse.database.username" /> and <xref
85- linkend="opt-services.discourse.database.passwordFile" /> as
86- appropriate. Note that you need to manually create a database
87- called <literal>discourse</literal> (or the name you chose in
88- <xref linkend="opt-services.discourse.database.name" />) and
89- allow the configured database user full access to it.
90- </para>
91- </section>
92-93- <section xml:id="module-services-discourse-mail">
94- <title>Email</title>
95- <para>
96- In addition to the basic setup, you'll want to configure an SMTP
97- server <productname>Discourse</productname> can use to send user
98- registration and password reset emails, among others. You can
99- also optionally let <productname>Discourse</productname> receive
100- email, which enables people to reply to threads and conversations
101- via email.
102- </para>
103-104- <para>
105- A basic setup which assumes you want to use your configured <link
106- linkend="opt-services.discourse.hostname">hostname</link> as
107- email domain can be done like this:
108-109-<programlisting>
110services.discourse = {
111- <link linkend="opt-services.discourse.enable">enable</link> = true;
112- <link linkend="opt-services.discourse.hostname">hostname</link> = "discourse.example.com";
113- <link linkend="opt-services.discourse.sslCertificate">sslCertificate</link> = "/path/to/ssl_certificate";
114- <link linkend="opt-services.discourse.sslCertificateKey">sslCertificateKey</link> = "/path/to/ssl_certificate_key";
115 admin = {
116- <link linkend="opt-services.discourse.admin.email">email</link> = "admin@example.com";
117- <link linkend="opt-services.discourse.admin.username">username</link> = "admin";
118- <link linkend="opt-services.discourse.admin.fullName">fullName</link> = "Administrator";
119- <link linkend="opt-services.discourse.admin.passwordFile">passwordFile</link> = "/path/to/password_file";
120 };
121 mail.outgoing = {
122- <link linkend="opt-services.discourse.mail.outgoing.serverAddress">serverAddress</link> = "smtp.emailprovider.com";
123- <link linkend="opt-services.discourse.mail.outgoing.port">port</link> = 587;
124- <link linkend="opt-services.discourse.mail.outgoing.username">username</link> = "user@emailprovider.com";
125- <link linkend="opt-services.discourse.mail.outgoing.passwordFile">passwordFile</link> = "/path/to/smtp_password_file";
126 };
127- <link linkend="opt-services.discourse.mail.incoming.enable">mail.incoming.enable</link> = true;
128- <link linkend="opt-services.discourse.secretKeyBaseFile">secretKeyBaseFile</link> = "/path/to/secret_key_base_file";
129};
130</programlisting>
131-132- This assumes you have set up an MX record for the address you've
133- set in <link linkend="opt-services.discourse.hostname">hostname</link> and
134- requires proper SPF, DKIM and DMARC configuration to be done for
135- the domain you're sending from, in order for email to be reliably delivered.
136- </para>
137-138- <para>
139- If you want to use a different domain for your outgoing email
140- (for example <literal>example.com</literal> instead of
141- <literal>discourse.example.com</literal>) you should set
142- <xref linkend="opt-services.discourse.mail.notificationEmailAddress" /> and
143- <xref linkend="opt-services.discourse.mail.contactEmailAddress" /> manually.
144- </para>
145-146- <note>
147- <para>
148- Setup of TLS for incoming email is currently only configured
149- automatically when a regular TLS certificate is used, i.e. when
150- <xref linkend="opt-services.discourse.sslCertificate" /> and
151- <xref linkend="opt-services.discourse.sslCertificateKey" /> are
152- set.
153- </para>
154- </note>
155-156- </section>
157-158- <section xml:id="module-services-discourse-settings">
159- <title>Additional settings</title>
160- <para>
161- Additional site settings and backend settings, for which no
162- explicit <productname>NixOS</productname> options are provided,
163- can be set in <xref linkend="opt-services.discourse.siteSettings" /> and
164- <xref linkend="opt-services.discourse.backendSettings" /> respectively.
165- </para>
166-167- <section xml:id="module-services-discourse-site-settings">
168- <title>Site settings</title>
169- <para>
170- <quote>Site settings</quote> are the settings that can be
171- changed through the <productname>Discourse</productname>
172- UI. Their <emphasis>default</emphasis> values can be set using
173- <xref linkend="opt-services.discourse.siteSettings" />.
174- </para>
175-176- <para>
177- Settings are expressed as a Nix attribute set which matches the
178- structure of the configuration in
179- <link xlink:href="https://github.com/discourse/discourse/blob/master/config/site_settings.yml">config/site_settings.yml</link>.
180- To find a setting's path, you only need to care about the first
181- two levels; i.e. its category (e.g. <literal>login</literal>)
182- and name (e.g. <literal>invite_only</literal>).
183- </para>
184-185- <para>
186- Settings containing secret data should be set to an attribute
187- set containing the attribute <literal>_secret</literal> - a
188- string pointing to a file containing the value the option
189- should be set to. See the example.
190- </para>
191- </section>
192-193- <section xml:id="module-services-discourse-backend-settings">
194- <title>Backend settings</title>
195- <para>
196- Settings are expressed as a Nix attribute set which matches the
197- structure of the configuration in
198- <link xlink:href="https://github.com/discourse/discourse/blob/stable/config/discourse_defaults.conf">config/discourse.conf</link>.
199- Empty parameters can be defined by setting them to
200- <literal>null</literal>.
201- </para>
202- </section>
203-204- <section xml:id="module-services-discourse-settings-example">
205- <title>Example</title>
206- <para>
207- The following example sets the title and description of the
208- <productname>Discourse</productname> instance and enables
209- <productname>GitHub</productname> login in the site settings,
210- and changes a few request limits in the backend settings:
211-<programlisting>
212services.discourse = {
213- <link linkend="opt-services.discourse.enable">enable</link> = true;
214- <link linkend="opt-services.discourse.hostname">hostname</link> = "discourse.example.com";
215- <link linkend="opt-services.discourse.sslCertificate">sslCertificate</link> = "/path/to/ssl_certificate";
216- <link linkend="opt-services.discourse.sslCertificateKey">sslCertificateKey</link> = "/path/to/ssl_certificate_key";
217 admin = {
218- <link linkend="opt-services.discourse.admin.email">email</link> = "admin@example.com";
219- <link linkend="opt-services.discourse.admin.username">username</link> = "admin";
220- <link linkend="opt-services.discourse.admin.fullName">fullName</link> = "Administrator";
221- <link linkend="opt-services.discourse.admin.passwordFile">passwordFile</link> = "/path/to/password_file";
222 };
223 mail.outgoing = {
224- <link linkend="opt-services.discourse.mail.outgoing.serverAddress">serverAddress</link> = "smtp.emailprovider.com";
225- <link linkend="opt-services.discourse.mail.outgoing.port">port</link> = 587;
226- <link linkend="opt-services.discourse.mail.outgoing.username">username</link> = "user@emailprovider.com";
227- <link linkend="opt-services.discourse.mail.outgoing.passwordFile">passwordFile</link> = "/path/to/smtp_password_file";
228 };
229- <link linkend="opt-services.discourse.mail.incoming.enable">mail.incoming.enable</link> = true;
230- <link linkend="opt-services.discourse.siteSettings">siteSettings</link> = {
231 required = {
232- title = "My Cats";
233- site_description = "Discuss My Cats (and be nice plz)";
234 };
235 login = {
236 enable_github_logins = true;
237- github_client_id = "a2f6dfe838cb3206ce20";
238 github_client_secret._secret = /run/keys/discourse_github_client_secret;
239 };
240 };
241- <link linkend="opt-services.discourse.backendSettings">backendSettings</link> = {
242 max_reqs_per_ip_per_minute = 300;
243 max_reqs_per_ip_per_10_seconds = 60;
244 max_asset_reqs_per_ip_per_10_seconds = 250;
245- max_reqs_per_ip_mode = "warn+block";
246 };
247- <link linkend="opt-services.discourse.secretKeyBaseFile">secretKeyBaseFile</link> = "/path/to/secret_key_base_file";
248};
249</programlisting>
250- </para>
251- <para>
252- In the resulting site settings file, the
253- <literal>login.github_client_secret</literal> key will be set
254- to the contents of the
255- <filename>/run/keys/discourse_github_client_secret</filename>
256- file.
257- </para>
258- </section>
259- </section>
260 <section xml:id="module-services-discourse-plugins">
261 <title>Plugins</title>
262 <para>
263- You can install <productname>Discourse</productname> plugins
264- using the <xref linkend="opt-services.discourse.plugins" />
265- option. Pre-packaged plugins are provided in
266 <literal><your_discourse_package_here>.plugins</literal>. If
267 you want the full suite of plugins provided through
268- <literal>nixpkgs</literal>, you can also set the <xref
269- linkend="opt-services.discourse.package" /> option to
270 <literal>pkgs.discourseAllPlugins</literal>.
271 </para>
272-273 <para>
274 Plugins can be built with the
275 <literal><your_discourse_package_here>.mkDiscoursePlugin</literal>
276 function. Normally, it should suffice to provide a
277 <literal>name</literal> and <literal>src</literal> attribute. If
278 the plugin has Ruby dependencies, however, they need to be
279- packaged in accordance with the <link
280- xlink:href="https://nixos.org/manual/nixpkgs/stable/#developing-with-ruby">Developing
281- with Ruby</link> section of the Nixpkgs manual and the
282- appropriate gem options set in <literal>bundlerEnvArgs</literal>
283- (normally <literal>gemdir</literal> is sufficient). A plugin's
284- Ruby dependencies are listed in its
285- <filename>plugin.rb</filename> file as function calls to
286- <literal>gem</literal>. To construct the corresponding
287- <filename>Gemfile</filename> manually, run <command>bundle
288- init</command>, then add the <literal>gem</literal> lines to it
289- verbatim.
290 </para>
291-292 <para>
293 Much of the packaging can be done automatically by the
294 <filename>nixpkgs/pkgs/servers/web-apps/discourse/update.py</filename>
295 script - just add the plugin to the <literal>plugins</literal>
296- list in the <function>update_plugins</function> function and run
297- the script:
298- <programlisting language="bash">
0299./update.py update-plugins
300</programlisting>
301- </para>
302-303 <para>
304- Some plugins provide <link
305- linkend="module-services-discourse-site-settings">site
306- settings</link>. Their defaults can be configured using <xref
307- linkend="opt-services.discourse.siteSettings" />, just like
308 regular site settings. To find the names of these settings, look
309 in the <literal>config/settings.yml</literal> file of the plugin
310 repo.
311 </para>
312-313 <para>
314- For example, to add the <link
315- xlink:href="https://github.com/discourse/discourse-spoiler-alert">discourse-spoiler-alert</link>
316- and <link
317- xlink:href="https://github.com/discourse/discourse-solved">discourse-solved</link>
318- plugins, and disable <literal>discourse-spoiler-alert</literal>
319- by default:
320-321-<programlisting>
322services.discourse = {
323- <link linkend="opt-services.discourse.enable">enable</link> = true;
324- <link linkend="opt-services.discourse.hostname">hostname</link> = "discourse.example.com";
325- <link linkend="opt-services.discourse.sslCertificate">sslCertificate</link> = "/path/to/ssl_certificate";
326- <link linkend="opt-services.discourse.sslCertificateKey">sslCertificateKey</link> = "/path/to/ssl_certificate_key";
327 admin = {
328- <link linkend="opt-services.discourse.admin.email">email</link> = "admin@example.com";
329- <link linkend="opt-services.discourse.admin.username">username</link> = "admin";
330- <link linkend="opt-services.discourse.admin.fullName">fullName</link> = "Administrator";
331- <link linkend="opt-services.discourse.admin.passwordFile">passwordFile</link> = "/path/to/password_file";
332 };
333 mail.outgoing = {
334- <link linkend="opt-services.discourse.mail.outgoing.serverAddress">serverAddress</link> = "smtp.emailprovider.com";
335- <link linkend="opt-services.discourse.mail.outgoing.port">port</link> = 587;
336- <link linkend="opt-services.discourse.mail.outgoing.username">username</link> = "user@emailprovider.com";
337- <link linkend="opt-services.discourse.mail.outgoing.passwordFile">passwordFile</link> = "/path/to/smtp_password_file";
338 };
339- <link linkend="opt-services.discourse.mail.incoming.enable">mail.incoming.enable</link> = true;
340- <link linkend="opt-services.discourse.mail.incoming.enable">plugins</link> = with config.services.discourse.package.plugins; [
341 discourse-spoiler-alert
342 discourse-solved
343 ];
344- <link linkend="opt-services.discourse.siteSettings">siteSettings</link> = {
345 plugins = {
346 spoiler_enabled = false;
347 };
348 };
349- <link linkend="opt-services.discourse.secretKeyBaseFile">secretKeyBaseFile</link> = "/path/to/secret_key_base_file";
350};
351</programlisting>
352-353- </para>
354 </section>
355</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-discourse">
4+ <title>Discourse</title>
5+ <para>
6+ <link xlink:href="https://www.discourse.org/">Discourse</link> is a
7+ modern and open source discussion platform.
8+ </para>
9+ <section xml:id="module-services-discourse-basic-usage">
10+ <title>Basic usage</title>
11+ <para>
12+ A minimal configuration using Let’s Encrypt for TLS certificates
13+ looks like this:
14+ </para>
15+ <programlisting>
016services.discourse = {
17+ enable = true;
18+ hostname = "discourse.example.com";
19 admin = {
20+ email = "admin@example.com";
21+ username = "admin";
22+ fullName = "Administrator";
23+ passwordFile = "/path/to/password_file";
24 };
25+ secretKeyBaseFile = "/path/to/secret_key_base_file";
26};
27+security.acme.email = "me@example.com";
28+security.acme.acceptTerms = true;
29</programlisting>
30+ <para>
31+ Provided a proper DNS setup, you’ll be able to connect to the
32+ instance at <literal>discourse.example.com</literal> and log in
33+ using the credentials provided in
34+ <literal>services.discourse.admin</literal>.
35+ </para>
36+ </section>
37+ <section xml:id="module-services-discourse-tls">
38+ <title>Using a regular TLS certificate</title>
39+ <para>
40+ To set up TLS using a regular certificate and key on file, use the
41+ <xref linkend="opt-services.discourse.sslCertificate" /> and
42+ <xref linkend="opt-services.discourse.sslCertificateKey" />
43+ options:
44+ </para>
45+ <programlisting>
00046services.discourse = {
47+ enable = true;
48+ hostname = "discourse.example.com";
49+ sslCertificate = "/path/to/ssl_certificate";
50+ sslCertificateKey = "/path/to/ssl_certificate_key";
51 admin = {
52+ email = "admin@example.com";
53+ username = "admin";
54+ fullName = "Administrator";
55+ passwordFile = "/path/to/password_file";
56 };
57+ secretKeyBaseFile = "/path/to/secret_key_base_file";
58};
59</programlisting>
60+ </section>
61+ <section xml:id="module-services-discourse-database">
62+ <title>Database access</title>
63+ <para>
64+ Discourse uses PostgreSQL to store most of its data. A database
65+ will automatically be enabled and a database and role created
66+ unless <xref linkend="opt-services.discourse.database.host" /> is
67+ changed from its default of <literal>null</literal> or
68+ <xref linkend="opt-services.discourse.database.createLocally" />
69+ is set to <literal>false</literal>.
70+ </para>
71+ <para>
72+ External database access can also be configured by setting
73+ <xref linkend="opt-services.discourse.database.host" />,
74+ <xref linkend="opt-services.discourse.database.username" /> and
75+ <xref linkend="opt-services.discourse.database.passwordFile" /> as
76+ appropriate. Note that you need to manually create a database
77+ called <literal>discourse</literal> (or the name you chose in
78+ <xref linkend="opt-services.discourse.database.name" />) and allow
79+ the configured database user full access to it.
80+ </para>
81+ </section>
82+ <section xml:id="module-services-discourse-mail">
83+ <title>Email</title>
84+ <para>
85+ In addition to the basic setup, you’ll want to configure an SMTP
86+ server Discourse can use to send user registration and password
87+ reset emails, among others. You can also optionally let Discourse
88+ receive email, which enables people to reply to threads and
89+ conversations via email.
90+ </para>
91+ <para>
92+ A basic setup which assumes you want to use your configured
93+ <link linkend="opt-services.discourse.hostname">hostname</link> as
94+ email domain can be done like this:
95+ </para>
96+ <programlisting>
00000000097services.discourse = {
98+ enable = true;
99+ hostname = "discourse.example.com";
100+ sslCertificate = "/path/to/ssl_certificate";
101+ sslCertificateKey = "/path/to/ssl_certificate_key";
102 admin = {
103+ email = "admin@example.com";
104+ username = "admin";
105+ fullName = "Administrator";
106+ passwordFile = "/path/to/password_file";
107 };
108 mail.outgoing = {
109+ serverAddress = "smtp.emailprovider.com";
110+ port = 587;
111+ username = "user@emailprovider.com";
112+ passwordFile = "/path/to/smtp_password_file";
113 };
114+ mail.incoming.enable = true;
115+ secretKeyBaseFile = "/path/to/secret_key_base_file";
116};
117</programlisting>
118+ <para>
119+ This assumes you have set up an MX record for the address you’ve
120+ set in
121+ <link linkend="opt-services.discourse.hostname">hostname</link>
122+ and requires proper SPF, DKIM and DMARC configuration to be done
123+ for the domain you’re sending from, in order for email to be
124+ reliably delivered.
125+ </para>
126+ <para>
127+ If you want to use a different domain for your outgoing email (for
128+ example <literal>example.com</literal> instead of
129+ <literal>discourse.example.com</literal>) you should set
130+ <xref linkend="opt-services.discourse.mail.notificationEmailAddress" />
131+ and
132+ <xref linkend="opt-services.discourse.mail.contactEmailAddress" />
133+ manually.
134+ </para>
135+ <note>
136+ <para>
137+ Setup of TLS for incoming email is currently only configured
138+ automatically when a regular TLS certificate is used, i.e. when
139+ <xref linkend="opt-services.discourse.sslCertificate" /> and
140+ <xref linkend="opt-services.discourse.sslCertificateKey" /> are
141+ set.
142+ </para>
143+ </note>
144+ </section>
145+ <section xml:id="module-services-discourse-settings">
146+ <title>Additional settings</title>
147+ <para>
148+ Additional site settings and backend settings, for which no
149+ explicit NixOS options are provided, can be set in
150+ <xref linkend="opt-services.discourse.siteSettings" /> and
151+ <xref linkend="opt-services.discourse.backendSettings" />
152+ respectively.
153+ </para>
154+ <section xml:id="module-services-discourse-site-settings">
155+ <title>Site settings</title>
156+ <para>
157+ <quote>Site settings</quote> are the settings that can be
158+ changed through the Discourse UI. Their
159+ <emphasis>default</emphasis> values can be set using
160+ <xref linkend="opt-services.discourse.siteSettings" />.
161+ </para>
162+ <para>
163+ Settings are expressed as a Nix attribute set which matches the
164+ structure of the configuration in
165+ <link xlink:href="https://github.com/discourse/discourse/blob/master/config/site_settings.yml">config/site_settings.yml</link>.
166+ To find a setting’s path, you only need to care about the first
167+ two levels; i.e. its category (e.g. <literal>login</literal>)
168+ and name (e.g. <literal>invite_only</literal>).
169+ </para>
170+ <para>
171+ Settings containing secret data should be set to an attribute
172+ set containing the attribute <literal>_secret</literal> - a
173+ string pointing to a file containing the value the option should
174+ be set to. See the example.
175+ </para>
176+ </section>
177+ <section xml:id="module-services-discourse-backend-settings">
178+ <title>Backend settings</title>
179+ <para>
180+ Settings are expressed as a Nix attribute set which matches the
181+ structure of the configuration in
182+ <link xlink:href="https://github.com/discourse/discourse/blob/stable/config/discourse_defaults.conf">config/discourse.conf</link>.
183+ Empty parameters can be defined by setting them to
184+ <literal>null</literal>.
185+ </para>
186+ </section>
187+ <section xml:id="module-services-discourse-settings-example">
188+ <title>Example</title>
189+ <para>
190+ The following example sets the title and description of the
191+ Discourse instance and enables GitHub login in the site
192+ settings, and changes a few request limits in the backend
193+ settings:
194+ </para>
195+ <programlisting>
000196services.discourse = {
197+ enable = true;
198+ hostname = "discourse.example.com";
199+ sslCertificate = "/path/to/ssl_certificate";
200+ sslCertificateKey = "/path/to/ssl_certificate_key";
201 admin = {
202+ email = "admin@example.com";
203+ username = "admin";
204+ fullName = "Administrator";
205+ passwordFile = "/path/to/password_file";
206 };
207 mail.outgoing = {
208+ serverAddress = "smtp.emailprovider.com";
209+ port = 587;
210+ username = "user@emailprovider.com";
211+ passwordFile = "/path/to/smtp_password_file";
212 };
213+ mail.incoming.enable = true;
214+ siteSettings = {
215 required = {
216+ title = "My Cats";
217+ site_description = "Discuss My Cats (and be nice plz)";
218 };
219 login = {
220 enable_github_logins = true;
221+ github_client_id = "a2f6dfe838cb3206ce20";
222 github_client_secret._secret = /run/keys/discourse_github_client_secret;
223 };
224 };
225+ backendSettings = {
226 max_reqs_per_ip_per_minute = 300;
227 max_reqs_per_ip_per_10_seconds = 60;
228 max_asset_reqs_per_ip_per_10_seconds = 250;
229+ max_reqs_per_ip_mode = "warn+block";
230 };
231+ secretKeyBaseFile = "/path/to/secret_key_base_file";
232};
233</programlisting>
234+ <para>
235+ In the resulting site settings file, the
236+ <literal>login.github_client_secret</literal> key will be set to
237+ the contents of the
238+ <filename>/run/keys/discourse_github_client_secret</filename>
239+ file.
240+ </para>
241+ </section>
242+ </section>
0243 <section xml:id="module-services-discourse-plugins">
244 <title>Plugins</title>
245 <para>
246+ You can install Discourse plugins using the
247+ <xref linkend="opt-services.discourse.plugins" /> option.
248+ Pre-packaged plugins are provided in
249 <literal><your_discourse_package_here>.plugins</literal>. If
250 you want the full suite of plugins provided through
251+ <literal>nixpkgs</literal>, you can also set the
252+ <xref linkend="opt-services.discourse.package" /> option to
253 <literal>pkgs.discourseAllPlugins</literal>.
254 </para>
0255 <para>
256 Plugins can be built with the
257 <literal><your_discourse_package_here>.mkDiscoursePlugin</literal>
258 function. Normally, it should suffice to provide a
259 <literal>name</literal> and <literal>src</literal> attribute. If
260 the plugin has Ruby dependencies, however, they need to be
261+ packaged in accordance with the
262+ <link xlink:href="https://nixos.org/manual/nixpkgs/stable/#developing-with-ruby">Developing
263+ with Ruby</link> section of the Nixpkgs manual and the appropriate
264+ gem options set in <literal>bundlerEnvArgs</literal> (normally
265+ <literal>gemdir</literal> is sufficient). A plugin’s Ruby
266+ dependencies are listed in its <filename>plugin.rb</filename> file
267+ as function calls to <literal>gem</literal>. To construct the
268+ corresponding <filename>Gemfile</filename> manually, run
269+ <command>bundle init</command>, then add the
270+ <literal>gem</literal> lines to it verbatim.
0271 </para>
0272 <para>
273 Much of the packaging can be done automatically by the
274 <filename>nixpkgs/pkgs/servers/web-apps/discourse/update.py</filename>
275 script - just add the plugin to the <literal>plugins</literal>
276+ list in the <literal>update_plugins</literal> function and run the
277+ script:
278+ </para>
279+ <programlisting language="bash">
280./update.py update-plugins
281</programlisting>
00282 <para>
283+ Some plugins provide
284+ <link linkend="module-services-discourse-site-settings">site
285+ settings</link>. Their defaults can be configured using
286+ <xref linkend="opt-services.discourse.siteSettings" />, just like
287 regular site settings. To find the names of these settings, look
288 in the <literal>config/settings.yml</literal> file of the plugin
289 repo.
290 </para>
0291 <para>
292+ For example, to add the
293+ <link xlink:href="https://github.com/discourse/discourse-spoiler-alert">discourse-spoiler-alert</link>
294+ and
295+ <link xlink:href="https://github.com/discourse/discourse-solved">discourse-solved</link>
296+ plugins, and disable <literal>discourse-spoiler-alert</literal> by
297+ default:
298+ </para>
299+ <programlisting>
300services.discourse = {
301+ enable = true;
302+ hostname = "discourse.example.com";
303+ sslCertificate = "/path/to/ssl_certificate";
304+ sslCertificateKey = "/path/to/ssl_certificate_key";
305 admin = {
306+ email = "admin@example.com";
307+ username = "admin";
308+ fullName = "Administrator";
309+ passwordFile = "/path/to/password_file";
310 };
311 mail.outgoing = {
312+ serverAddress = "smtp.emailprovider.com";
313+ port = 587;
314+ username = "user@emailprovider.com";
315+ passwordFile = "/path/to/smtp_password_file";
316 };
317+ mail.incoming.enable = true;
318+ plugins = with config.services.discourse.package.plugins; [
319 discourse-spoiler-alert
320 discourse-solved
321 ];
322+ siteSettings = {
323 plugins = {
324 spoiler_enabled = false;
325 };
326 };
327+ secretKeyBaseFile = "/path/to/secret_key_base_file";
328};
329</programlisting>
00330 </section>
331</chapter>
···1+# Grocy {#module-services-grocy}
2+3+[Grocy](https://grocy.info/) is a web-based self-hosted groceries
4+& household management solution for your home.
5+6+## Basic usage {#module-services-grocy-basic-usage}
7+8+A very basic configuration may look like this:
9+```
10+{ pkgs, ... }:
11+{
12+ services.grocy = {
13+ enable = true;
14+ hostName = "grocy.tld";
15+ };
16+}
17+```
18+This configures a simple vhost using [nginx](#opt-services.nginx.enable)
19+which listens to `grocy.tld` with fully configured ACME/LE (this can be
20+disabled by setting [services.grocy.nginx.enableSSL](#opt-services.grocy.nginx.enableSSL)
21+to `false`). After the initial setup the credentials `admin:admin`
22+can be used to login.
23+24+The application's state is persisted at `/var/lib/grocy/grocy.db` in a
25+`sqlite3` database. The migration is applied when requesting the `/`-route
26+of the application.
27+28+## Settings {#module-services-grocy-settings}
29+30+The configuration for `grocy` is located at `/etc/grocy/config.php`.
31+By default, the following settings can be defined in the NixOS-configuration:
32+```
33+{ pkgs, ... }:
34+{
35+ services.grocy.settings = {
36+ # The default currency in the system for invoices etc.
37+ # Please note that exchange rates aren't taken into account, this
38+ # is just the setting for what's shown in the frontend.
39+ currency = "EUR";
40+41+ # The display language (and locale configuration) for grocy.
42+ culture = "de";
43+44+ calendar = {
45+ # Whether or not to show the week-numbers
46+ # in the calendar.
47+ showWeekNumber = true;
48+49+ # Index of the first day to be shown in the calendar (0=Sunday, 1=Monday,
50+ # 2=Tuesday and so on).
51+ firstDayOfWeek = 2;
52+ };
53+ };
54+}
55+```
56+57+If you want to alter the configuration file on your own, you can do this manually with
58+an expression like this:
59+```
60+{ lib, ... }:
61+{
62+ environment.etc."grocy/config.php".text = lib.mkAfter ''
63+ // Arbitrary PHP code in grocy's configuration file
64+ '';
65+}
66+```
+54-47
nixos/modules/services/web-apps/grocy.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-grocy">
6-7 <title>Grocy</title>
8 <para>
9- <link xlink:href="https://grocy.info/">Grocy</link> is a web-based self-hosted groceries
10- & household management solution for your home.
011 </para>
12-13 <section xml:id="module-services-grocy-basic-usage">
14- <title>Basic usage</title>
15- <para>
16- A very basic configuration may look like this:
17-<programlisting>{ pkgs, ... }:
0018{
19 services.grocy = {
20- <link linkend="opt-services.grocy.enable">enable</link> = true;
21- <link linkend="opt-services.grocy.hostName">hostName</link> = "grocy.tld";
22 };
23-}</programlisting>
24- This configures a simple vhost using <link linkend="opt-services.nginx.enable">nginx</link>
25- which listens to <literal>grocy.tld</literal> with fully configured ACME/LE (this can be
26- disabled by setting <link linkend="opt-services.grocy.nginx.enableSSL">services.grocy.nginx.enableSSL</link>
27- to <literal>false</literal>). After the initial setup the credentials <literal>admin:admin</literal>
28- can be used to login.
29- </para>
30- <para>
31- The application's state is persisted at <literal>/var/lib/grocy/grocy.db</literal> in a
32- <package>sqlite3</package> database. The migration is applied when requesting the <literal>/</literal>-route
33- of the application.
34- </para>
0000035 </section>
36-37 <section xml:id="module-services-grocy-settings">
38- <title>Settings</title>
39- <para>
40- The configuration for <literal>grocy</literal> is located at <literal>/etc/grocy/config.php</literal>.
41- By default, the following settings can be defined in the NixOS-configuration:
42-<programlisting>{ pkgs, ... }:
00043{
44 services.grocy.settings = {
45 # The default currency in the system for invoices etc.
46 # Please note that exchange rates aren't taken into account, this
47 # is just the setting for what's shown in the frontend.
48- <link linkend="opt-services.grocy.settings.currency">currency</link> = "EUR";
4950 # The display language (and locale configuration) for grocy.
51- <link linkend="opt-services.grocy.settings.currency">culture</link> = "de";
5253 calendar = {
54 # Whether or not to show the week-numbers
55 # in the calendar.
56- <link linkend="opt-services.grocy.settings.calendar.showWeekNumber">showWeekNumber</link> = true;
5758 # Index of the first day to be shown in the calendar (0=Sunday, 1=Monday,
59 # 2=Tuesday and so on).
60- <link linkend="opt-services.grocy.settings.calendar.firstDayOfWeek">firstDayOfWeek</link> = 2;
61 };
62 };
63-}</programlisting>
64- </para>
65- <para>
66- If you want to alter the configuration file on your own, you can do this manually with
67- an expression like this:
68-<programlisting>{ lib, ... }:
0069{
70- environment.etc."grocy/config.php".text = lib.mkAfter ''
71 // Arbitrary PHP code in grocy's configuration file
72 '';
73-}</programlisting>
74- </para>
75 </section>
76-77</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-grocy">
0004 <title>Grocy</title>
5 <para>
6+ <link xlink:href="https://grocy.info/">Grocy</link> is a web-based
7+ self-hosted groceries & household management solution for your
8+ home.
9 </para>
010 <section xml:id="module-services-grocy-basic-usage">
11+ <title>Basic usage</title>
12+ <para>
13+ A very basic configuration may look like this:
14+ </para>
15+ <programlisting>
16+{ pkgs, ... }:
17{
18 services.grocy = {
19+ enable = true;
20+ hostName = "grocy.tld";
21 };
22+}
23+</programlisting>
24+ <para>
25+ This configures a simple vhost using
26+ <link linkend="opt-services.nginx.enable">nginx</link> which
27+ listens to <literal>grocy.tld</literal> with fully configured
28+ ACME/LE (this can be disabled by setting
29+ <link linkend="opt-services.grocy.nginx.enableSSL">services.grocy.nginx.enableSSL</link>
30+ to <literal>false</literal>). After the initial setup the
31+ credentials <literal>admin:admin</literal> can be used to login.
32+ </para>
33+ <para>
34+ The application’s state is persisted at
35+ <literal>/var/lib/grocy/grocy.db</literal> in a
36+ <literal>sqlite3</literal> database. The migration is applied when
37+ requesting the <literal>/</literal>-route of the application.
38+ </para>
39 </section>
040 <section xml:id="module-services-grocy-settings">
41+ <title>Settings</title>
42+ <para>
43+ The configuration for <literal>grocy</literal> is located at
44+ <literal>/etc/grocy/config.php</literal>. By default, the
45+ following settings can be defined in the NixOS-configuration:
46+ </para>
47+ <programlisting>
48+{ pkgs, ... }:
49{
50 services.grocy.settings = {
51 # The default currency in the system for invoices etc.
52 # Please note that exchange rates aren't taken into account, this
53 # is just the setting for what's shown in the frontend.
54+ currency = "EUR";
5556 # The display language (and locale configuration) for grocy.
57+ culture = "de";
5859 calendar = {
60 # Whether or not to show the week-numbers
61 # in the calendar.
62+ showWeekNumber = true;
6364 # Index of the first day to be shown in the calendar (0=Sunday, 1=Monday,
65 # 2=Tuesday and so on).
66+ firstDayOfWeek = 2;
67 };
68 };
69+}
70+</programlisting>
71+ <para>
72+ If you want to alter the configuration file on your own, you can
73+ do this manually with an expression like this:
74+ </para>
75+ <programlisting>
76+{ lib, ... }:
77{
78+ environment.etc."grocy/config.php".text = lib.mkAfter ''
79 // Arbitrary PHP code in grocy's configuration file
80 '';
81+}
82+</programlisting>
83 </section>
084</chapter>
···1+# Keycloak {#module-services-keycloak}
2+3+[Keycloak](https://www.keycloak.org/) is an
4+open source identity and access management server with support for
5+[OpenID Connect](https://openid.net/connect/),
6+[OAUTH 2.0](https://oauth.net/2/) and
7+[SAML 2.0](https://en.wikipedia.org/wiki/SAML_2.0).
8+9+## Administration {#module-services-keycloak-admin}
10+11+An administrative user with the username
12+`admin` is automatically created in the
13+`master` realm. Its initial password can be
14+configured by setting [](#opt-services.keycloak.initialAdminPassword)
15+and defaults to `changeme`. The password is
16+not stored safely and should be changed immediately in the
17+admin panel.
18+19+Refer to the [Keycloak Server Administration Guide](
20+ https://www.keycloak.org/docs/latest/server_admin/index.html
21+) for information on
22+how to administer your Keycloak
23+instance.
24+25+## Database access {#module-services-keycloak-database}
26+27+Keycloak can be used with either PostgreSQL, MariaDB or
28+MySQL. Which one is used can be
29+configured in [](#opt-services.keycloak.database.type). The selected
30+database will automatically be enabled and a database and role
31+created unless [](#opt-services.keycloak.database.host) is changed
32+from its default of `localhost` or
33+[](#opt-services.keycloak.database.createLocally) is set to `false`.
34+35+External database access can also be configured by setting
36+[](#opt-services.keycloak.database.host),
37+[](#opt-services.keycloak.database.name),
38+[](#opt-services.keycloak.database.username),
39+[](#opt-services.keycloak.database.useSSL) and
40+[](#opt-services.keycloak.database.caCert) as
41+appropriate. Note that you need to manually create the database
42+and allow the configured database user full access to it.
43+44+[](#opt-services.keycloak.database.passwordFile)
45+must be set to the path to a file containing the password used
46+to log in to the database. If [](#opt-services.keycloak.database.host)
47+and [](#opt-services.keycloak.database.createLocally)
48+are kept at their defaults, the database role
49+`keycloak` with that password is provisioned
50+on the local database instance.
51+52+::: {.warning}
53+The path should be provided as a string, not a Nix path, since Nix
54+paths are copied into the world readable Nix store.
55+:::
56+57+## Hostname {#module-services-keycloak-hostname}
58+59+The hostname is used to build the public URL used as base for
60+all frontend requests and must be configured through
61+[](#opt-services.keycloak.settings.hostname).
62+63+::: {.note}
64+If you're migrating an old Wildfly based Keycloak instance
65+and want to keep compatibility with your current clients,
66+you'll likely want to set [](#opt-services.keycloak.settings.http-relative-path)
67+to `/auth`. See the option description
68+for more details.
69+:::
70+71+[](#opt-services.keycloak.settings.hostname-strict-backchannel)
72+determines whether Keycloak should force all requests to go
73+through the frontend URL. By default,
74+Keycloak allows backend requests to
75+instead use its local hostname or IP address and may also
76+advertise it to clients through its OpenID Connect Discovery
77+endpoint.
78+79+For more information on hostname configuration, see the [Hostname
80+section of the Keycloak Server Installation and Configuration
81+Guide](https://www.keycloak.org/server/hostname).
82+83+## Setting up TLS/SSL {#module-services-keycloak-tls}
84+85+By default, Keycloak won't accept
86+unsecured HTTP connections originating from outside its local
87+network.
88+89+HTTPS support requires a TLS/SSL certificate and a private key,
90+both [PEM formatted](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail).
91+Their paths should be set through
92+[](#opt-services.keycloak.sslCertificate) and
93+[](#opt-services.keycloak.sslCertificateKey).
94+95+::: {.warning}
96+ The paths should be provided as a strings, not a Nix paths,
97+since Nix paths are copied into the world readable Nix store.
98+:::
99+100+## Themes {#module-services-keycloak-themes}
101+102+You can package custom themes and make them visible to
103+Keycloak through [](#opt-services.keycloak.themes). See the
104+[Themes section of the Keycloak Server Development Guide](
105+ https://www.keycloak.org/docs/latest/server_development/#_themes
106+) and the description of the aforementioned NixOS option for
107+more information.
108+109+## Configuration file settings {#module-services-keycloak-settings}
110+111+Keycloak server configuration parameters can be set in
112+[](#opt-services.keycloak.settings). These correspond
113+directly to options in
114+{file}`conf/keycloak.conf`. Some of the most
115+important parameters are documented as suboptions, the rest can
116+be found in the [All
117+configuration section of the Keycloak Server Installation and
118+Configuration Guide](https://www.keycloak.org/server/all-config).
119+120+Options containing secret data should be set to an attribute
121+set containing the attribute `_secret` - a
122+string pointing to a file containing the value the option
123+should be set to. See the description of
124+[](#opt-services.keycloak.settings) for an example.
125+126+## Example configuration {#module-services-keycloak-example-config}
127+128+A basic configuration with some custom settings could look like this:
129+```
130+services.keycloak = {
131+ enable = true;
132+ settings = {
133+ hostname = "keycloak.example.com";
134+ hostname-strict-backchannel = true;
135+ };
136+ initialAdminPassword = "e6Wcm0RrtegMEHl"; # change on first login
137+ sslCertificate = "/run/keys/ssl_cert";
138+ sslCertificateKey = "/run/keys/ssl_key";
139+ database.passwordFile = "/run/keys/db_password";
140+};
141+```
+172-197
nixos/modules/services/web-apps/keycloak.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-keycloak">
6- <title>Keycloak</title>
7- <para>
8- <link xlink:href="https://www.keycloak.org/">Keycloak</link> is an
9- open source identity and access management server with support for
10- <link xlink:href="https://openid.net/connect/">OpenID
11- Connect</link>, <link xlink:href="https://oauth.net/2/">OAUTH
12- 2.0</link> and <link
13- xlink:href="https://en.wikipedia.org/wiki/SAML_2.0">SAML
14- 2.0</link>.
15- </para>
16- <section xml:id="module-services-keycloak-admin">
17- <title>Administration</title>
18- <para>
19- An administrative user with the username
20- <literal>admin</literal> is automatically created in the
21- <literal>master</literal> realm. Its initial password can be
22- configured by setting <xref linkend="opt-services.keycloak.initialAdminPassword" />
23- and defaults to <literal>changeme</literal>. The password is
24- not stored safely and should be changed immediately in the
25- admin panel.
26- </para>
27-28- <para>
29- Refer to the <link
30- xlink:href="https://www.keycloak.org/docs/latest/server_admin/index.html">
31- Keycloak Server Administration Guide</link> for information on
32- how to administer your <productname>Keycloak</productname>
33- instance.
34- </para>
35- </section>
36-37- <section xml:id="module-services-keycloak-database">
38- <title>Database access</title>
39- <para>
40- <productname>Keycloak</productname> can be used with either
41- <productname>PostgreSQL</productname>,
42- <productname>MariaDB</productname> or
43- <productname>MySQL</productname>. Which one is used can be
44- configured in <xref
45- linkend="opt-services.keycloak.database.type" />. The selected
46- database will automatically be enabled and a database and role
47- created unless <xref
48- linkend="opt-services.keycloak.database.host" /> is changed
49- from its default of <literal>localhost</literal> or <xref
50- linkend="opt-services.keycloak.database.createLocally" /> is
51- set to <literal>false</literal>.
52- </para>
53-54- <para>
55- External database access can also be configured by setting
56- <xref linkend="opt-services.keycloak.database.host" />, <xref
57- linkend="opt-services.keycloak.database.name" />, <xref
58- linkend="opt-services.keycloak.database.username" />, <xref
59- linkend="opt-services.keycloak.database.useSSL" /> and <xref
60- linkend="opt-services.keycloak.database.caCert" /> as
61- appropriate. Note that you need to manually create the database
62- and allow the configured database user full access to it.
63- </para>
64-65- <para>
66- <xref linkend="opt-services.keycloak.database.passwordFile" />
67- must be set to the path to a file containing the password used
68- to log in to the database. If <xref linkend="opt-services.keycloak.database.host" />
69- and <xref linkend="opt-services.keycloak.database.createLocally" />
70- are kept at their defaults, the database role
71- <literal>keycloak</literal> with that password is provisioned
72- on the local database instance.
73- </para>
74-75- <warning>
76- <para>
77- The path should be provided as a string, not a Nix path, since Nix
78- paths are copied into the world readable Nix store.
79- </para>
80- </warning>
81- </section>
82-83- <section xml:id="module-services-keycloak-hostname">
84- <title>Hostname</title>
85- <para>
86- The hostname is used to build the public URL used as base for
87- all frontend requests and must be configured through <xref
88- linkend="opt-services.keycloak.settings.hostname" />.
89- </para>
90-91- <note>
92- <para>
93- If you're migrating an old Wildfly based Keycloak instance
94- and want to keep compatibility with your current clients,
95- you'll likely want to set <xref
96- linkend="opt-services.keycloak.settings.http-relative-path"
97- /> to <literal>/auth</literal>. See the option description
98- for more details.
99- </para>
100- </note>
101-102- <para>
103- <xref linkend="opt-services.keycloak.settings.hostname-strict-backchannel" />
104- determines whether Keycloak should force all requests to go
105- through the frontend URL. By default,
106- <productname>Keycloak</productname> allows backend requests to
107- instead use its local hostname or IP address and may also
108- advertise it to clients through its OpenID Connect Discovery
109- endpoint.
110- </para>
111-112- <para>
113- For more information on hostname configuration, see the <link
114- xlink:href="https://www.keycloak.org/server/hostname">Hostname
115- section of the Keycloak Server Installation and Configuration
116- Guide</link>.
117- </para>
118- </section>
119-120- <section xml:id="module-services-keycloak-tls">
121- <title>Setting up TLS/SSL</title>
122- <para>
123- By default, <productname>Keycloak</productname> won't accept
124- unsecured HTTP connections originating from outside its local
125- network.
126- </para>
127-128- <para>
129- HTTPS support requires a TLS/SSL certificate and a private key,
130- both <link
131- xlink:href="https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail">PEM
132- formatted</link>. Their paths should be set through <xref
133- linkend="opt-services.keycloak.sslCertificate" /> and <xref
134- linkend="opt-services.keycloak.sslCertificateKey" />.
135- </para>
136-137- <warning>
138- <para>
139- The paths should be provided as a strings, not a Nix paths,
140- since Nix paths are copied into the world readable Nix store.
141- </para>
142- </warning>
143- </section>
144-145- <section xml:id="module-services-keycloak-themes">
146- <title>Themes</title>
147- <para>
148- You can package custom themes and make them visible to
149- Keycloak through <xref linkend="opt-services.keycloak.themes"
150- />. See the <link
151- xlink:href="https://www.keycloak.org/docs/latest/server_development/#_themes">
152- Themes section of the Keycloak Server Development Guide</link>
153- and the description of the aforementioned NixOS option for
154- more information.
155- </para>
156- </section>
157-158- <section xml:id="module-services-keycloak-settings">
159- <title>Configuration file settings</title>
160- <para>
161- Keycloak server configuration parameters can be set in <xref
162- linkend="opt-services.keycloak.settings" />. These correspond
163- directly to options in
164- <filename>conf/keycloak.conf</filename>. Some of the most
165- important parameters are documented as suboptions, the rest can
166- be found in the <link
167- xlink:href="https://www.keycloak.org/server/all-config">All
168- configuration section of the Keycloak Server Installation and
169- Configuration Guide</link>.
170- </para>
171-172- <para>
173- Options containing secret data should be set to an attribute
174- set containing the attribute <literal>_secret</literal> - a
175- string pointing to a file containing the value the option
176- should be set to. See the description of <xref
177- linkend="opt-services.keycloak.settings" /> for an example.
178- </para>
179- </section>
180-181-182- <section xml:id="module-services-keycloak-example-config">
183- <title>Example configuration</title>
184- <para>
185- A basic configuration with some custom settings could look like this:
186-<programlisting>
187services.keycloak = {
188- <link linkend="opt-services.keycloak.enable">enable</link> = true;
189 settings = {
190- <link linkend="opt-services.keycloak.settings.hostname">hostname</link> = "keycloak.example.com";
191- <link linkend="opt-services.keycloak.settings.hostname-strict-backchannel">hostname-strict-backchannel</link> = true;
192 };
193- <link linkend="opt-services.keycloak.initialAdminPassword">initialAdminPassword</link> = "e6Wcm0RrtegMEHl"; # change on first login
194- <link linkend="opt-services.keycloak.sslCertificate">sslCertificate</link> = "/run/keys/ssl_cert";
195- <link linkend="opt-services.keycloak.sslCertificateKey">sslCertificateKey</link> = "/run/keys/ssl_key";
196- <link linkend="opt-services.keycloak.database.passwordFile">database.passwordFile</link> = "/run/keys/db_password";
197};
198</programlisting>
199- </para>
200-201- </section>
202- </chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-keycloak">
4+ <title>Keycloak</title>
5+ <para>
6+ <link xlink:href="https://www.keycloak.org/">Keycloak</link> is an
7+ open source identity and access management server with support for
8+ <link xlink:href="https://openid.net/connect/">OpenID
9+ Connect</link>, <link xlink:href="https://oauth.net/2/">OAUTH
10+ 2.0</link> and
11+ <link xlink:href="https://en.wikipedia.org/wiki/SAML_2.0">SAML
12+ 2.0</link>.
13+ </para>
14+ <section xml:id="module-services-keycloak-admin">
15+ <title>Administration</title>
16+ <para>
17+ An administrative user with the username <literal>admin</literal>
18+ is automatically created in the <literal>master</literal> realm.
19+ Its initial password can be configured by setting
20+ <xref linkend="opt-services.keycloak.initialAdminPassword" /> and
21+ defaults to <literal>changeme</literal>. The password is not
22+ stored safely and should be changed immediately in the admin
23+ panel.
24+ </para>
25+ <para>
26+ Refer to the
27+ <link xlink:href="https://www.keycloak.org/docs/latest/server_admin/index.html">Keycloak
28+ Server Administration Guide</link> for information on how to
29+ administer your Keycloak instance.
30+ </para>
31+ </section>
32+ <section xml:id="module-services-keycloak-database">
33+ <title>Database access</title>
34+ <para>
35+ Keycloak can be used with either PostgreSQL, MariaDB or MySQL.
36+ Which one is used can be configured in
37+ <xref linkend="opt-services.keycloak.database.type" />. The
38+ selected database will automatically be enabled and a database and
39+ role created unless
40+ <xref linkend="opt-services.keycloak.database.host" /> is changed
41+ from its default of <literal>localhost</literal> or
42+ <xref linkend="opt-services.keycloak.database.createLocally" /> is
43+ set to <literal>false</literal>.
44+ </para>
45+ <para>
46+ External database access can also be configured by setting
47+ <xref linkend="opt-services.keycloak.database.host" />,
48+ <xref linkend="opt-services.keycloak.database.name" />,
49+ <xref linkend="opt-services.keycloak.database.username" />,
50+ <xref linkend="opt-services.keycloak.database.useSSL" /> and
51+ <xref linkend="opt-services.keycloak.database.caCert" /> as
52+ appropriate. Note that you need to manually create the database
53+ and allow the configured database user full access to it.
54+ </para>
55+ <para>
56+ <xref linkend="opt-services.keycloak.database.passwordFile" />
57+ must be set to the path to a file containing the password used to
58+ log in to the database. If
59+ <xref linkend="opt-services.keycloak.database.host" /> and
60+ <xref linkend="opt-services.keycloak.database.createLocally" />
61+ are kept at their defaults, the database role
62+ <literal>keycloak</literal> with that password is provisioned on
63+ the local database instance.
64+ </para>
65+ <warning>
66+ <para>
67+ The path should be provided as a string, not a Nix path, since
68+ Nix paths are copied into the world readable Nix store.
69+ </para>
70+ </warning>
71+ </section>
72+ <section xml:id="module-services-keycloak-hostname">
73+ <title>Hostname</title>
74+ <para>
75+ The hostname is used to build the public URL used as base for all
76+ frontend requests and must be configured through
77+ <xref linkend="opt-services.keycloak.settings.hostname" />.
78+ </para>
79+ <note>
80+ <para>
81+ If you’re migrating an old Wildfly based Keycloak instance and
82+ want to keep compatibility with your current clients, you’ll
83+ likely want to set
84+ <xref linkend="opt-services.keycloak.settings.http-relative-path" />
85+ to <literal>/auth</literal>. See the option description for more
86+ details.
87+ </para>
88+ </note>
89+ <para>
90+ <xref linkend="opt-services.keycloak.settings.hostname-strict-backchannel" />
91+ determines whether Keycloak should force all requests to go
92+ through the frontend URL. By default, Keycloak allows backend
93+ requests to instead use its local hostname or IP address and may
94+ also advertise it to clients through its OpenID Connect Discovery
95+ endpoint.
96+ </para>
97+ <para>
98+ For more information on hostname configuration, see the
99+ <link xlink:href="https://www.keycloak.org/server/hostname">Hostname
100+ section of the Keycloak Server Installation and Configuration
101+ Guide</link>.
102+ </para>
103+ </section>
104+ <section xml:id="module-services-keycloak-tls">
105+ <title>Setting up TLS/SSL</title>
106+ <para>
107+ By default, Keycloak won’t accept unsecured HTTP connections
108+ originating from outside its local network.
109+ </para>
110+ <para>
111+ HTTPS support requires a TLS/SSL certificate and a private key,
112+ both
113+ <link xlink:href="https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail">PEM
114+ formatted</link>. Their paths should be set through
115+ <xref linkend="opt-services.keycloak.sslCertificate" /> and
116+ <xref linkend="opt-services.keycloak.sslCertificateKey" />.
117+ </para>
118+ <warning>
119+ <para>
120+ The paths should be provided as a strings, not a Nix paths,
121+ since Nix paths are copied into the world readable Nix store.
122+ </para>
123+ </warning>
124+ </section>
125+ <section xml:id="module-services-keycloak-themes">
126+ <title>Themes</title>
127+ <para>
128+ You can package custom themes and make them visible to Keycloak
129+ through <xref linkend="opt-services.keycloak.themes" />. See the
130+ <link xlink:href="https://www.keycloak.org/docs/latest/server_development/#_themes">Themes
131+ section of the Keycloak Server Development Guide</link> and the
132+ description of the aforementioned NixOS option for more
133+ information.
134+ </para>
135+ </section>
136+ <section xml:id="module-services-keycloak-settings">
137+ <title>Configuration file settings</title>
138+ <para>
139+ Keycloak server configuration parameters can be set in
140+ <xref linkend="opt-services.keycloak.settings" />. These
141+ correspond directly to options in
142+ <filename>conf/keycloak.conf</filename>. Some of the most
143+ important parameters are documented as suboptions, the rest can be
144+ found in the
145+ <link xlink:href="https://www.keycloak.org/server/all-config">All
146+ configuration section of the Keycloak Server Installation and
147+ Configuration Guide</link>.
148+ </para>
149+ <para>
150+ Options containing secret data should be set to an attribute set
151+ containing the attribute <literal>_secret</literal> - a string
152+ pointing to a file containing the value the option should be set
153+ to. See the description of
154+ <xref linkend="opt-services.keycloak.settings" /> for an example.
155+ </para>
156+ </section>
157+ <section xml:id="module-services-keycloak-example-config">
158+ <title>Example configuration</title>
159+ <para>
160+ A basic configuration with some custom settings could look like
161+ this:
162+ </para>
163+ <programlisting>
00000000000000000000000164services.keycloak = {
165+ enable = true;
166 settings = {
167+ hostname = "keycloak.example.com";
168+ hostname-strict-backchannel = true;
169 };
170+ initialAdminPassword = "e6Wcm0RrtegMEHl"; # change on first login
171+ sslCertificate = "/run/keys/ssl_cert";
172+ sslCertificateKey = "/run/keys/ssl_key";
173+ database.passwordFile = "/run/keys/db_password";
174};
175</programlisting>
176+ </section>
177+</chapter>
00
-2
nixos/modules/services/web-apps/lemmy.nix
···6in
7{
8 meta.maintainers = with maintainers; [ happysalada ];
9- # Don't edit the docbook xml directly, edit the md and generate it:
10- # `pandoc lemmy.md -t docbook --top-level-division=chapter --extract-media=media -f markdown+smart > lemmy.xml`
11 meta.doc = ./lemmy.xml;
1213 imports = [
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-lemmy">
4 <title>Lemmy</title>
5 <para>
-107
nixos/modules/services/web-apps/matomo-doc.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-matomo">
6- <title>Matomo</title>
7- <para>
8- Matomo is a real-time web analytics application. This module configures
9- php-fpm as backend for Matomo, optionally configuring an nginx vhost as well.
10- </para>
11- <para>
12- An automatic setup is not suported by Matomo, so you need to configure Matomo
13- itself in the browser-based Matomo setup.
14- </para>
15- <section xml:id="module-services-matomo-database-setup">
16- <title>Database Setup</title>
17-18- <para>
19- You also need to configure a MariaDB or MySQL database and -user for Matomo
20- yourself, and enter those credentials in your browser. You can use
21- passwordless database authentication via the UNIX_SOCKET authentication
22- plugin with the following SQL commands:
23-<programlisting>
24-# For MariaDB
25-INSTALL PLUGIN unix_socket SONAME 'auth_socket';
26-CREATE DATABASE matomo;
27-CREATE USER 'matomo'@'localhost' IDENTIFIED WITH unix_socket;
28-GRANT ALL PRIVILEGES ON matomo.* TO 'matomo'@'localhost';
29-30-# For MySQL
31-INSTALL PLUGIN auth_socket SONAME 'auth_socket.so';
32-CREATE DATABASE matomo;
33-CREATE USER 'matomo'@'localhost' IDENTIFIED WITH auth_socket;
34-GRANT ALL PRIVILEGES ON matomo.* TO 'matomo'@'localhost';
35-</programlisting>
36- Then fill in <literal>matomo</literal> as database user and database name,
37- and leave the password field blank. This authentication works by allowing
38- only the <literal>matomo</literal> unix user to authenticate as the
39- <literal>matomo</literal> database user (without needing a password), but no
40- other users. For more information on passwordless login, see
41- <link xlink:href="https://mariadb.com/kb/en/mariadb/unix_socket-authentication-plugin/" />.
42- </para>
43-44- <para>
45- Of course, you can use password based authentication as well, e.g. when the
46- database is not on the same host.
47- </para>
48- </section>
49- <section xml:id="module-services-matomo-archive-processing">
50- <title>Archive Processing</title>
51-52- <para>
53- This module comes with the systemd service
54- <literal>matomo-archive-processing.service</literal> and a timer that
55- automatically triggers archive processing every hour. This means that you
56- can safely
57- <link xlink:href="https://matomo.org/docs/setup-auto-archiving/#disable-browser-triggers-for-matomo-archiving-and-limit-matomo-reports-to-updating-every-hour">
58- disable browser triggers for Matomo archiving </link> at
59- <literal>Administration > System > General Settings</literal>.
60- </para>
61-62- <para>
63- With automatic archive processing, you can now also enable to
64- <link xlink:href="https://matomo.org/docs/privacy/#step-2-delete-old-visitors-logs">
65- delete old visitor logs </link> at <literal>Administration > System >
66- Privacy</literal>, but make sure that you run <literal>systemctl start
67- matomo-archive-processing.service</literal> at least once without errors if
68- you have already collected data before, so that the reports get archived
69- before the source data gets deleted.
70- </para>
71- </section>
72- <section xml:id="module-services-matomo-backups">
73- <title>Backup</title>
74-75- <para>
76- You only need to take backups of your MySQL database and the
77- <filename>/var/lib/matomo/config/config.ini.php</filename> file. Use a user
78- in the <literal>matomo</literal> group or root to access the file. For more
79- information, see
80- <link xlink:href="https://matomo.org/faq/how-to-install/faq_138/" />.
81- </para>
82- </section>
83- <section xml:id="module-services-matomo-issues">
84- <title>Issues</title>
85-86- <itemizedlist>
87- <listitem>
88- <para>
89- Matomo will warn you that the JavaScript tracker is not writable. This is
90- because it's located in the read-only nix store. You can safely ignore
91- this, unless you need a plugin that needs JavaScript tracker access.
92- </para>
93- </listitem>
94- </itemizedlist>
95- </section>
96- <section xml:id="module-services-matomo-other-web-servers">
97- <title>Using other Web Servers than nginx</title>
98-99- <para>
100- You can use other web servers by forwarding calls for
101- <filename>index.php</filename> and <filename>piwik.php</filename> to the
102- <literal><link linkend="opt-services.phpfpm.pools._name_.socket">services.phpfpm.pools.<name>.socket</link></literal> fastcgi unix socket. You can use
103- the nginx configuration in the module code as a reference to what else
104- should be configured.
105- </para>
106- </section>
107-</chapter>
···1+# Matomo {#module-services-matomo}
2+3+Matomo is a real-time web analytics application. This module configures
4+php-fpm as backend for Matomo, optionally configuring an nginx vhost as well.
5+6+An automatic setup is not suported by Matomo, so you need to configure Matomo
7+itself in the browser-based Matomo setup.
8+9+## Database Setup {#module-services-matomo-database-setup}
10+11+You also need to configure a MariaDB or MySQL database and -user for Matomo
12+yourself, and enter those credentials in your browser. You can use
13+passwordless database authentication via the UNIX_SOCKET authentication
14+plugin with the following SQL commands:
15+```
16+# For MariaDB
17+INSTALL PLUGIN unix_socket SONAME 'auth_socket';
18+CREATE DATABASE matomo;
19+CREATE USER 'matomo'@'localhost' IDENTIFIED WITH unix_socket;
20+GRANT ALL PRIVILEGES ON matomo.* TO 'matomo'@'localhost';
21+22+# For MySQL
23+INSTALL PLUGIN auth_socket SONAME 'auth_socket.so';
24+CREATE DATABASE matomo;
25+CREATE USER 'matomo'@'localhost' IDENTIFIED WITH auth_socket;
26+GRANT ALL PRIVILEGES ON matomo.* TO 'matomo'@'localhost';
27+```
28+Then fill in `matomo` as database user and database name,
29+and leave the password field blank. This authentication works by allowing
30+only the `matomo` unix user to authenticate as the
31+`matomo` database user (without needing a password), but no
32+other users. For more information on passwordless login, see
33+<https://mariadb.com/kb/en/mariadb/unix_socket-authentication-plugin/>.
34+35+Of course, you can use password based authentication as well, e.g. when the
36+database is not on the same host.
37+38+## Archive Processing {#module-services-matomo-archive-processing}
39+40+This module comes with the systemd service
41+`matomo-archive-processing.service` and a timer that
42+automatically triggers archive processing every hour. This means that you
43+can safely
44+[disable browser triggers for Matomo archiving](
45+https://matomo.org/docs/setup-auto-archiving/#disable-browser-triggers-for-matomo-archiving-and-limit-matomo-reports-to-updating-every-hour
46+) at
47+`Administration > System > General Settings`.
48+49+With automatic archive processing, you can now also enable to
50+[delete old visitor logs](https://matomo.org/docs/privacy/#step-2-delete-old-visitors-logs)
51+at `Administration > System > Privacy`, but make sure that you run `systemctl start
52+matomo-archive-processing.service` at least once without errors if
53+you have already collected data before, so that the reports get archived
54+before the source data gets deleted.
55+56+## Backup {#module-services-matomo-backups}
57+58+You only need to take backups of your MySQL database and the
59+{file}`/var/lib/matomo/config/config.ini.php` file. Use a user
60+in the `matomo` group or root to access the file. For more
61+information, see
62+<https://matomo.org/faq/how-to-install/faq_138/>.
63+64+## Issues {#module-services-matomo-issues}
65+66+ - Matomo will warn you that the JavaScript tracker is not writable. This is
67+ because it's located in the read-only nix store. You can safely ignore
68+ this, unless you need a plugin that needs JavaScript tracker access.
69+70+## Using other Web Servers than nginx {#module-services-matomo-other-web-servers}
71+72+You can use other web servers by forwarding calls for
73+{file}`index.php` and {file}`piwik.php` to the
74+[`services.phpfpm.pools.<name>.socket`](#opt-services.phpfpm.pools._name_.socket)
75+fastcgi unix socket. You can use
76+the nginx configuration in the module code as a reference to what else
77+should be configured.
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-matomo">
4+ <title>Matomo</title>
5+ <para>
6+ Matomo is a real-time web analytics application. This module
7+ configures php-fpm as backend for Matomo, optionally configuring an
8+ nginx vhost as well.
9+ </para>
10+ <para>
11+ An automatic setup is not suported by Matomo, so you need to
12+ configure Matomo itself in the browser-based Matomo setup.
13+ </para>
14+ <section xml:id="module-services-matomo-database-setup">
15+ <title>Database Setup</title>
16+ <para>
17+ You also need to configure a MariaDB or MySQL database and -user
18+ for Matomo yourself, and enter those credentials in your browser.
19+ You can use passwordless database authentication via the
20+ UNIX_SOCKET authentication plugin with the following SQL commands:
21+ </para>
22+ <programlisting>
23+# For MariaDB
24+INSTALL PLUGIN unix_socket SONAME 'auth_socket';
25+CREATE DATABASE matomo;
26+CREATE USER 'matomo'@'localhost' IDENTIFIED WITH unix_socket;
27+GRANT ALL PRIVILEGES ON matomo.* TO 'matomo'@'localhost';
28+29+# For MySQL
30+INSTALL PLUGIN auth_socket SONAME 'auth_socket.so';
31+CREATE DATABASE matomo;
32+CREATE USER 'matomo'@'localhost' IDENTIFIED WITH auth_socket;
33+GRANT ALL PRIVILEGES ON matomo.* TO 'matomo'@'localhost';
34+</programlisting>
35+ <para>
36+ Then fill in <literal>matomo</literal> as database user and
37+ database name, and leave the password field blank. This
38+ authentication works by allowing only the
39+ <literal>matomo</literal> unix user to authenticate as the
40+ <literal>matomo</literal> database user (without needing a
41+ password), but no other users. For more information on
42+ passwordless login, see
43+ <link xlink:href="https://mariadb.com/kb/en/mariadb/unix_socket-authentication-plugin/">https://mariadb.com/kb/en/mariadb/unix_socket-authentication-plugin/</link>.
44+ </para>
45+ <para>
46+ Of course, you can use password based authentication as well, e.g.
47+ when the database is not on the same host.
48+ </para>
49+ </section>
50+ <section xml:id="module-services-matomo-archive-processing">
51+ <title>Archive Processing</title>
52+ <para>
53+ This module comes with the systemd service
54+ <literal>matomo-archive-processing.service</literal> and a timer
55+ that automatically triggers archive processing every hour. This
56+ means that you can safely
57+ <link xlink:href="https://matomo.org/docs/setup-auto-archiving/#disable-browser-triggers-for-matomo-archiving-and-limit-matomo-reports-to-updating-every-hour">disable
58+ browser triggers for Matomo archiving</link> at
59+ <literal>Administration > System > General Settings</literal>.
60+ </para>
61+ <para>
62+ With automatic archive processing, you can now also enable to
63+ <link xlink:href="https://matomo.org/docs/privacy/#step-2-delete-old-visitors-logs">delete
64+ old visitor logs</link> at
65+ <literal>Administration > System > Privacy</literal>, but
66+ make sure that you run
67+ <literal>systemctl start matomo-archive-processing.service</literal>
68+ at least once without errors if you have already collected data
69+ before, so that the reports get archived before the source data
70+ gets deleted.
71+ </para>
72+ </section>
73+ <section xml:id="module-services-matomo-backups">
74+ <title>Backup</title>
75+ <para>
76+ You only need to take backups of your MySQL database and the
77+ <filename>/var/lib/matomo/config/config.ini.php</filename> file.
78+ Use a user in the <literal>matomo</literal> group or root to
79+ access the file. For more information, see
80+ <link xlink:href="https://matomo.org/faq/how-to-install/faq_138/">https://matomo.org/faq/how-to-install/faq_138/</link>.
81+ </para>
82+ </section>
83+ <section xml:id="module-services-matomo-issues">
84+ <title>Issues</title>
85+ <itemizedlist spacing="compact">
86+ <listitem>
87+ <para>
88+ Matomo will warn you that the JavaScript tracker is not
89+ writable. This is because it’s located in the read-only nix
90+ store. You can safely ignore this, unless you need a plugin
91+ that needs JavaScript tracker access.
92+ </para>
93+ </listitem>
94+ </itemizedlist>
95+ </section>
96+ <section xml:id="module-services-matomo-other-web-servers">
97+ <title>Using other Web Servers than nginx</title>
98+ <para>
99+ You can use other web servers by forwarding calls for
100+ <filename>index.php</filename> and <filename>piwik.php</filename>
101+ to the
102+ <link linkend="opt-services.phpfpm.pools._name_.socket"><literal>services.phpfpm.pools.<name>.socket</literal></link>
103+ fastcgi unix socket. You can use the nginx configuration in the
104+ module code as a reference to what else should be configured.
105+ </para>
106+ </section>
107+</chapter>
···1+# Nextcloud {#module-services-nextcloud}
2+3+[Nextcloud](https://nextcloud.com/) is an open-source,
4+self-hostable cloud platform. The server setup can be automated using
5+[services.nextcloud](#opt-services.nextcloud.enable). A
6+desktop client is packaged at `pkgs.nextcloud-client`.
7+8+The current default by NixOS is `nextcloud25` which is also the latest
9+major version available.
10+11+## Basic usage {#module-services-nextcloud-basic-usage}
12+13+Nextcloud is a PHP-based application which requires an HTTP server
14+([`services.nextcloud`](#opt-services.nextcloud.enable)
15+optionally supports
16+[`services.nginx`](#opt-services.nginx.enable))
17+and a database (it's recommended to use
18+[`services.postgresql`](#opt-services.postgresql.enable)).
19+20+A very basic configuration may look like this:
21+```
22+{ pkgs, ... }:
23+{
24+ services.nextcloud = {
25+ enable = true;
26+ hostName = "nextcloud.tld";
27+ config = {
28+ dbtype = "pgsql";
29+ dbuser = "nextcloud";
30+ dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself
31+ dbname = "nextcloud";
32+ adminpassFile = "/path/to/admin-pass-file";
33+ adminuser = "root";
34+ };
35+ };
36+37+ services.postgresql = {
38+ enable = true;
39+ ensureDatabases = [ "nextcloud" ];
40+ ensureUsers = [
41+ { name = "nextcloud";
42+ ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES";
43+ }
44+ ];
45+ };
46+47+ # ensure that postgres is running *before* running the setup
48+ systemd.services."nextcloud-setup" = {
49+ requires = ["postgresql.service"];
50+ after = ["postgresql.service"];
51+ };
52+53+ networking.firewall.allowedTCPPorts = [ 80 443 ];
54+}
55+```
56+57+The `hostName` option is used internally to configure an HTTP
58+server using [`PHP-FPM`](https://php-fpm.org/)
59+and `nginx`. The `config` attribute set is
60+used by the imperative installer and all values are written to an additional file
61+to ensure that changes can be applied by changing the module's options.
62+63+In case the application serves multiple domains (those are checked with
64+[`$_SERVER['HTTP_HOST']`](http://php.net/manual/en/reserved.variables.server.php))
65+it's needed to add them to
66+[`services.nextcloud.config.extraTrustedDomains`](#opt-services.nextcloud.config.extraTrustedDomains).
67+68+Auto updates for Nextcloud apps can be enabled using
69+[`services.nextcloud.autoUpdateApps`](#opt-services.nextcloud.autoUpdateApps.enable).
70+71+## Common problems {#module-services-nextcloud-pitfalls-during-upgrade}
72+73+ - **General notes.**
74+ Unfortunately Nextcloud appears to be very stateful when it comes to
75+ managing its own configuration. The config file lives in the home directory
76+ of the `nextcloud` user (by default
77+ `/var/lib/nextcloud/config/config.php`) and is also used to
78+ track several states of the application (e.g., whether installed or not).
79+80+ All configuration parameters are also stored in
81+ {file}`/var/lib/nextcloud/config/override.config.php` which is generated by
82+ the module and linked from the store to ensure that all values from
83+ {file}`config.php` can be modified by the module.
84+ However {file}`config.php` manages the application's state and shouldn't be
85+ touched manually because of that.
86+87+ ::: {.warning}
88+ Don't delete {file}`config.php`! This file
89+ tracks the application's state and a deletion can cause unwanted
90+ side-effects!
91+ :::
92+93+ ::: {.warning}
94+ Don't rerun `nextcloud-occ maintenance:install`!
95+ This command tries to install the application
96+ and can cause unwanted side-effects!
97+ :::
98+ - **Multiple version upgrades.**
99+ Nextcloud doesn't allow to move more than one major-version forward. E.g., if you're on
100+ `v16`, you cannot upgrade to `v18`, you need to upgrade to
101+ `v17` first. This is ensured automatically as long as the
102+ [stateVersion](#opt-system.stateVersion) is declared properly. In that case
103+ the oldest version available (one major behind the one from the previous NixOS
104+ release) will be selected by default and the module will generate a warning that reminds
105+ the user to upgrade to latest Nextcloud *after* that deploy.
106+ - **`Error: Command "upgrade" is not defined.`**
107+ This error usually occurs if the initial installation
108+ ({command}`nextcloud-occ maintenance:install`) has failed. After that, the application
109+ is not installed, but the upgrade is attempted to be executed. Further context can
110+ be found in [NixOS/nixpkgs#111175](https://github.com/NixOS/nixpkgs/issues/111175).
111+112+ First of all, it makes sense to find out what went wrong by looking at the logs
113+ of the installation via {command}`journalctl -u nextcloud-setup` and try to fix
114+ the underlying issue.
115+116+ - If this occurs on an *existing* setup, this is most likely because
117+ the maintenance mode is active. It can be deactivated by running
118+ {command}`nextcloud-occ maintenance:mode --off`. It's advisable though to
119+ check the logs first on why the maintenance mode was activated.
120+ - ::: {.warning}
121+ Only perform the following measures on
122+ *freshly installed instances!*
123+ :::
124+125+ A re-run of the installer can be forced by *deleting*
126+ {file}`/var/lib/nextcloud/config/config.php`. This is the only time
127+ advisable because the fresh install doesn't have any state that can be lost.
128+ In case that doesn't help, an entire re-creation can be forced via
129+ {command}`rm -rf ~nextcloud/`.
130+131+ - **Server-side encryption.**
132+ Nextcloud supports [server-side encryption (SSE)](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html).
133+ This is not an end-to-end encryption, but can be used to encrypt files that will be persisted
134+ to external storage such as S3. Please note that this won't work anymore when using OpenSSL 3
135+ for PHP's openssl extension because this is implemented using the legacy cipher RC4.
136+ If [](#opt-system.stateVersion) is *above* `22.05`,
137+ this is disabled by default. To turn it on again and for further information please refer to
138+ [](#opt-services.nextcloud.enableBrokenCiphersForSSE).
139+140+## Using an alternative webserver as reverse-proxy (e.g. `httpd`) {#module-services-nextcloud-httpd}
141+142+By default, `nginx` is used as reverse-proxy for `nextcloud`.
143+However, it's possible to use e.g. `httpd` by explicitly disabling
144+`nginx` using [](#opt-services.nginx.enable) and fixing the
145+settings `listen.owner` & `listen.group` in the
146+[corresponding `phpfpm` pool](#opt-services.phpfpm.pools).
147+148+An exemplary configuration may look like this:
149+```
150+{ config, lib, pkgs, ... }: {
151+ services.nginx.enable = false;
152+ services.nextcloud = {
153+ enable = true;
154+ hostName = "localhost";
155+156+ /* further, required options */
157+ };
158+ services.phpfpm.pools.nextcloud.settings = {
159+ "listen.owner" = config.services.httpd.user;
160+ "listen.group" = config.services.httpd.group;
161+ };
162+ services.httpd = {
163+ enable = true;
164+ adminAddr = "webmaster@localhost";
165+ extraModules = [ "proxy_fcgi" ];
166+ virtualHosts."localhost" = {
167+ documentRoot = config.services.nextcloud.package;
168+ extraConfig = ''
169+ <Directory "${config.services.nextcloud.package}">
170+ <FilesMatch "\.php$">
171+ <If "-f %{REQUEST_FILENAME}">
172+ SetHandler "proxy:unix:${config.services.phpfpm.pools.nextcloud.socket}|fcgi://localhost/"
173+ </If>
174+ </FilesMatch>
175+ <IfModule mod_rewrite.c>
176+ RewriteEngine On
177+ RewriteBase /
178+ RewriteRule ^index\.php$ - [L]
179+ RewriteCond %{REQUEST_FILENAME} !-f
180+ RewriteCond %{REQUEST_FILENAME} !-d
181+ RewriteRule . /index.php [L]
182+ </IfModule>
183+ DirectoryIndex index.php
184+ Require all granted
185+ Options +FollowSymLinks
186+ </Directory>
187+ '';
188+ };
189+ };
190+}
191+```
192+193+## Installing Apps and PHP extensions {#installing-apps-php-extensions-nextcloud}
194+195+Nextcloud apps are installed statefully through the web interface.
196+Some apps may require extra PHP extensions to be installed.
197+This can be configured with the [](#opt-services.nextcloud.phpExtraExtensions) setting.
198+199+Alternatively, extra apps can also be declared with the [](#opt-services.nextcloud.extraApps) setting.
200+When using this setting, apps can no longer be managed statefully because this can lead to Nextcloud updating apps
201+that are managed by Nix. If you want automatic updates it is recommended that you use web interface to install apps.
202+203+## Maintainer information {#module-services-nextcloud-maintainer-info}
204+205+As stated in the previous paragraph, we must provide a clean upgrade-path for Nextcloud
206+since it cannot move more than one major version forward on a single upgrade. This chapter
207+adds some notes how Nextcloud updates should be rolled out in the future.
208+209+While minor and patch-level updates are no problem and can be done directly in the
210+package-expression (and should be backported to supported stable branches after that),
211+major-releases should be added in a new attribute (e.g. Nextcloud `v19.0.0`
212+should be available in `nixpkgs` as `pkgs.nextcloud19`).
213+To provide simple upgrade paths it's generally useful to backport those as well to stable
214+branches. As long as the package-default isn't altered, this won't break existing setups.
215+After that, the versioning-warning in the `nextcloud`-module should be
216+updated to make sure that the
217+[package](#opt-services.nextcloud.package)-option selects the latest version
218+on fresh setups.
219+220+If major-releases will be abandoned by upstream, we should check first if those are needed
221+in NixOS for a safe upgrade-path before removing those. In that case we should keep those
222+packages, but mark them as insecure in an expression like this (in
223+`<nixpkgs/pkgs/servers/nextcloud/default.nix>`):
224+```
225+/* ... */
226+{
227+ nextcloud17 = generic {
228+ version = "17.0.x";
229+ sha256 = "0000000000000000000000000000000000000000000000000000";
230+ eol = true;
231+ };
232+}
233+```
234+235+Ideally we should make sure that it's possible to jump two NixOS versions forward:
236+i.e. the warnings and the logic in the module should guard a user to upgrade from a
237+Nextcloud on e.g. 19.09 to a Nextcloud on 20.09.
+282-254
nixos/modules/services/web-apps/nextcloud.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-nextcloud">
6- <title>Nextcloud</title>
7- <para>
8- <link xlink:href="https://nextcloud.com/">Nextcloud</link> is an open-source,
9- self-hostable cloud platform. The server setup can be automated using
10- <link linkend="opt-services.nextcloud.enable">services.nextcloud</link>. A
11- desktop client is packaged at <literal>pkgs.nextcloud-client</literal>.
12- </para>
13- <para>
14- The current default by NixOS is <package>nextcloud25</package> which is also the latest
15- major version available.
16- </para>
17- <section xml:id="module-services-nextcloud-basic-usage">
18- <title>Basic usage</title>
19-20 <para>
21- Nextcloud is a PHP-based application which requires an HTTP server
22- (<literal><link linkend="opt-services.nextcloud.enable">services.nextcloud</link></literal>
23- optionally supports
24- <literal><link linkend="opt-services.nginx.enable">services.nginx</link></literal>)
25- and a database (it's recommended to use
26- <literal><link linkend="opt-services.postgresql.enable">services.postgresql</link></literal>).
27 </para>
28-29 <para>
30- A very basic configuration may look like this:
31-<programlisting>{ pkgs, ... }:
000000000000000032{
33 services.nextcloud = {
34- <link linkend="opt-services.nextcloud.enable">enable</link> = true;
35- <link linkend="opt-services.nextcloud.hostName">hostName</link> = "nextcloud.tld";
36 config = {
37- <link linkend="opt-services.nextcloud.config.dbtype">dbtype</link> = "pgsql";
38- <link linkend="opt-services.nextcloud.config.dbuser">dbuser</link> = "nextcloud";
39- <link linkend="opt-services.nextcloud.config.dbhost">dbhost</link> = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself
40- <link linkend="opt-services.nextcloud.config.dbname">dbname</link> = "nextcloud";
41- <link linkend="opt-services.nextcloud.config.adminpassFile">adminpassFile</link> = "/path/to/admin-pass-file";
42- <link linkend="opt-services.nextcloud.config.adminuser">adminuser</link> = "root";
43 };
44 };
4546 services.postgresql = {
47- <link linkend="opt-services.postgresql.enable">enable</link> = true;
48- <link linkend="opt-services.postgresql.ensureDatabases">ensureDatabases</link> = [ "nextcloud" ];
49- <link linkend="opt-services.postgresql.ensureUsers">ensureUsers</link> = [
50- { name = "nextcloud";
51- ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES";
52 }
53 ];
54 };
5556 # ensure that postgres is running *before* running the setup
57- systemd.services."nextcloud-setup" = {
58- requires = ["postgresql.service"];
59- after = ["postgresql.service"];
60 };
6162- <link linkend="opt-networking.firewall.allowedTCPPorts">networking.firewall.allowedTCPPorts</link> = [ 80 443 ];
63-}</programlisting>
64- </para>
65-66- <para>
67- The <literal>hostName</literal> option is used internally to configure an HTTP
68- server using <literal><link xlink:href="https://php-fpm.org/">PHP-FPM</link></literal>
69- and <literal>nginx</literal>. The <literal>config</literal> attribute set is
70- used by the imperative installer and all values are written to an additional file
71- to ensure that changes can be applied by changing the module's options.
72- </para>
73-74- <para>
75- In case the application serves multiple domains (those are checked with
76- <literal><link xlink:href="http://php.net/manual/en/reserved.variables.server.php">$_SERVER['HTTP_HOST']</link></literal>)
77- it's needed to add them to
78- <literal><link linkend="opt-services.nextcloud.config.extraTrustedDomains">services.nextcloud.config.extraTrustedDomains</link></literal>.
79- </para>
80-81- <para>
82- Auto updates for Nextcloud apps can be enabled using
83- <literal><link linkend="opt-services.nextcloud.autoUpdateApps.enable">services.nextcloud.autoUpdateApps</link></literal>.
84-</para>
85-86- </section>
87-88- <section xml:id="module-services-nextcloud-pitfalls-during-upgrade">
89- <title>Common problems</title>
90- <itemizedlist>
91- <listitem>
92- <formalpara>
93- <title>General notes</title>
94- <para>
95- Unfortunately Nextcloud appears to be very stateful when it comes to
96- managing its own configuration. The config file lives in the home directory
97- of the <literal>nextcloud</literal> user (by default
98- <literal>/var/lib/nextcloud/config/config.php</literal>) and is also used to
99- track several states of the application (e.g., whether installed or not).
100- </para>
101- </formalpara>
102 <para>
103- All configuration parameters are also stored in
104- <filename>/var/lib/nextcloud/config/override.config.php</filename> which is generated by
105- the module and linked from the store to ensure that all values from
106- <filename>config.php</filename> can be modified by the module.
107- However <filename>config.php</filename> manages the application's state and shouldn't be
108- touched manually because of that.
0109 </para>
110- <warning>
111- <para>Don't delete <filename>config.php</filename>! This file
112- tracks the application's state and a deletion can cause unwanted
113- side-effects!</para>
114- </warning>
115-116- <warning>
117- <para>Don't rerun <literal>nextcloud-occ
118- maintenance:install</literal>! This command tries to install the application
119- and can cause unwanted side-effects!</para>
120- </warning>
121- </listitem>
122- <listitem>
123- <formalpara>
124- <title>Multiple version upgrades</title>
125- <para>
126- Nextcloud doesn't allow to move more than one major-version forward. E.g., if you're on
127- <literal>v16</literal>, you cannot upgrade to <literal>v18</literal>, you need to upgrade to
128- <literal>v17</literal> first. This is ensured automatically as long as the
129- <link linkend="opt-system.stateVersion">stateVersion</link> is declared properly. In that case
130- the oldest version available (one major behind the one from the previous NixOS
131- release) will be selected by default and the module will generate a warning that reminds
132- the user to upgrade to latest Nextcloud <emphasis>after</emphasis> that deploy.
133- </para>
134- </formalpara>
135- </listitem>
136- <listitem>
137- <formalpara>
138- <title><literal>Error: Command "upgrade" is not defined.</literal></title>
139- <para>
140- This error usually occurs if the initial installation
141- (<command>nextcloud-occ maintenance:install</command>) has failed. After that, the application
142- is not installed, but the upgrade is attempted to be executed. Further context can
143- be found in <link xlink:href="https://github.com/NixOS/nixpkgs/issues/111175">NixOS/nixpkgs#111175</link>.
144- </para>
145- </formalpara>
146 <para>
147- First of all, it makes sense to find out what went wrong by looking at the logs
148- of the installation via <command>journalctl -u nextcloud-setup</command> and try to fix
149- the underlying issue.
150 </para>
000151 <itemizedlist>
152- <listitem>
153- <para>
154- If this occurs on an <emphasis>existing</emphasis> setup, this is most likely because
155- the maintenance mode is active. It can be deactivated by running
156- <command>nextcloud-occ maintenance:mode --off</command>. It's advisable though to
157- check the logs first on why the maintenance mode was activated.
158- </para>
159- </listitem>
160- <listitem>
161- <warning><para>Only perform the following measures on
162- <emphasis>freshly installed instances!</emphasis></para></warning>
163- <para>
164- A re-run of the installer can be forced by <emphasis>deleting</emphasis>
165- <filename>/var/lib/nextcloud/config/config.php</filename>. This is the only time
166- advisable because the fresh install doesn't have any state that can be lost.
167- In case that doesn't help, an entire re-creation can be forced via
168- <command>rm -rf ~nextcloud/</command>.
169- </para>
170- </listitem>
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000171 </itemizedlist>
172- </listitem>
173- <listitem>
174- <formalpara>
175- <title>Server-side encryption</title>
176- <para>
177- Nextcloud supports <link xlink:href="https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html">server-side encryption (SSE)</link>.
178- This is not an end-to-end encryption, but can be used to encrypt files that will be persisted
179- to external storage such as S3. Please note that this won't work anymore when using OpenSSL 3
180- for PHP's openssl extension because this is implemented using the legacy cipher RC4.
181- If <xref linkend="opt-system.stateVersion" /> is <emphasis>above</emphasis> <literal>22.05</literal>,
182- this is disabled by default. To turn it on again and for further information please refer to
183- <xref linkend="opt-services.nextcloud.enableBrokenCiphersForSSE" />.
184- </para>
185- </formalpara>
186- </listitem>
187- </itemizedlist>
188- </section>
189-190- <section xml:id="module-services-nextcloud-httpd">
191- <title>Using an alternative webserver as reverse-proxy (e.g. <literal>httpd</literal>)</title>
192- <para>
193- By default, <package>nginx</package> is used as reverse-proxy for <package>nextcloud</package>.
194- However, it's possible to use e.g. <package>httpd</package> by explicitly disabling
195- <package>nginx</package> using <xref linkend="opt-services.nginx.enable" /> and fixing the
196- settings <literal>listen.owner</literal> & <literal>listen.group</literal> in the
197- <link linkend="opt-services.phpfpm.pools">corresponding <literal>phpfpm</literal> pool</link>.
198- </para>
199- <para>
200- An exemplary configuration may look like this:
201-<programlisting>{ config, lib, pkgs, ... }: {
202- <link linkend="opt-services.nginx.enable">services.nginx.enable</link> = false;
203 services.nextcloud = {
204- <link linkend="opt-services.nextcloud.enable">enable</link> = true;
205- <link linkend="opt-services.nextcloud.hostName">hostName</link> = "localhost";
206207 /* further, required options */
208 };
209- <link linkend="opt-services.phpfpm.pools._name_.settings">services.phpfpm.pools.nextcloud.settings</link> = {
210- "listen.owner" = config.services.httpd.user;
211- "listen.group" = config.services.httpd.group;
212 };
213 services.httpd = {
214- <link linkend="opt-services.httpd.enable">enable</link> = true;
215- <link linkend="opt-services.httpd.adminAddr">adminAddr</link> = "webmaster@localhost";
216- <link linkend="opt-services.httpd.extraModules">extraModules</link> = [ "proxy_fcgi" ];
217- virtualHosts."localhost" = {
218- <link linkend="opt-services.httpd.virtualHosts._name_.documentRoot">documentRoot</link> = config.services.nextcloud.package;
219- <link linkend="opt-services.httpd.virtualHosts._name_.extraConfig">extraConfig</link> = ''
220- <Directory "${config.services.nextcloud.package}">
221- <FilesMatch "\.php$">
222- <If "-f %{REQUEST_FILENAME}">
223- SetHandler "proxy:unix:${config.services.phpfpm.pools.nextcloud.socket}|fcgi://localhost/"
224 </If>
225 </FilesMatch>
226 <IfModule mod_rewrite.c>
···238 '';
239 };
240 };
241-}</programlisting>
242- </para>
243- </section>
244-245- <section xml:id="installing-apps-php-extensions-nextcloud">
246- <title>Installing Apps and PHP extensions</title>
247-248- <para>
249- Nextcloud apps are installed statefully through the web interface.
250-251- Some apps may require extra PHP extensions to be installed.
252- This can be configured with the <xref linkend="opt-services.nextcloud.phpExtraExtensions" /> setting.
253- </para>
254-255- <para>
256- Alternatively, extra apps can also be declared with the <xref linkend="opt-services.nextcloud.extraApps" /> setting.
257- When using this setting, apps can no longer be managed statefully because this can lead to Nextcloud updating apps
258- that are managed by Nix. If you want automatic updates it is recommended that you use web interface to install apps.
259- </para>
260- </section>
261-262- <section xml:id="module-services-nextcloud-maintainer-info">
263- <title>Maintainer information</title>
264-265- <para>
266- As stated in the previous paragraph, we must provide a clean upgrade-path for Nextcloud
267- since it cannot move more than one major version forward on a single upgrade. This chapter
268- adds some notes how Nextcloud updates should be rolled out in the future.
269- </para>
270-271- <para>
272- While minor and patch-level updates are no problem and can be done directly in the
273- package-expression (and should be backported to supported stable branches after that),
274- major-releases should be added in a new attribute (e.g. Nextcloud <literal>v19.0.0</literal>
275- should be available in <literal>nixpkgs</literal> as <literal>pkgs.nextcloud19</literal>).
276- To provide simple upgrade paths it's generally useful to backport those as well to stable
277- branches. As long as the package-default isn't altered, this won't break existing setups.
278- After that, the versioning-warning in the <literal>nextcloud</literal>-module should be
279- updated to make sure that the
280- <link linkend="opt-services.nextcloud.package">package</link>-option selects the latest version
281- on fresh setups.
282- </para>
283-284- <para>
285- If major-releases will be abandoned by upstream, we should check first if those are needed
286- in NixOS for a safe upgrade-path before removing those. In that case we should keep those
287- packages, but mark them as insecure in an expression like this (in
288- <literal><nixpkgs/pkgs/servers/nextcloud/default.nix></literal>):
289-<programlisting>/* ... */
00000290{
291 nextcloud17 = generic {
292- version = "17.0.x";
293- sha256 = "0000000000000000000000000000000000000000000000000000";
294 eol = true;
295 };
296-}</programlisting>
297- </para>
298-299- <para>
300- Ideally we should make sure that it's possible to jump two NixOS versions forward:
301- i.e. the warnings and the logic in the module should guard a user to upgrade from a
302- Nextcloud on e.g. 19.09 to a Nextcloud on 20.09.
303- </para>
304- </section>
305</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-nextcloud">
4+ <title>Nextcloud</title>
0000000000000005 <para>
6+ <link xlink:href="https://nextcloud.com/">Nextcloud</link> is an
7+ open-source, self-hostable cloud platform. The server setup can be
8+ automated using
9+ <link linkend="opt-services.nextcloud.enable">services.nextcloud</link>.
10+ A desktop client is packaged at
11+ <literal>pkgs.nextcloud-client</literal>.
12 </para>
013 <para>
14+ The current default by NixOS is <literal>nextcloud25</literal> which
15+ is also the latest major version available.
16+ </para>
17+ <section xml:id="module-services-nextcloud-basic-usage">
18+ <title>Basic usage</title>
19+ <para>
20+ Nextcloud is a PHP-based application which requires an HTTP server
21+ (<link linkend="opt-services.nextcloud.enable"><literal>services.nextcloud</literal></link>
22+ optionally supports
23+ <link linkend="opt-services.nginx.enable"><literal>services.nginx</literal></link>)
24+ and a database (it’s recommended to use
25+ <link linkend="opt-services.postgresql.enable"><literal>services.postgresql</literal></link>).
26+ </para>
27+ <para>
28+ A very basic configuration may look like this:
29+ </para>
30+ <programlisting>
31+{ pkgs, ... }:
32{
33 services.nextcloud = {
34+ enable = true;
35+ hostName = "nextcloud.tld";
36 config = {
37+ dbtype = "pgsql";
38+ dbuser = "nextcloud";
39+ dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself
40+ dbname = "nextcloud";
41+ adminpassFile = "/path/to/admin-pass-file";
42+ adminuser = "root";
43 };
44 };
4546 services.postgresql = {
47+ enable = true;
48+ ensureDatabases = [ "nextcloud" ];
49+ ensureUsers = [
50+ { name = "nextcloud";
51+ ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES";
52 }
53 ];
54 };
5556 # ensure that postgres is running *before* running the setup
57+ systemd.services."nextcloud-setup" = {
58+ requires = ["postgresql.service"];
59+ after = ["postgresql.service"];
60 };
6162+ networking.firewall.allowedTCPPorts = [ 80 443 ];
63+}
64+</programlisting>
000000000000000000000000000000000000065 <para>
66+ The <literal>hostName</literal> option is used internally to
67+ configure an HTTP server using
68+ <link xlink:href="https://php-fpm.org/"><literal>PHP-FPM</literal></link>
69+ and <literal>nginx</literal>. The <literal>config</literal>
70+ attribute set is used by the imperative installer and all values
71+ are written to an additional file to ensure that changes can be
72+ applied by changing the module’s options.
73 </para>
74+ <para>
75+ In case the application serves multiple domains (those are checked
76+ with
77+ <link xlink:href="http://php.net/manual/en/reserved.variables.server.php"><literal>$_SERVER['HTTP_HOST']</literal></link>)
78+ it’s needed to add them to
79+ <link linkend="opt-services.nextcloud.config.extraTrustedDomains"><literal>services.nextcloud.config.extraTrustedDomains</literal></link>.
80+ </para>
0000000000000000000000000000081 <para>
82+ Auto updates for Nextcloud apps can be enabled using
83+ <link linkend="opt-services.nextcloud.autoUpdateApps.enable"><literal>services.nextcloud.autoUpdateApps</literal></link>.
084 </para>
85+ </section>
86+ <section xml:id="module-services-nextcloud-pitfalls-during-upgrade">
87+ <title>Common problems</title>
88 <itemizedlist>
89+ <listitem>
90+ <para>
91+ <emphasis role="strong">General notes.</emphasis>
92+ Unfortunately Nextcloud appears to be very stateful when it
93+ comes to managing its own configuration. The config file lives
94+ in the home directory of the <literal>nextcloud</literal> user
95+ (by default
96+ <literal>/var/lib/nextcloud/config/config.php</literal>) and
97+ is also used to track several states of the application (e.g.,
98+ whether installed or not).
99+ </para>
100+ <para>
101+ All configuration parameters are also stored in
102+ <filename>/var/lib/nextcloud/config/override.config.php</filename>
103+ which is generated by the module and linked from the store to
104+ ensure that all values from <filename>config.php</filename>
105+ can be modified by the module. However
106+ <filename>config.php</filename> manages the application’s
107+ state and shouldn’t be touched manually because of that.
108+ </para>
109+ <warning>
110+ <para>
111+ Don’t delete <filename>config.php</filename>! This file
112+ tracks the application’s state and a deletion can cause
113+ unwanted side-effects!
114+ </para>
115+ </warning>
116+ <warning>
117+ <para>
118+ Don’t rerun
119+ <literal>nextcloud-occ maintenance:install</literal>! This
120+ command tries to install the application and can cause
121+ unwanted side-effects!
122+ </para>
123+ </warning>
124+ </listitem>
125+ <listitem>
126+ <para>
127+ <emphasis role="strong">Multiple version upgrades.</emphasis>
128+ Nextcloud doesn’t allow to move more than one major-version
129+ forward. E.g., if you’re on <literal>v16</literal>, you cannot
130+ upgrade to <literal>v18</literal>, you need to upgrade to
131+ <literal>v17</literal> first. This is ensured automatically as
132+ long as the
133+ <link linkend="opt-system.stateVersion">stateVersion</link> is
134+ declared properly. In that case the oldest version available
135+ (one major behind the one from the previous NixOS release)
136+ will be selected by default and the module will generate a
137+ warning that reminds the user to upgrade to latest Nextcloud
138+ <emphasis>after</emphasis> that deploy.
139+ </para>
140+ </listitem>
141+ <listitem>
142+ <para>
143+ <emphasis role="strong"><literal>Error: Command "upgrade" is not defined.</literal></emphasis>
144+ This error usually occurs if the initial installation
145+ (<command>nextcloud-occ maintenance:install</command>) has
146+ failed. After that, the application is not installed, but the
147+ upgrade is attempted to be executed. Further context can be
148+ found in
149+ <link xlink:href="https://github.com/NixOS/nixpkgs/issues/111175">NixOS/nixpkgs#111175</link>.
150+ </para>
151+ <para>
152+ First of all, it makes sense to find out what went wrong by
153+ looking at the logs of the installation via
154+ <command>journalctl -u nextcloud-setup</command> and try to
155+ fix the underlying issue.
156+ </para>
157+ <itemizedlist>
158+ <listitem>
159+ <para>
160+ If this occurs on an <emphasis>existing</emphasis> setup,
161+ this is most likely because the maintenance mode is
162+ active. It can be deactivated by running
163+ <command>nextcloud-occ maintenance:mode --off</command>.
164+ It’s advisable though to check the logs first on why the
165+ maintenance mode was activated.
166+ </para>
167+ </listitem>
168+ <listitem>
169+ <warning>
170+ <para>
171+ Only perform the following measures on <emphasis>freshly
172+ installed instances!</emphasis>
173+ </para>
174+ </warning>
175+ <para>
176+ A re-run of the installer can be forced by
177+ <emphasis>deleting</emphasis>
178+ <filename>/var/lib/nextcloud/config/config.php</filename>.
179+ This is the only time advisable because the fresh install
180+ doesn’t have any state that can be lost. In case that
181+ doesn’t help, an entire re-creation can be forced via
182+ <command>rm -rf ~nextcloud/</command>.
183+ </para>
184+ </listitem>
185+ </itemizedlist>
186+ </listitem>
187+ <listitem>
188+ <para>
189+ <emphasis role="strong">Server-side encryption.</emphasis>
190+ Nextcloud supports
191+ <link xlink:href="https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html">server-side
192+ encryption (SSE)</link>. This is not an end-to-end encryption,
193+ but can be used to encrypt files that will be persisted to
194+ external storage such as S3. Please note that this won’t work
195+ anymore when using OpenSSL 3 for PHP’s openssl extension
196+ because this is implemented using the legacy cipher RC4. If
197+ <xref linkend="opt-system.stateVersion" /> is
198+ <emphasis>above</emphasis> <literal>22.05</literal>, this is
199+ disabled by default. To turn it on again and for further
200+ information please refer to
201+ <xref linkend="opt-services.nextcloud.enableBrokenCiphersForSSE" />.
202+ </para>
203+ </listitem>
204 </itemizedlist>
205+ </section>
206+ <section xml:id="module-services-nextcloud-httpd">
207+ <title>Using an alternative webserver as reverse-proxy (e.g.
208+ <literal>httpd</literal>)</title>
209+ <para>
210+ By default, <literal>nginx</literal> is used as reverse-proxy for
211+ <literal>nextcloud</literal>. However, it’s possible to use e.g.
212+ <literal>httpd</literal> by explicitly disabling
213+ <literal>nginx</literal> using
214+ <xref linkend="opt-services.nginx.enable" /> and fixing the
215+ settings <literal>listen.owner</literal> &
216+ <literal>listen.group</literal> in the
217+ <link linkend="opt-services.phpfpm.pools">corresponding
218+ <literal>phpfpm</literal> pool</link>.
219+ </para>
220+ <para>
221+ An exemplary configuration may look like this:
222+ </para>
223+ <programlisting>
224+{ config, lib, pkgs, ... }: {
225+ services.nginx.enable = false;
0000000000226 services.nextcloud = {
227+ enable = true;
228+ hostName = "localhost";
229230 /* further, required options */
231 };
232+ services.phpfpm.pools.nextcloud.settings = {
233+ "listen.owner" = config.services.httpd.user;
234+ "listen.group" = config.services.httpd.group;
235 };
236 services.httpd = {
237+ enable = true;
238+ adminAddr = "webmaster@localhost";
239+ extraModules = [ "proxy_fcgi" ];
240+ virtualHosts."localhost" = {
241+ documentRoot = config.services.nextcloud.package;
242+ extraConfig = ''
243+ <Directory "${config.services.nextcloud.package}">
244+ <FilesMatch "\.php$">
245+ <If "-f %{REQUEST_FILENAME}">
246+ SetHandler "proxy:unix:${config.services.phpfpm.pools.nextcloud.socket}|fcgi://localhost/"
247 </If>
248 </FilesMatch>
249 <IfModule mod_rewrite.c>
···261 '';
262 };
263 };
264+}
265+</programlisting>
266+ </section>
267+ <section xml:id="installing-apps-php-extensions-nextcloud">
268+ <title>Installing Apps and PHP extensions</title>
269+ <para>
270+ Nextcloud apps are installed statefully through the web interface.
271+ Some apps may require extra PHP extensions to be installed. This
272+ can be configured with the
273+ <xref linkend="opt-services.nextcloud.phpExtraExtensions" />
274+ setting.
275+ </para>
276+ <para>
277+ Alternatively, extra apps can also be declared with the
278+ <xref linkend="opt-services.nextcloud.extraApps" /> setting. When
279+ using this setting, apps can no longer be managed statefully
280+ because this can lead to Nextcloud updating apps that are managed
281+ by Nix. If you want automatic updates it is recommended that you
282+ use web interface to install apps.
283+ </para>
284+ </section>
285+ <section xml:id="module-services-nextcloud-maintainer-info">
286+ <title>Maintainer information</title>
287+ <para>
288+ As stated in the previous paragraph, we must provide a clean
289+ upgrade-path for Nextcloud since it cannot move more than one
290+ major version forward on a single upgrade. This chapter adds some
291+ notes how Nextcloud updates should be rolled out in the future.
292+ </para>
293+ <para>
294+ While minor and patch-level updates are no problem and can be done
295+ directly in the package-expression (and should be backported to
296+ supported stable branches after that), major-releases should be
297+ added in a new attribute (e.g. Nextcloud
298+ <literal>v19.0.0</literal> should be available in
299+ <literal>nixpkgs</literal> as
300+ <literal>pkgs.nextcloud19</literal>). To provide simple upgrade
301+ paths it’s generally useful to backport those as well to stable
302+ branches. As long as the package-default isn’t altered, this won’t
303+ break existing setups. After that, the versioning-warning in the
304+ <literal>nextcloud</literal>-module should be updated to make sure
305+ that the
306+ <link linkend="opt-services.nextcloud.package">package</link>-option
307+ selects the latest version on fresh setups.
308+ </para>
309+ <para>
310+ If major-releases will be abandoned by upstream, we should check
311+ first if those are needed in NixOS for a safe upgrade-path before
312+ removing those. In that case we should keep those packages, but
313+ mark them as insecure in an expression like this (in
314+ <literal><nixpkgs/pkgs/servers/nextcloud/default.nix></literal>):
315+ </para>
316+ <programlisting>
317+/* ... */
318{
319 nextcloud17 = generic {
320+ version = "17.0.x";
321+ sha256 = "0000000000000000000000000000000000000000000000000000";
322 eol = true;
323 };
324+}
325+</programlisting>
326+ <para>
327+ Ideally we should make sure that it’s possible to jump two NixOS
328+ versions forward: i.e. the warnings and the logic in the module
329+ should guard a user to upgrade from a Nextcloud on e.g. 19.09 to a
330+ Nextcloud on 20.09.
331+ </para>
332+ </section>
333</chapter>
+1
nixos/modules/services/web-apps/pict-rs.md
···15## Usage {#module-services-pict-rs-usage}
1617pict-rs offers the following endpoints:
018- `POST /image` for uploading an image. Uploaded content must be valid multipart/form-data with an
19 image array located within the `images[]` key
20
···15## Usage {#module-services-pict-rs-usage}
1617pict-rs offers the following endpoints:
18+19- `POST /image` for uploading an image. Uploaded content must be valid multipart/form-data with an
20 image array located within the `images[]` key
21
-2
nixos/modules/services/web-apps/pict-rs.nix
···5in
6{
7 meta.maintainers = with maintainers; [ happysalada ];
8- # Don't edit the docbook xml directly, edit the md and generate it:
9- # `pandoc pict-rs.md -t docbook --top-level-division=chapter --extract-media=media -f markdown+smart > pict-rs.xml`
10 meta.doc = ./pict-rs.xml;
1112 options.services.pict-rs = {
···001<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-pict-rs">
2 <title>Pict-rs</title>
3 <para>
···8 <para>
9 the minimum to start pict-rs is
10 </para>
11- <programlisting language="bash">
12services.pict-rs.enable = true;
13</programlisting>
14 <para>
···18 <section xml:id="module-services-pict-rs-usage">
19 <title>Usage</title>
20 <para>
21- pict-rs offers the following endpoints: -
22- <literal>POST /image</literal> for uploading an image. Uploaded
23- content must be valid multipart/form-data with an image array
24- located within the <literal>images[]</literal> key
25 </para>
26- <programlisting>
27-This endpoint returns the following JSON structure on success with a 201 Created status
28-```json
00000000029{
30 "files": [
31 {
···43 ],
44 "msg": "ok"
45}
46-```
47</programlisting>
48- <itemizedlist>
49 <listitem>
50 <para>
51 <literal>GET /image/download?url=...</literal> Download an
···66 <literal>GET /image/details/original/{file}</literal> for
67 getting the details of a full-resolution image. The returned
68 JSON is structured like so:
69- <literal>json { "width": 800, "height": 537, "content_type": "image/webp", "created_at": [ 2020, 345, 67376, 394363487 ] }</literal>
70 </para>
000000000000071 </listitem>
72 <listitem>
73 <para>
···124 </para>
125 <para>
126 An example of usage could be
127- <literal>GET /image/process.jpg?src=asdf.png&thumbnail=256&blur=3.0</literal>
0000128 which would create a 256x256px JPEG thumbnail and blur it
129 </para>
130 </listitem>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-pict-rs">
4 <title>Pict-rs</title>
5 <para>
···10 <para>
11 the minimum to start pict-rs is
12 </para>
13+ <programlisting language="nix">
14services.pict-rs.enable = true;
15</programlisting>
16 <para>
···20 <section xml:id="module-services-pict-rs-usage">
21 <title>Usage</title>
22 <para>
23+ pict-rs offers the following endpoints:
00024 </para>
25+ <itemizedlist>
26+ <listitem>
27+ <para>
28+ <literal>POST /image</literal> for uploading an image.
29+ Uploaded content must be valid multipart/form-data with an
30+ image array located within the <literal>images[]</literal> key
31+ </para>
32+ <para>
33+ This endpoint returns the following JSON structure on success
34+ with a 201 Created status
35+ </para>
36+ <programlisting language="json">
37{
38 "files": [
39 {
···51 ],
52 "msg": "ok"
53}
054</programlisting>
55+ </listitem>
56 <listitem>
57 <para>
58 <literal>GET /image/download?url=...</literal> Download an
···73 <literal>GET /image/details/original/{file}</literal> for
74 getting the details of a full-resolution image. The returned
75 JSON is structured like so:
076 </para>
77+ <programlisting language="json">
78+{
79+ "width": 800,
80+ "height": 537,
81+ "content_type": "image/webp",
82+ "created_at": [
83+ 2020,
84+ 345,
85+ 67376,
86+ 394363487
87+ ]
88+}
89+</programlisting>
90 </listitem>
91 <listitem>
92 <para>
···143 </para>
144 <para>
145 An example of usage could be
146+ </para>
147+ <programlisting>
148+GET /image/process.jpg?src=asdf.png&thumbnail=256&blur=3.0
149+</programlisting>
150+ <para>
151 which would create a 256x256px JPEG thumbnail and blur it
152 </para>
153 </listitem>
+35
nixos/modules/services/web-apps/plausible.md
···00000000000000000000000000000000000
···1+# Plausible {#module-services-plausible}
2+3+[Plausible](https://plausible.io/) is a privacy-friendly alternative to
4+Google analytics.
5+6+## Basic Usage {#module-services-plausible-basic-usage}
7+8+At first, a secret key is needed to be generated. This can be done with e.g.
9+```ShellSession
10+$ openssl rand -base64 64
11+```
12+13+After that, `plausible` can be deployed like this:
14+```
15+{
16+ services.plausible = {
17+ enable = true;
18+ adminUser = {
19+ # activate is used to skip the email verification of the admin-user that's
20+ # automatically created by plausible. This is only supported if
21+ # postgresql is configured by the module. This is done by default, but
22+ # can be turned off with services.plausible.database.postgres.setup.
23+ activate = true;
24+ email = "admin@localhost";
25+ passwordFile = "/run/secrets/plausible-admin-pwd";
26+ };
27+ server = {
28+ baseUrl = "http://analytics.example.org";
29+ # secretKeybaseFile is a path to the file which contains the secret generated
30+ # with openssl as described above.
31+ secretKeybaseFile = "/run/secrets/plausible-secret-key-base";
32+ };
33+ };
34+}
35+```
+36-42
nixos/modules/services/web-apps/plausible.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-plausible">
6- <title>Plausible</title>
7- <para>
8- <link xlink:href="https://plausible.io/">Plausible</link> is a privacy-friendly alternative to
9- Google analytics.
10- </para>
11- <section xml:id="module-services-plausible-basic-usage">
12- <title>Basic Usage</title>
13 <para>
14- At first, a secret key is needed to be generated. This can be done with e.g.
15- <screen><prompt>$ </prompt>openssl rand -base64 64</screen>
16 </para>
17- <para>
18- After that, <package>plausible</package> can be deployed like this:
19-<programlisting>{
00000000000020 services.plausible = {
21- <link linkend="opt-services.plausible.enable">enable</link> = true;
22 adminUser = {
23- <link linkend="opt-services.plausible.adminUser.activate">activate</link> = true; <co xml:id='ex-plausible-cfg-activate' />
24- <link linkend="opt-services.plausible.adminUser.email">email</link> = "admin@localhost";
25- <link linkend="opt-services.plausible.adminUser.passwordFile">passwordFile</link> = "/run/secrets/plausible-admin-pwd";
000026 };
27 server = {
28- <link linkend="opt-services.plausible.server.baseUrl">baseUrl</link> = "http://analytics.example.org";
29- <link linkend="opt-services.plausible.server.secretKeybaseFile">secretKeybaseFile</link> = "/run/secrets/plausible-secret-key-base"; <co xml:id='ex-plausible-cfg-secretbase' />
0030 };
31 };
32-}</programlisting>
33- <calloutlist>
34- <callout arearefs='ex-plausible-cfg-activate'>
35- <para>
36- <varname>activate</varname> is used to skip the email verification of the admin-user that's
37- automatically created by <package>plausible</package>. This is only supported if
38- <package>postgresql</package> is configured by the module. This is done by default, but
39- can be turned off with <xref linkend="opt-services.plausible.database.postgres.setup" />.
40- </para>
41- </callout>
42- <callout arearefs='ex-plausible-cfg-secretbase'>
43- <para>
44- <varname>secretKeybaseFile</varname> is a path to the file which contains the secret generated
45- with <package>openssl</package> as described above.
46- </para>
47- </callout>
48- </calloutlist>
49- </para>
50- </section>
51</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-plausible">
4+ <title>Plausible</title>
000000005 <para>
6+ <link xlink:href="https://plausible.io/">Plausible</link> is a
7+ privacy-friendly alternative to Google analytics.
8 </para>
9+ <section xml:id="module-services-plausible-basic-usage">
10+ <title>Basic Usage</title>
11+ <para>
12+ At first, a secret key is needed to be generated. This can be done
13+ with e.g.
14+ </para>
15+ <programlisting>
16+$ openssl rand -base64 64
17+</programlisting>
18+ <para>
19+ After that, <literal>plausible</literal> can be deployed like
20+ this:
21+ </para>
22+ <programlisting>
23+{
24 services.plausible = {
25+ enable = true;
26 adminUser = {
27+ # activate is used to skip the email verification of the admin-user that's
28+ # automatically created by plausible. This is only supported if
29+ # postgresql is configured by the module. This is done by default, but
30+ # can be turned off with services.plausible.database.postgres.setup.
31+ activate = true;
32+ email = "admin@localhost";
33+ passwordFile = "/run/secrets/plausible-admin-pwd";
34 };
35 server = {
36+ baseUrl = "http://analytics.example.org";
37+ # secretKeybaseFile is a path to the file which contains the secret generated
38+ # with openssl as described above.
39+ secretKeybaseFile = "/run/secrets/plausible-secret-key-base";
40 };
41 };
42+}
43+</programlisting>
44+ </section>
000000000000000045</chapter>
-139
nixos/modules/services/web-servers/garage-doc.xml
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xmlns:xi="http://www.w3.org/2001/XInclude"
4- version="5.0"
5- xml:id="module-services-garage">
6- <title>Garage</title>
7- <para>
8- <link xlink:href="https://garagehq.deuxfleurs.fr/">Garage</link>
9- is an open-source, self-hostable S3 store, simpler than MinIO, for geodistributed stores.
10- The server setup can be automated using
11- <link linkend="opt-services.garage.enable">services.garage</link>. A
12- client configured to your local Garage instance is available in
13- the global environment as <literal>garage-manage</literal>.
14- </para>
15- <para>
16- The current default by NixOS is <package>garage_0_8</package> which is also the latest
17- major version available.
18- </para>
19- <section xml:id="module-services-garage-upgrade-scenarios">
20- <title>General considerations on upgrades</title>
21-22- <para>
23- Garage provides a cookbook documentation on how to upgrade:
24- <link xlink:href="https://garagehq.deuxfleurs.fr/documentation/cookbook/upgrading/">https://garagehq.deuxfleurs.fr/documentation/cookbook/upgrading/</link>
25- </para>
26-27- <warning>
28- <para>Garage has two types of upgrades: patch-level upgrades and minor/major version upgrades.</para>
29-30- <para>In all cases, you should read the changelog and ideally test the upgrade on a staging cluster.</para>
31-32- <para>Checking the health of your cluster can be achieved using <literal>garage-manage repair</literal>.</para>
33- </warning>
34-35-36- <warning>
37- <para>Until 1.0 is released, patch-level upgrades are considered as minor version upgrades.
38- Minor version upgrades are considered as major version upgrades.
39- i.e. 0.6 to 0.7 is a major version upgrade.</para>
40- </warning>
41-42- <itemizedlist>
43- <listitem>
44- <formalpara>
45- <title>Straightforward upgrades (patch-level upgrades)</title>
46- <para>
47- Upgrades must be performed one by one, i.e. for each node, stop it, upgrade it : change <link linkend="opt-system.stateVersion">stateVersion</link> or <link linkend="opt-services.garage.package">services.garage.package</link>, restart it if it was not already by switching.
48- </para>
49- </formalpara>
50- </listitem>
51-52- <listitem>
53- <formalpara>
54- <title>Multiple version upgrades</title>
55- <para>
56- Garage do not provide any guarantee on moving more than one major-version forward.
57- E.g., if you're on <literal>0.7</literal>, you cannot upgrade to <literal>0.9</literal>.
58- You need to upgrade to <literal>0.8</literal> first.
59-60- As long as <link linkend="opt-system.stateVersion">stateVersion</link> is declared properly,
61- this is enforced automatically. The module will issue a warning to remind the user to upgrade to latest
62- Garage <emphasis>after</emphasis> that deploy.
63- </para>
64- </formalpara>
65- </listitem>
66-</itemizedlist>
67-</section>
68-69-<section xml:id="module-services-garage-advanced-upgrades">
70- <title>Advanced upgrades (minor/major version upgrades)</title>
71- <para>Here are some baseline instructions to handle advanced upgrades in Garage, when in doubt, please refer to upstream instructions.</para>
72-73- <itemizedlist>
74- <listitem><para>Disable API and web access to Garage.</para></listitem>
75- <listitem><para>Perform <literal>garage-manage repair --all-nodes --yes tables</literal> and <literal>garage-manage repair --all-nodes --yes blocks</literal>.</para></listitem>
76- <listitem><para>Verify the resulting logs and check that data is synced properly between all nodes.
77- If you have time, do additional checks (<literal>scrub</literal>, <literal>block_refs</literal>, etc.).</para></listitem>
78- <listitem><para>Check if queues are empty by <literal>garage-manage stats</literal> or through monitoring tools.</para></listitem>
79- <listitem><para>Run <literal>systemctl stop garage</literal> to stop the actual Garage version.</para></listitem>
80- <listitem><para>Backup the metadata folder of ALL your nodes, e.g. for a metadata directory (the default one) in <literal>/var/lib/garage/meta</literal>,
81- you can run <literal>pushd /var/lib/garage; tar -acf meta-v0.7.tar.zst meta/; popd</literal>.</para></listitem>
82- <listitem><para>Run the offline migration: <literal>nix-shell -p garage_0_8 --run "garage offline-repair --yes"</literal>, this can take some time depending on how many objects are stored in your cluster.</para></listitem>
83- <listitem><para>Bump Garage version in your NixOS configuration, either by changing <link linkend="opt-system.stateVersion">stateVersion</link> or bumping <link linkend="opt-services.garage.package">services.garage.package</link>, this should restart Garage automatically.</para></listitem>
84- <listitem><para>Perform <literal>garage-manage repair --all-nodes --yes tables</literal> and <literal>garage-manage repair --all-nodes --yes blocks</literal>.</para></listitem>
85- <listitem><para>Wait for a full table sync to run.</para></listitem>
86- </itemizedlist>
87-88- <para>
89- Your upgraded cluster should be in a working state, re-enable API and web access.
90- </para>
91-</section>
92-93-<section xml:id="module-services-garage-maintainer-info">
94- <title>Maintainer information</title>
95-96- <para>
97- As stated in the previous paragraph, we must provide a clean upgrade-path for Garage
98- since it cannot move more than one major version forward on a single upgrade. This chapter
99- adds some notes how Garage updates should be rolled out in the future.
100-101- This is inspired from how Nextcloud does it.
102- </para>
103-104- <para>
105- While patch-level updates are no problem and can be done directly in the
106- package-expression (and should be backported to supported stable branches after that),
107- major-releases should be added in a new attribute (e.g. Garage <literal>v0.8.0</literal>
108- should be available in <literal>nixpkgs</literal> as <literal>pkgs.garage_0_8_0</literal>).
109- To provide simple upgrade paths it's generally useful to backport those as well to stable
110- branches. As long as the package-default isn't altered, this won't break existing setups.
111- After that, the versioning-warning in the <literal>garage</literal>-module should be
112- updated to make sure that the
113- <link linkend="opt-services.garage.package">package</link>-option selects the latest version
114- on fresh setups.
115- </para>
116-117- <para>
118- If major-releases will be abandoned by upstream, we should check first if those are needed
119- in NixOS for a safe upgrade-path before removing those. In that case we shold keep those
120- packages, but mark them as insecure in an expression like this (in
121- <literal><nixpkgs/pkgs/tools/filesystem/garage/default.nix></literal>):
122-<programlisting>/* ... */
123-{
124- garage_0_7_3 = generic {
125- version = "0.7.3";
126- sha256 = "0000000000000000000000000000000000000000000000000000";
127- eol = true;
128- };
129-}</programlisting>
130- </para>
131-132- <para>
133- Ideally we should make sure that it's possible to jump two NixOS versions forward:
134- i.e. the warnings and the logic in the module should guard a user to upgrade from a
135- Garage on e.g. 22.11 to a Garage on 23.11.
136- </para>
137- </section>
138-139-</chapter>
···1+# Garage {#module-services-garage}
2+3+[Garage](https://garagehq.deuxfleurs.fr/)
4+is an open-source, self-hostable S3 store, simpler than MinIO, for geodistributed stores.
5+The server setup can be automated using
6+[services.garage](#opt-services.garage.enable). A
7+ client configured to your local Garage instance is available in
8+ the global environment as `garage-manage`.
9+10+The current default by NixOS is `garage_0_8` which is also the latest
11+major version available.
12+13+## General considerations on upgrades {#module-services-garage-upgrade-scenarios}
14+15+Garage provides a cookbook documentation on how to upgrade:
16+<https://garagehq.deuxfleurs.fr/documentation/cookbook/upgrading/>
17+18+::: {.warning}
19+Garage has two types of upgrades: patch-level upgrades and minor/major version upgrades.
20+21+In all cases, you should read the changelog and ideally test the upgrade on a staging cluster.
22+23+Checking the health of your cluster can be achieved using `garage-manage repair`.
24+:::
25+26+::: {.warning}
27+Until 1.0 is released, patch-level upgrades are considered as minor version upgrades.
28+Minor version upgrades are considered as major version upgrades.
29+i.e. 0.6 to 0.7 is a major version upgrade.
30+:::
31+32+ - **Straightforward upgrades (patch-level upgrades).**
33+ Upgrades must be performed one by one, i.e. for each node, stop it, upgrade it : change [stateVersion](#opt-system.stateVersion) or [services.garage.package](#opt-services.garage.package), restart it if it was not already by switching.
34+ - **Multiple version upgrades.**
35+ Garage do not provide any guarantee on moving more than one major-version forward.
36+ E.g., if you're on `0.7`, you cannot upgrade to `0.9`.
37+ You need to upgrade to `0.8` first.
38+ As long as [stateVersion](#opt-system.stateVersion) is declared properly,
39+ this is enforced automatically. The module will issue a warning to remind the user to upgrade to latest
40+ Garage *after* that deploy.
41+42+## Advanced upgrades (minor/major version upgrades) {#module-services-garage-advanced-upgrades}
43+44+Here are some baseline instructions to handle advanced upgrades in Garage, when in doubt, please refer to upstream instructions.
45+46+ - Disable API and web access to Garage.
47+ - Perform `garage-manage repair --all-nodes --yes tables` and `garage-manage repair --all-nodes --yes blocks`.
48+ - Verify the resulting logs and check that data is synced properly between all nodes.
49+ If you have time, do additional checks (`scrub`, `block_refs`, etc.).
50+ - Check if queues are empty by `garage-manage stats` or through monitoring tools.
51+ - Run `systemctl stop garage` to stop the actual Garage version.
52+ - Backup the metadata folder of ALL your nodes, e.g. for a metadata directory (the default one) in `/var/lib/garage/meta`,
53+ you can run `pushd /var/lib/garage; tar -acf meta-v0.7.tar.zst meta/; popd`.
54+ - Run the offline migration: `nix-shell -p garage_0_8 --run "garage offline-repair --yes"`, this can take some time depending on how many objects are stored in your cluster.
55+ - Bump Garage version in your NixOS configuration, either by changing [stateVersion](#opt-system.stateVersion) or bumping [services.garage.package](#opt-services.garage.package), this should restart Garage automatically.
56+ - Perform `garage-manage repair --all-nodes --yes tables` and `garage-manage repair --all-nodes --yes blocks`.
57+ - Wait for a full table sync to run.
58+59+Your upgraded cluster should be in a working state, re-enable API and web access.
60+61+## Maintainer information {#module-services-garage-maintainer-info}
62+63+As stated in the previous paragraph, we must provide a clean upgrade-path for Garage
64+since it cannot move more than one major version forward on a single upgrade. This chapter
65+adds some notes how Garage updates should be rolled out in the future.
66+This is inspired from how Nextcloud does it.
67+68+While patch-level updates are no problem and can be done directly in the
69+package-expression (and should be backported to supported stable branches after that),
70+major-releases should be added in a new attribute (e.g. Garage `v0.8.0`
71+should be available in `nixpkgs` as `pkgs.garage_0_8_0`).
72+To provide simple upgrade paths it's generally useful to backport those as well to stable
73+branches. As long as the package-default isn't altered, this won't break existing setups.
74+After that, the versioning-warning in the `garage`-module should be
75+updated to make sure that the
76+[package](#opt-services.garage.package)-option selects the latest version
77+on fresh setups.
78+79+If major-releases will be abandoned by upstream, we should check first if those are needed
80+in NixOS for a safe upgrade-path before removing those. In that case we shold keep those
81+packages, but mark them as insecure in an expression like this (in
82+`<nixpkgs/pkgs/tools/filesystem/garage/default.nix>`):
83+```
84+/* ... */
85+{
86+ garage_0_7_3 = generic {
87+ version = "0.7.3";
88+ sha256 = "0000000000000000000000000000000000000000000000000000";
89+ eol = true;
90+ };
91+}
92+```
93+94+Ideally we should make sure that it's possible to jump two NixOS versions forward:
95+i.e. the warnings and the logic in the module should guard a user to upgrade from a
96+Garage on e.g. 22.11 to a Garage on 23.11.
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-garage">
4+ <title>Garage</title>
5+ <para>
6+ <link xlink:href="https://garagehq.deuxfleurs.fr/">Garage</link> is
7+ an open-source, self-hostable S3 store, simpler than MinIO, for
8+ geodistributed stores. The server setup can be automated using
9+ <link linkend="opt-services.garage.enable">services.garage</link>. A
10+ client configured to your local Garage instance is available in the
11+ global environment as <literal>garage-manage</literal>.
12+ </para>
13+ <para>
14+ The current default by NixOS is <literal>garage_0_8</literal> which
15+ is also the latest major version available.
16+ </para>
17+ <section xml:id="module-services-garage-upgrade-scenarios">
18+ <title>General considerations on upgrades</title>
19+ <para>
20+ Garage provides a cookbook documentation on how to upgrade:
21+ <link xlink:href="https://garagehq.deuxfleurs.fr/documentation/cookbook/upgrading/">https://garagehq.deuxfleurs.fr/documentation/cookbook/upgrading/</link>
22+ </para>
23+ <warning>
24+ <para>
25+ Garage has two types of upgrades: patch-level upgrades and
26+ minor/major version upgrades.
27+ </para>
28+ <para>
29+ In all cases, you should read the changelog and ideally test the
30+ upgrade on a staging cluster.
31+ </para>
32+ <para>
33+ Checking the health of your cluster can be achieved using
34+ <literal>garage-manage repair</literal>.
35+ </para>
36+ </warning>
37+ <warning>
38+ <para>
39+ Until 1.0 is released, patch-level upgrades are considered as
40+ minor version upgrades. Minor version upgrades are considered as
41+ major version upgrades. i.e. 0.6 to 0.7 is a major version
42+ upgrade.
43+ </para>
44+ </warning>
45+ <itemizedlist spacing="compact">
46+ <listitem>
47+ <para>
48+ <emphasis role="strong">Straightforward upgrades (patch-level
49+ upgrades).</emphasis> Upgrades must be performed one by one,
50+ i.e. for each node, stop it, upgrade it : change
51+ <link linkend="opt-system.stateVersion">stateVersion</link> or
52+ <link linkend="opt-services.garage.package">services.garage.package</link>,
53+ restart it if it was not already by switching.
54+ </para>
55+ </listitem>
56+ <listitem>
57+ <para>
58+ <emphasis role="strong">Multiple version upgrades.</emphasis>
59+ Garage do not provide any guarantee on moving more than one
60+ major-version forward. E.g., if you’re on
61+ <literal>0.7</literal>, you cannot upgrade to
62+ <literal>0.9</literal>. You need to upgrade to
63+ <literal>0.8</literal> first. As long as
64+ <link linkend="opt-system.stateVersion">stateVersion</link> is
65+ declared properly, this is enforced automatically. The module
66+ will issue a warning to remind the user to upgrade to latest
67+ Garage <emphasis>after</emphasis> that deploy.
68+ </para>
69+ </listitem>
70+ </itemizedlist>
71+ </section>
72+ <section xml:id="module-services-garage-advanced-upgrades">
73+ <title>Advanced upgrades (minor/major version upgrades)</title>
74+ <para>
75+ Here are some baseline instructions to handle advanced upgrades in
76+ Garage, when in doubt, please refer to upstream instructions.
77+ </para>
78+ <itemizedlist spacing="compact">
79+ <listitem>
80+ <para>
81+ Disable API and web access to Garage.
82+ </para>
83+ </listitem>
84+ <listitem>
85+ <para>
86+ Perform
87+ <literal>garage-manage repair --all-nodes --yes tables</literal>
88+ and
89+ <literal>garage-manage repair --all-nodes --yes blocks</literal>.
90+ </para>
91+ </listitem>
92+ <listitem>
93+ <para>
94+ Verify the resulting logs and check that data is synced
95+ properly between all nodes. If you have time, do additional
96+ checks (<literal>scrub</literal>,
97+ <literal>block_refs</literal>, etc.).
98+ </para>
99+ </listitem>
100+ <listitem>
101+ <para>
102+ Check if queues are empty by
103+ <literal>garage-manage stats</literal> or through monitoring
104+ tools.
105+ </para>
106+ </listitem>
107+ <listitem>
108+ <para>
109+ Run <literal>systemctl stop garage</literal> to stop the
110+ actual Garage version.
111+ </para>
112+ </listitem>
113+ <listitem>
114+ <para>
115+ Backup the metadata folder of ALL your nodes, e.g. for a
116+ metadata directory (the default one) in
117+ <literal>/var/lib/garage/meta</literal>, you can run
118+ <literal>pushd /var/lib/garage; tar -acf meta-v0.7.tar.zst meta/; popd</literal>.
119+ </para>
120+ </listitem>
121+ <listitem>
122+ <para>
123+ Run the offline migration:
124+ <literal>nix-shell -p garage_0_8 --run "garage offline-repair --yes"</literal>,
125+ this can take some time depending on how many objects are
126+ stored in your cluster.
127+ </para>
128+ </listitem>
129+ <listitem>
130+ <para>
131+ Bump Garage version in your NixOS configuration, either by
132+ changing
133+ <link linkend="opt-system.stateVersion">stateVersion</link> or
134+ bumping
135+ <link linkend="opt-services.garage.package">services.garage.package</link>,
136+ this should restart Garage automatically.
137+ </para>
138+ </listitem>
139+ <listitem>
140+ <para>
141+ Perform
142+ <literal>garage-manage repair --all-nodes --yes tables</literal>
143+ and
144+ <literal>garage-manage repair --all-nodes --yes blocks</literal>.
145+ </para>
146+ </listitem>
147+ <listitem>
148+ <para>
149+ Wait for a full table sync to run.
150+ </para>
151+ </listitem>
152+ </itemizedlist>
153+ <para>
154+ Your upgraded cluster should be in a working state, re-enable API
155+ and web access.
156+ </para>
157+ </section>
158+ <section xml:id="module-services-garage-maintainer-info">
159+ <title>Maintainer information</title>
160+ <para>
161+ As stated in the previous paragraph, we must provide a clean
162+ upgrade-path for Garage since it cannot move more than one major
163+ version forward on a single upgrade. This chapter adds some notes
164+ how Garage updates should be rolled out in the future. This is
165+ inspired from how Nextcloud does it.
166+ </para>
167+ <para>
168+ While patch-level updates are no problem and can be done directly
169+ in the package-expression (and should be backported to supported
170+ stable branches after that), major-releases should be added in a
171+ new attribute (e.g. Garage <literal>v0.8.0</literal> should be
172+ available in <literal>nixpkgs</literal> as
173+ <literal>pkgs.garage_0_8_0</literal>). To provide simple upgrade
174+ paths it’s generally useful to backport those as well to stable
175+ branches. As long as the package-default isn’t altered, this won’t
176+ break existing setups. After that, the versioning-warning in the
177+ <literal>garage</literal>-module should be updated to make sure
178+ that the
179+ <link linkend="opt-services.garage.package">package</link>-option
180+ selects the latest version on fresh setups.
181+ </para>
182+ <para>
183+ If major-releases will be abandoned by upstream, we should check
184+ first if those are needed in NixOS for a safe upgrade-path before
185+ removing those. In that case we shold keep those packages, but
186+ mark them as insecure in an expression like this (in
187+ <literal><nixpkgs/pkgs/tools/filesystem/garage/default.nix></literal>):
188+ </para>
189+ <programlisting>
190+/* ... */
191+{
192+ garage_0_7_3 = generic {
193+ version = "0.7.3";
194+ sha256 = "0000000000000000000000000000000000000000000000000000";
195+ eol = true;
196+ };
197+}
198+</programlisting>
199+ <para>
200+ Ideally we should make sure that it’s possible to jump two NixOS
201+ versions forward: i.e. the warnings and the logic in the module
202+ should guard a user to upgrade from a Garage on e.g. 22.11 to a
203+ Garage on 23.11.
204+ </para>
205+ </section>
206+</chapter>
···1+# GNOME Desktop {#chap-gnome}
2+3+GNOME provides a simple, yet full-featured desktop environment with a focus on productivity. Its Mutter compositor supports both Wayland and X server, and the GNOME Shell user interface is fully customizable by extensions.
4+5+## Enabling GNOME {#sec-gnome-enable}
6+7+All of the core apps, optional apps, games, and core developer tools from GNOME are available.
8+9+To enable the GNOME desktop use:
10+11+```
12+services.xserver.desktopManager.gnome.enable = true;
13+services.xserver.displayManager.gdm.enable = true;
14+```
15+16+::: {.note}
17+While it is not strictly necessary to use GDM as the display manager with GNOME, it is recommended, as some features such as screen lock [might not work](#sec-gnome-faq-can-i-use-lightdm-with-gnome) without it.
18+:::
19+20+The default applications used in NixOS are very minimal, inspired by the defaults used in [gnome-build-meta](https://gitlab.gnome.org/GNOME/gnome-build-meta/blob/40.0/elements/core/meta-gnome-core-utilities.bst).
21+22+### GNOME without the apps {#sec-gnome-without-the-apps}
23+24+If you’d like to only use the GNOME desktop and not the apps, you can disable them with:
25+26+```
27+services.gnome.core-utilities.enable = false;
28+```
29+30+and none of them will be installed.
31+32+If you’d only like to omit a subset of the core utilities, you can use
33+[](#opt-environment.gnome.excludePackages).
34+Note that this mechanism can only exclude core utilities, games and core developer tools.
35+36+### Disabling GNOME services {#sec-gnome-disabling-services}
37+38+It is also possible to disable many of the [core services](https://github.com/NixOS/nixpkgs/blob/b8ec4fd2a4edc4e30d02ba7b1a2cc1358f3db1d5/nixos/modules/services/x11/desktop-managers/gnome.nix#L329-L348). For example, if you do not need indexing files, you can disable Tracker with:
39+40+```
41+services.gnome.tracker-miners.enable = false;
42+services.gnome.tracker.enable = false;
43+```
44+45+Note, however, that doing so is not supported and might break some applications. Notably, GNOME Music cannot work without Tracker.
46+47+### GNOME games {#sec-gnome-games}
48+49+You can install all of the GNOME games with:
50+51+```
52+services.gnome.games.enable = true;
53+```
54+55+### GNOME core developer tools {#sec-gnome-core-developer-tools}
56+57+You can install GNOME core developer tools with:
58+59+```
60+services.gnome.core-developer-tools.enable = true;
61+```
62+63+## Enabling GNOME Flashback {#sec-gnome-enable-flashback}
64+65+GNOME Flashback provides a desktop environment based on the classic GNOME 2 architecture. You can enable the default GNOME Flashback session, which uses the Metacity window manager, with:
66+67+```
68+services.xserver.desktopManager.gnome.flashback.enableMetacity = true;
69+```
70+71+It is also possible to create custom sessions that replace Metacity with a different window manager using [](#opt-services.xserver.desktopManager.gnome.flashback.customSessions).
72+73+The following example uses `xmonad` window manager:
74+75+```
76+services.xserver.desktopManager.gnome.flashback.customSessions = [
77+ {
78+ wmName = "xmonad";
79+ wmLabel = "XMonad";
80+ wmCommand = "${pkgs.haskellPackages.xmonad}/bin/xmonad";
81+ enableGnomePanel = false;
82+ }
83+];
84+```
85+86+## Icons and GTK Themes {#sec-gnome-icons-and-gtk-themes}
87+88+Icon themes and GTK themes don’t require any special option to install in NixOS.
89+90+You can add them to [](#opt-environment.systemPackages) and switch to them with GNOME Tweaks.
91+If you’d like to do this manually in dconf, change the values of the following keys:
92+93+```
94+/org/gnome/desktop/interface/gtk-theme
95+/org/gnome/desktop/interface/icon-theme
96+```
97+98+in `dconf-editor`
99+100+## Shell Extensions {#sec-gnome-shell-extensions}
101+102+Most Shell extensions are packaged under the `gnomeExtensions` attribute.
103+Some packages that include Shell extensions, like `gnome.gpaste`, don’t have their extension decoupled under this attribute.
104+105+You can install them like any other package:
106+107+```
108+environment.systemPackages = [
109+ gnomeExtensions.dash-to-dock
110+ gnomeExtensions.gsconnect
111+ gnomeExtensions.mpris-indicator-button
112+];
113+```
114+115+Unfortunately, we lack a way for these to be managed in a completely declarative way.
116+So you have to enable them manually with an Extensions application.
117+It is possible to use a [GSettings override](#sec-gnome-gsettings-overrides) for this on `org.gnome.shell.enabled-extensions`, but that will only influence the default value.
118+119+## GSettings Overrides {#sec-gnome-gsettings-overrides}
120+121+Majority of software building on the GNOME platform use GLib’s [GSettings](https://developer.gnome.org/gio/unstable/GSettings.html) system to manage runtime configuration. For our purposes, the system consists of XML schemas describing the individual configuration options, stored in the package, and a settings backend, where the values of the settings are stored. On NixOS, like on most Linux distributions, dconf database is used as the backend.
122+123+[GSettings vendor overrides](https://developer.gnome.org/gio/unstable/GSettings.html#id-1.4.19.2.9.25) can be used to adjust the default values for settings of the GNOME desktop and apps by replacing the default values specified in the XML schemas. Using overrides will allow you to pre-seed user settings before you even start the session.
124+125+::: {.warning}
126+Overrides really only change the default values for GSettings keys so if you or an application changes the setting value, the value set by the override will be ignored. Until [NixOS’s dconf module implements changing values](https://github.com/NixOS/nixpkgs/issues/54150), you will either need to keep that in mind and clear the setting from the backend using `dconf reset` command when that happens, or use the [module from home-manager](https://nix-community.github.io/home-manager/options.html#opt-dconf.settings).
127+:::
128+129+You can override the default GSettings values using the
130+[](#opt-services.xserver.desktopManager.gnome.extraGSettingsOverrides) option.
131+132+Take note that whatever packages you want to override GSettings for, you need to add them to
133+[](#opt-services.xserver.desktopManager.gnome.extraGSettingsOverridePackages).
134+135+You can use `dconf-editor` tool to explore which GSettings you can set.
136+137+### Example {#sec-gnome-gsettings-overrides-example}
138+139+```
140+services.xserver.desktopManager.gnome = {
141+ extraGSettingsOverrides = ''
142+ # Change default background
143+ [org.gnome.desktop.background]
144+ picture-uri='file://${pkgs.nixos-artwork.wallpapers.mosaic-blue.gnomeFilePath}'
145+146+ # Favorite apps in gnome-shell
147+ [org.gnome.shell]
148+ favorite-apps=['org.gnome.Photos.desktop', 'org.gnome.Nautilus.desktop']
149+ '';
150+151+ extraGSettingsOverridePackages = [
152+ pkgs.gsettings-desktop-schemas # for org.gnome.desktop
153+ pkgs.gnome.gnome-shell # for org.gnome.shell
154+ ];
155+};
156+```
157+158+## Frequently Asked Questions {#sec-gnome-faq}
159+160+### Can I use LightDM with GNOME? {#sec-gnome-faq-can-i-use-lightdm-with-gnome}
161+162+Yes you can, and any other display-manager in NixOS.
163+164+However, it doesn’t work correctly for the Wayland session of GNOME Shell yet, and
165+won’t be able to lock your screen.
166+167+See [this issue.](https://github.com/NixOS/nixpkgs/issues/56342)
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xml:id="chap-gnome">
4- <title>GNOME Desktop</title>
5- <para>
6- GNOME provides a simple, yet full-featured desktop environment with a focus on productivity. Its Mutter compositor supports both Wayland and X server, and the GNOME Shell user interface is fully customizable by extensions.
7- </para>
8-9- <section xml:id="sec-gnome-enable">
10- <title>Enabling GNOME</title>
11-12 <para>
13- All of the core apps, optional apps, games, and core developer tools from GNOME are available.
00014 </para>
15-16- <para>
17- To enable the GNOME desktop use:
18- </para>
19-20-<programlisting>
21-<xref linkend="opt-services.xserver.desktopManager.gnome.enable"/> = true;
22-<xref linkend="opt-services.xserver.displayManager.gdm.enable"/> = true;
000023</programlisting>
24-25- <note>
26- <para>
27- While it is not strictly necessary to use GDM as the display manager with GNOME, it is recommended, as some features such as screen lock <link xlink:href="#sec-gnome-faq-can-i-use-lightdm-with-gnome">might not work</link> without it.
28- </para>
29- </note>
30-31- <para>
32- The default applications used in NixOS are very minimal, inspired by the defaults used in <link xlink:href="https://gitlab.gnome.org/GNOME/gnome-build-meta/blob/40.0/elements/core/meta-gnome-core-utilities.bst">gnome-build-meta</link>.
33- </para>
34-35- <section xml:id="sec-gnome-without-the-apps">
36- <title>GNOME without the apps</title>
37-38- <para>
39- If you’d like to only use the GNOME desktop and not the apps, you can disable them with:
40- </para>
41-42-<programlisting>
43-<xref linkend="opt-services.gnome.core-utilities.enable"/> = false;
0044</programlisting>
45-46- <para>
47- and none of them will be installed.
48- </para>
49-50- <para>
51- If you’d only like to omit a subset of the core utilities, you can use <xref linkend="opt-environment.gnome.excludePackages"/>.
52- Note that this mechanism can only exclude core utilities, games and core developer tools.
53- </para>
54- </section>
55-56- <section xml:id="sec-gnome-disabling-services">
57- <title>Disabling GNOME services</title>
58-59- <para>
60- It is also possible to disable many of the <link xlink:href="https://github.com/NixOS/nixpkgs/blob/b8ec4fd2a4edc4e30d02ba7b1a2cc1358f3db1d5/nixos/modules/services/x11/desktop-managers/gnome.nix#L329-L348">core services</link>. For example, if you do not need indexing files, you can disable Tracker with:
61- </para>
62-63-<programlisting>
64-<xref linkend="opt-services.gnome.tracker-miners.enable"/> = false;
65-<xref linkend="opt-services.gnome.tracker.enable"/> = false;
066</programlisting>
67-68- <para>
69- Note, however, that doing so is not supported and might break some applications. Notably, GNOME Music cannot work without Tracker.
70- </para>
71- </section>
72-73- <section xml:id="sec-gnome-games">
74- <title>GNOME games</title>
75-76- <para>
77- You can install all of the GNOME games with:
78- </para>
79-80-<programlisting>
81-<xref linkend="opt-services.gnome.games.enable"/> = true;
82</programlisting>
83- </section>
84-85- <section xml:id="sec-gnome-core-developer-tools">
86- <title>GNOME core developer tools</title>
87-88- <para>
89- You can install GNOME core developer tools with:
90- </para>
91-92-<programlisting>
93-<xref linkend="opt-services.gnome.core-developer-tools.enable"/> = true;
94</programlisting>
095 </section>
96- </section>
97-98- <section xml:id="sec-gnome-enable-flashback">
99- <title>Enabling GNOME Flashback</title>
100-101- <para>
102- GNOME Flashback provides a desktop environment based on the classic GNOME 2 architecture. You can enable the default GNOME Flashback session, which uses the Metacity window manager, with:
103- </para>
104-105-<programlisting>
106-<xref linkend="opt-services.xserver.desktopManager.gnome.flashback.enableMetacity"/> = true;
107</programlisting>
108-109- <para>
110- It is also possible to create custom sessions that replace Metacity with a different window manager using <xref linkend="opt-services.xserver.desktopManager.gnome.flashback.customSessions"/>.
111- </para>
112-113- <para>
114- The following example uses <literal>xmonad</literal> window manager:
115- </para>
116-117-<programlisting>
118-<xref linkend="opt-services.xserver.desktopManager.gnome.flashback.customSessions"/> = [
119 {
120- wmName = "xmonad";
121- wmLabel = "XMonad";
122- wmCommand = "${pkgs.haskellPackages.xmonad}/bin/xmonad";
123 enableGnomePanel = false;
124 }
125];
126</programlisting>
127-128- </section>
129-130- <section xml:id="sec-gnome-icons-and-gtk-themes">
131- <title>Icons and GTK Themes</title>
132-133- <para>
134- Icon themes and GTK themes don’t require any special option to install in NixOS.
135- </para>
136-137- <para>
138- You can add them to <xref linkend="opt-environment.systemPackages"/> and switch to them with GNOME Tweaks.
139- If you’d like to do this manually in dconf, change the values of the following keys:
140- </para>
141-142-<programlisting>
143/org/gnome/desktop/interface/gtk-theme
144/org/gnome/desktop/interface/icon-theme
145</programlisting>
146-147- <para>
148- in <literal>dconf-editor</literal>
149- </para>
150- </section>
151-152- <section xml:id="sec-gnome-shell-extensions">
153- <title>Shell Extensions</title>
154-155- <para>
156- Most Shell extensions are packaged under the <literal>gnomeExtensions</literal> attribute.
157- Some packages that include Shell extensions, like <literal>gnome.gpaste</literal>, don’t have their extension decoupled under this attribute.
158- </para>
159-160- <para>
161- You can install them like any other package:
162- </para>
163-164-<programlisting>
165-<xref linkend="opt-environment.systemPackages"/> = [
166 gnomeExtensions.dash-to-dock
167 gnomeExtensions.gsconnect
168 gnomeExtensions.mpris-indicator-button
169];
170</programlisting>
171-172- <para>
173- Unfortunately, we lack a way for these to be managed in a completely declarative way.
174- So you have to enable them manually with an Extensions application.
175- It is possible to use a <link xlink:href="#sec-gnome-gsettings-overrides">GSettings override</link> for this on <literal>org.gnome.shell.enabled-extensions</literal>, but that will only influence the default value.
176- </para>
177- </section>
178-179- <section xml:id="sec-gnome-gsettings-overrides">
180- <title>GSettings Overrides</title>
181-182- <para>
183- Majority of software building on the GNOME platform use GLib’s <link xlink:href="https://developer.gnome.org/gio/unstable/GSettings.html">GSettings</link> system to manage runtime configuration. For our purposes, the system consists of XML schemas describing the individual configuration options, stored in the package, and a settings backend, where the values of the settings are stored. On NixOS, like on most Linux distributions, dconf database is used as the backend.
184- </para>
185-186- <para>
187- <link xlink:href="https://developer.gnome.org/gio/unstable/GSettings.html#id-1.4.19.2.9.25">GSettings vendor overrides</link> can be used to adjust the default values for settings of the GNOME desktop and apps by replacing the default values specified in the XML schemas. Using overrides will allow you to pre-seed user settings before you even start the session.
188- </para>
189-190- <warning>
191- <para>
192- Overrides really only change the default values for GSettings keys so if you or an application changes the setting value, the value set by the override will be ignored. Until <link xlink:href="https://github.com/NixOS/nixpkgs/issues/54150">NixOS’s dconf module implements changing values</link>, you will either need to keep that in mind and clear the setting from the backend using <literal>dconf reset</literal> command when that happens, or use the <link xlink:href="https://nix-community.github.io/home-manager/options.html#opt-dconf.settings">module from home-manager</link>.
193- </para>
194- </warning>
195-196- <para>
197- You can override the default GSettings values using the <xref linkend="opt-services.xserver.desktopManager.gnome.extraGSettingsOverrides"/> option.
198- </para>
199-200- <para>
201- Take note that whatever packages you want to override GSettings for, you need to add them to
202- <xref linkend="opt-services.xserver.desktopManager.gnome.extraGSettingsOverridePackages"/>.
203- </para>
204-205- <para>
206- You can use <literal>dconf-editor</literal> tool to explore which GSettings you can set.
207- </para>
208-209- <section xml:id="sec-gnome-gsettings-overrides-example">
210- <title>Example</title>
211-212-<programlisting>
0000000000000000000213services.xserver.desktopManager.gnome = {
214- <link xlink:href="#opt-services.xserver.desktopManager.gnome.extraGSettingsOverrides">extraGSettingsOverrides</link> = ''
215 # Change default background
216 [org.gnome.desktop.background]
217 picture-uri='file://${pkgs.nixos-artwork.wallpapers.mosaic-blue.gnomeFilePath}'
···221 favorite-apps=['org.gnome.Photos.desktop', 'org.gnome.Nautilus.desktop']
222 '';
223224- <link xlink:href="#opt-services.xserver.desktopManager.gnome.extraGSettingsOverridePackages">extraGSettingsOverridePackages</link> = [
225 pkgs.gsettings-desktop-schemas # for org.gnome.desktop
226 pkgs.gnome.gnome-shell # for org.gnome.shell
227 ];
228};
229</programlisting>
0230 </section>
231- </section>
232-233- <section xml:id="sec-gnome-faq">
234- <title>Frequently Asked Questions</title>
235-236- <section xml:id="sec-gnome-faq-can-i-use-lightdm-with-gnome">
237- <title>Can I use LightDM with GNOME?</title>
238-239- <para>
240- Yes you can, and any other display-manager in NixOS.
241- </para>
242-243- <para>
244- However, it doesn’t work correctly for the Wayland session of GNOME Shell yet, and
245- won’t be able to lock your screen.
246- </para>
247-248- <para>
249- See <link xlink:href="https://github.com/NixOS/nixpkgs/issues/56342">this issue.</link>
250- </para>
251 </section>
252- </section>
253</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="chap-gnome">
4+ <title>GNOME Desktop</title>
00000005 <para>
6+ GNOME provides a simple, yet full-featured desktop environment with
7+ a focus on productivity. Its Mutter compositor supports both Wayland
8+ and X server, and the GNOME Shell user interface is fully
9+ customizable by extensions.
10 </para>
11+ <section xml:id="sec-gnome-enable">
12+ <title>Enabling GNOME</title>
13+ <para>
14+ All of the core apps, optional apps, games, and core developer
15+ tools from GNOME are available.
16+ </para>
17+ <para>
18+ To enable the GNOME desktop use:
19+ </para>
20+ <programlisting>
21+services.xserver.desktopManager.gnome.enable = true;
22+services.xserver.displayManager.gdm.enable = true;
23</programlisting>
24+ <note>
25+ <para>
26+ While it is not strictly necessary to use GDM as the display
27+ manager with GNOME, it is recommended, as some features such as
28+ screen lock
29+ <link linkend="sec-gnome-faq-can-i-use-lightdm-with-gnome">might
30+ not work</link> without it.
31+ </para>
32+ </note>
33+ <para>
34+ The default applications used in NixOS are very minimal, inspired
35+ by the defaults used in
36+ <link xlink:href="https://gitlab.gnome.org/GNOME/gnome-build-meta/blob/40.0/elements/core/meta-gnome-core-utilities.bst">gnome-build-meta</link>.
37+ </para>
38+ <section xml:id="sec-gnome-without-the-apps">
39+ <title>GNOME without the apps</title>
40+ <para>
41+ If you’d like to only use the GNOME desktop and not the apps,
42+ you can disable them with:
43+ </para>
44+ <programlisting>
45+services.gnome.core-utilities.enable = false;
46</programlisting>
47+ <para>
48+ and none of them will be installed.
49+ </para>
50+ <para>
51+ If you’d only like to omit a subset of the core utilities, you
52+ can use
53+ <xref linkend="opt-environment.gnome.excludePackages" />. Note
54+ that this mechanism can only exclude core utilities, games and
55+ core developer tools.
56+ </para>
57+ </section>
58+ <section xml:id="sec-gnome-disabling-services">
59+ <title>Disabling GNOME services</title>
60+ <para>
61+ It is also possible to disable many of the
62+ <link xlink:href="https://github.com/NixOS/nixpkgs/blob/b8ec4fd2a4edc4e30d02ba7b1a2cc1358f3db1d5/nixos/modules/services/x11/desktop-managers/gnome.nix#L329-L348">core
63+ services</link>. For example, if you do not need indexing files,
64+ you can disable Tracker with:
65+ </para>
66+ <programlisting>
67+services.gnome.tracker-miners.enable = false;
68+services.gnome.tracker.enable = false;
69</programlisting>
70+ <para>
71+ Note, however, that doing so is not supported and might break
72+ some applications. Notably, GNOME Music cannot work without
73+ Tracker.
74+ </para>
75+ </section>
76+ <section xml:id="sec-gnome-games">
77+ <title>GNOME games</title>
78+ <para>
79+ You can install all of the GNOME games with:
80+ </para>
81+ <programlisting>
82+services.gnome.games.enable = true;
0083</programlisting>
84+ </section>
85+ <section xml:id="sec-gnome-core-developer-tools">
86+ <title>GNOME core developer tools</title>
87+ <para>
88+ You can install GNOME core developer tools with:
89+ </para>
90+ <programlisting>
91+services.gnome.core-developer-tools.enable = true;
00092</programlisting>
93+ </section>
94 </section>
95+ <section xml:id="sec-gnome-enable-flashback">
96+ <title>Enabling GNOME Flashback</title>
97+ <para>
98+ GNOME Flashback provides a desktop environment based on the
99+ classic GNOME 2 architecture. You can enable the default GNOME
100+ Flashback session, which uses the Metacity window manager, with:
101+ </para>
102+ <programlisting>
103+services.xserver.desktopManager.gnome.flashback.enableMetacity = true;
00104</programlisting>
105+ <para>
106+ It is also possible to create custom sessions that replace
107+ Metacity with a different window manager using
108+ <xref linkend="opt-services.xserver.desktopManager.gnome.flashback.customSessions" />.
109+ </para>
110+ <para>
111+ The following example uses <literal>xmonad</literal> window
112+ manager:
113+ </para>
114+ <programlisting>
115+services.xserver.desktopManager.gnome.flashback.customSessions = [
116 {
117+ wmName = "xmonad";
118+ wmLabel = "XMonad";
119+ wmCommand = "${pkgs.haskellPackages.xmonad}/bin/xmonad";
120 enableGnomePanel = false;
121 }
122];
123</programlisting>
124+ </section>
125+ <section xml:id="sec-gnome-icons-and-gtk-themes">
126+ <title>Icons and GTK Themes</title>
127+ <para>
128+ Icon themes and GTK themes don’t require any special option to
129+ install in NixOS.
130+ </para>
131+ <para>
132+ You can add them to
133+ <xref linkend="opt-environment.systemPackages" /> and switch to
134+ them with GNOME Tweaks. If you’d like to do this manually in
135+ dconf, change the values of the following keys:
136+ </para>
137+ <programlisting>
00138/org/gnome/desktop/interface/gtk-theme
139/org/gnome/desktop/interface/icon-theme
140</programlisting>
141+ <para>
142+ in <literal>dconf-editor</literal>
143+ </para>
144+ </section>
145+ <section xml:id="sec-gnome-shell-extensions">
146+ <title>Shell Extensions</title>
147+ <para>
148+ Most Shell extensions are packaged under the
149+ <literal>gnomeExtensions</literal> attribute. Some packages that
150+ include Shell extensions, like <literal>gnome.gpaste</literal>,
151+ don’t have their extension decoupled under this attribute.
152+ </para>
153+ <para>
154+ You can install them like any other package:
155+ </para>
156+ <programlisting>
157+environment.systemPackages = [
000158 gnomeExtensions.dash-to-dock
159 gnomeExtensions.gsconnect
160 gnomeExtensions.mpris-indicator-button
161];
162</programlisting>
163+ <para>
164+ Unfortunately, we lack a way for these to be managed in a
165+ completely declarative way. So you have to enable them manually
166+ with an Extensions application. It is possible to use a
167+ <link linkend="sec-gnome-gsettings-overrides">GSettings
168+ override</link> for this on
169+ <literal>org.gnome.shell.enabled-extensions</literal>, but that
170+ will only influence the default value.
171+ </para>
172+ </section>
173+ <section xml:id="sec-gnome-gsettings-overrides">
174+ <title>GSettings Overrides</title>
175+ <para>
176+ Majority of software building on the GNOME platform use GLib’s
177+ <link xlink:href="https://developer.gnome.org/gio/unstable/GSettings.html">GSettings</link>
178+ system to manage runtime configuration. For our purposes, the
179+ system consists of XML schemas describing the individual
180+ configuration options, stored in the package, and a settings
181+ backend, where the values of the settings are stored. On NixOS,
182+ like on most Linux distributions, dconf database is used as the
183+ backend.
184+ </para>
185+ <para>
186+ <link xlink:href="https://developer.gnome.org/gio/unstable/GSettings.html#id-1.4.19.2.9.25">GSettings
187+ vendor overrides</link> can be used to adjust the default values
188+ for settings of the GNOME desktop and apps by replacing the
189+ default values specified in the XML schemas. Using overrides will
190+ allow you to pre-seed user settings before you even start the
191+ session.
192+ </para>
193+ <warning>
194+ <para>
195+ Overrides really only change the default values for GSettings
196+ keys so if you or an application changes the setting value, the
197+ value set by the override will be ignored. Until
198+ <link xlink:href="https://github.com/NixOS/nixpkgs/issues/54150">NixOS’s
199+ dconf module implements changing values</link>, you will either
200+ need to keep that in mind and clear the setting from the backend
201+ using <literal>dconf reset</literal> command when that happens,
202+ or use the
203+ <link xlink:href="https://nix-community.github.io/home-manager/options.html#opt-dconf.settings">module
204+ from home-manager</link>.
205+ </para>
206+ </warning>
207+ <para>
208+ You can override the default GSettings values using the
209+ <xref linkend="opt-services.xserver.desktopManager.gnome.extraGSettingsOverrides" />
210+ option.
211+ </para>
212+ <para>
213+ Take note that whatever packages you want to override GSettings
214+ for, you need to add them to
215+ <xref linkend="opt-services.xserver.desktopManager.gnome.extraGSettingsOverridePackages" />.
216+ </para>
217+ <para>
218+ You can use <literal>dconf-editor</literal> tool to explore which
219+ GSettings you can set.
220+ </para>
221+ <section xml:id="sec-gnome-gsettings-overrides-example">
222+ <title>Example</title>
223+ <programlisting>
224services.xserver.desktopManager.gnome = {
225+ extraGSettingsOverrides = ''
226 # Change default background
227 [org.gnome.desktop.background]
228 picture-uri='file://${pkgs.nixos-artwork.wallpapers.mosaic-blue.gnomeFilePath}'
···232 favorite-apps=['org.gnome.Photos.desktop', 'org.gnome.Nautilus.desktop']
233 '';
234235+ extraGSettingsOverridePackages = [
236 pkgs.gsettings-desktop-schemas # for org.gnome.desktop
237 pkgs.gnome.gnome-shell # for org.gnome.shell
238 ];
239};
240</programlisting>
241+ </section>
242 </section>
243+ <section xml:id="sec-gnome-faq">
244+ <title>Frequently Asked Questions</title>
245+ <section xml:id="sec-gnome-faq-can-i-use-lightdm-with-gnome">
246+ <title>Can I use LightDM with GNOME?</title>
247+ <para>
248+ Yes you can, and any other display-manager in NixOS.
249+ </para>
250+ <para>
251+ However, it doesn’t work correctly for the Wayland session of
252+ GNOME Shell yet, and won’t be able to lock your screen.
253+ </para>
254+ <para>
255+ See
256+ <link xlink:href="https://github.com/NixOS/nixpkgs/issues/56342">this
257+ issue.</link>
258+ </para>
259+ </section>
000260 </section>
0261</chapter>
···1+# Pantheon Desktop {#chap-pantheon}
2+3+Pantheon is the desktop environment created for the elementary OS distribution. It is written from scratch in Vala, utilizing GNOME technologies with GTK and Granite.
4+5+## Enabling Pantheon {#sec-pantheon-enable}
6+7+All of Pantheon is working in NixOS and the applications should be available, aside from a few [exceptions](https://github.com/NixOS/nixpkgs/issues/58161). To enable Pantheon, set
8+```
9+services.xserver.desktopManager.pantheon.enable = true;
10+```
11+This automatically enables LightDM and Pantheon's LightDM greeter. If you'd like to disable this, set
12+```
13+services.xserver.displayManager.lightdm.greeters.pantheon.enable = false;
14+services.xserver.displayManager.lightdm.enable = false;
15+```
16+but please be aware using Pantheon without LightDM as a display manager will break screenlocking from the UI. The NixOS module for Pantheon installs all of Pantheon's default applications. If you'd like to not install Pantheon's apps, set
17+```
18+services.pantheon.apps.enable = false;
19+```
20+You can also use [](#opt-environment.pantheon.excludePackages) to remove any other app (like `elementary-mail`).
21+22+## Wingpanel and Switchboard plugins {#sec-pantheon-wingpanel-switchboard}
23+24+Wingpanel and Switchboard work differently than they do in other distributions, as far as using plugins. You cannot install a plugin globally (like with {option}`environment.systemPackages`) to start using it. You should instead be using the following options:
25+26+ - [](#opt-services.xserver.desktopManager.pantheon.extraWingpanelIndicators)
27+ - [](#opt-services.xserver.desktopManager.pantheon.extraSwitchboardPlugs)
28+29+to configure the programs with plugs or indicators.
30+31+The difference in NixOS is both these programs are patched to load plugins from a directory that is the value of an environment variable. All of which is controlled in Nix. If you need to configure the particular packages manually you can override the packages like:
32+```
33+wingpanel-with-indicators.override {
34+ indicators = [
35+ pkgs.some-special-indicator
36+ ];
37+};
38+39+switchboard-with-plugs.override {
40+ plugs = [
41+ pkgs.some-special-plug
42+ ];
43+};
44+```
45+please note that, like how the NixOS options describe these as extra plugins, this would only add to the default plugins included with the programs. If for some reason you'd like to configure which plugins to use exactly, both packages have an argument for this:
46+```
47+wingpanel-with-indicators.override {
48+ useDefaultIndicators = false;
49+ indicators = specialListOfIndicators;
50+};
51+52+switchboard-with-plugs.override {
53+ useDefaultPlugs = false;
54+ plugs = specialListOfPlugs;
55+};
56+```
57+this could be most useful for testing a particular plug-in in isolation.
58+59+## FAQ {#sec-pantheon-faq}
60+61+[I have switched from a different desktop and Pantheon’s theming looks messed up.]{#sec-pantheon-faq-messed-up-theme}
62+ : Open Switchboard and go to: Administration → About → Restore Default Settings → Restore Settings. This will reset any dconf settings to their Pantheon defaults. Note this could reset certain GNOME specific preferences if that desktop was used prior.
63+64+[I cannot enable both GNOME and Pantheon.]{#sec-pantheon-faq-gnome-and-pantheon}
65+ : This is a known [issue](https://github.com/NixOS/nixpkgs/issues/64611) and there is no known workaround.
66+67+[Does AppCenter work, or is it available?]{#sec-pantheon-faq-appcenter}
68+ : AppCenter has been available since 20.03. Starting from 21.11, the Flatpak backend should work so you can install some Flatpak applications using it. However, due to missing appstream metadata, the Packagekit backend does not function currently. See this [issue](https://github.com/NixOS/nixpkgs/issues/15932).
69+70+ If you are using Pantheon, AppCenter should be installed by default if you have [Flatpak support](#module-services-flatpak) enabled. If you also wish to add the `appcenter` Flatpak remote:
71+72+ ```ShellSession
73+ $ flatpak remote-add --if-not-exists appcenter https://flatpak.elementary.io/repo.flatpakrepo
74+ ```
···1-<chapter xmlns="http://docbook.org/ns/docbook"
2- xmlns:xlink="http://www.w3.org/1999/xlink"
3- xml:id="chap-pantheon">
4- <title>Pantheon Desktop</title>
5- <para>
6- Pantheon is the desktop environment created for the elementary OS distribution. It is written from scratch in Vala, utilizing GNOME technologies with GTK and Granite.
7- </para>
8- <section xml:id="sec-pantheon-enable">
9- <title>Enabling Pantheon</title>
10-11 <para>
12- All of Pantheon is working in NixOS and the applications should be available, aside from a few <link xlink:href="https://github.com/NixOS/nixpkgs/issues/58161">exceptions</link>. To enable Pantheon, set
13-<programlisting>
14-<xref linkend="opt-services.xserver.desktopManager.pantheon.enable"/> = true;
0000000000015</programlisting>
16- This automatically enables LightDM and Pantheon's LightDM greeter. If you'd like to disable this, set
17-<programlisting>
18-<xref linkend="opt-services.xserver.displayManager.lightdm.greeters.pantheon.enable"/> = false;
19-<xref linkend="opt-services.xserver.displayManager.lightdm.enable"/> = false;
00020</programlisting>
21- but please be aware using Pantheon without LightDM as a display manager will break screenlocking from the UI. The NixOS module for Pantheon installs all of Pantheon's default applications. If you'd like to not install Pantheon's apps, set
22-<programlisting>
23-<xref linkend="opt-services.pantheon.apps.enable"/> = false;
0000024</programlisting>
25- You can also use <xref linkend="opt-environment.pantheon.excludePackages"/> to remove any other app (like <package>elementary-mail</package>).
26- </para>
27- </section>
28- <section xml:id="sec-pantheon-wingpanel-switchboard">
29- <title>Wingpanel and Switchboard plugins</title>
30-31- <para>
32- Wingpanel and Switchboard work differently than they do in other distributions, as far as using plugins. You cannot install a plugin globally (like with <option>environment.systemPackages</option>) to start using it. You should instead be using the following options:
33- <itemizedlist>
34- <listitem>
35- <para>
36- <xref linkend="opt-services.xserver.desktopManager.pantheon.extraWingpanelIndicators"/>
37- </para>
38- </listitem>
39- <listitem>
40- <para>
41- <xref linkend="opt-services.xserver.desktopManager.pantheon.extraSwitchboardPlugs"/>
42- </para>
43- </listitem>
44- </itemizedlist>
45- to configure the programs with plugs or indicators.
46- </para>
47-48- <para>
49- The difference in NixOS is both these programs are patched to load plugins from a directory that is the value of an environment variable. All of which is controlled in Nix. If you need to configure the particular packages manually you can override the packages like:
50-<programlisting>
00000000000051wingpanel-with-indicators.override {
52 indicators = [
53 pkgs.some-special-indicator
···60 ];
61};
62</programlisting>
63- please note that, like how the NixOS options describe these as extra plugins, this would only add to the default plugins included with the programs. If for some reason you'd like to configure which plugins to use exactly, both packages have an argument for this:
64-<programlisting>
00000065wingpanel-with-indicators.override {
66 useDefaultIndicators = false;
67 indicators = specialListOfIndicators;
···72 plugs = specialListOfPlugs;
73};
74</programlisting>
75- this could be most useful for testing a particular plug-in in isolation.
76- </para>
77- </section>
78- <section xml:id="sec-pantheon-faq">
79- <title>FAQ</title>
80-81- <variablelist>
82- <varlistentry xml:id="sec-pantheon-faq-messed-up-theme">
83- <term>
84- I have switched from a different desktop and Pantheon’s theming looks messed up.
85- </term>
86- <listitem>
87- <para>
88- Open Switchboard and go to: <guilabel>Administration</guilabel> → <guilabel>About</guilabel> → <guilabel>Restore Default Settings</guilabel> → <guibutton>Restore Settings</guibutton>. This will reset any dconf settings to their Pantheon defaults. Note this could reset certain GNOME specific preferences if that desktop was used prior.
89- </para>
90- </listitem>
91- </varlistentry>
92- <varlistentry xml:id="sec-pantheon-faq-gnome-and-pantheon">
93- <term>
94- I cannot enable both GNOME and Pantheon.
95- </term>
96- <listitem>
97- <para>
98- This is a known <link xlink:href="https://github.com/NixOS/nixpkgs/issues/64611">issue</link> and there is no known workaround.
99- </para>
100- </listitem>
101- </varlistentry>
102- <varlistentry xml:id="sec-pantheon-faq-appcenter">
103- <term>
104- Does AppCenter work, or is it available?
105- </term>
106- <listitem>
107- <para>
108- AppCenter has been available since 20.03. Starting from 21.11, the Flatpak backend should work so you can install some Flatpak applications using it. However, due to missing appstream metadata, the Packagekit backend does not function currently. See this <link xlink:href="https://github.com/NixOS/nixpkgs/issues/15932">issue</link>.
109- </para>
110- <para>
111- If you are using Pantheon, AppCenter should be installed by default if you have <link linkend="module-services-flatpak">Flatpak support</link> enabled. If you also wish to add the <literal>appcenter</literal> Flatpak remote:
112- </para>
113-<screen>
114-<prompt>$ </prompt>flatpak remote-add --if-not-exists appcenter https://flatpak.elementary.io/repo.flatpakrepo
115-</screen>
116- </listitem>
117- </varlistentry>
118- </variablelist>
119- </section>
00000000000000000000120</chapter>
···1+<!-- Do not edit this file directly, edit its companion .md instead
2+ and regenerate this file using nixos/doc/manual/md-to-db.sh -->
3+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="chap-pantheon">
4+ <title>Pantheon Desktop</title>
0000005 <para>
6+ Pantheon is the desktop environment created for the elementary OS
7+ distribution. It is written from scratch in Vala, utilizing GNOME
8+ technologies with GTK and Granite.
9+ </para>
10+ <section xml:id="sec-pantheon-enable">
11+ <title>Enabling Pantheon</title>
12+ <para>
13+ All of Pantheon is working in NixOS and the applications should be
14+ available, aside from a few
15+ <link xlink:href="https://github.com/NixOS/nixpkgs/issues/58161">exceptions</link>.
16+ To enable Pantheon, set
17+ </para>
18+ <programlisting>
19+services.xserver.desktopManager.pantheon.enable = true;
20</programlisting>
21+ <para>
22+ This automatically enables LightDM and Pantheon’s LightDM greeter.
23+ If you’d like to disable this, set
24+ </para>
25+ <programlisting>
26+services.xserver.displayManager.lightdm.greeters.pantheon.enable = false;
27+services.xserver.displayManager.lightdm.enable = false;
28</programlisting>
29+ <para>
30+ but please be aware using Pantheon without LightDM as a display
31+ manager will break screenlocking from the UI. The NixOS module for
32+ Pantheon installs all of Pantheon’s default applications. If you’d
33+ like to not install Pantheon’s apps, set
34+ </para>
35+ <programlisting>
36+services.pantheon.apps.enable = false;
37</programlisting>
38+ <para>
39+ You can also use
40+ <xref linkend="opt-environment.pantheon.excludePackages" /> to
41+ remove any other app (like <literal>elementary-mail</literal>).
42+ </para>
43+ </section>
44+ <section xml:id="sec-pantheon-wingpanel-switchboard">
45+ <title>Wingpanel and Switchboard plugins</title>
46+ <para>
47+ Wingpanel and Switchboard work differently than they do in other
48+ distributions, as far as using plugins. You cannot install a
49+ plugin globally (like with
50+ <option>environment.systemPackages</option>) to start using it.
51+ You should instead be using the following options:
52+ </para>
53+ <itemizedlist spacing="compact">
54+ <listitem>
55+ <para>
56+ <xref linkend="opt-services.xserver.desktopManager.pantheon.extraWingpanelIndicators" />
57+ </para>
58+ </listitem>
59+ <listitem>
60+ <para>
61+ <xref linkend="opt-services.xserver.desktopManager.pantheon.extraSwitchboardPlugs" />
62+ </para>
63+ </listitem>
64+ </itemizedlist>
65+ <para>
66+ to configure the programs with plugs or indicators.
67+ </para>
68+ <para>
69+ The difference in NixOS is both these programs are patched to load
70+ plugins from a directory that is the value of an environment
71+ variable. All of which is controlled in Nix. If you need to
72+ configure the particular packages manually you can override the
73+ packages like:
74+ </para>
75+ <programlisting>
76wingpanel-with-indicators.override {
77 indicators = [
78 pkgs.some-special-indicator
···85 ];
86};
87</programlisting>
88+ <para>
89+ please note that, like how the NixOS options describe these as
90+ extra plugins, this would only add to the default plugins included
91+ with the programs. If for some reason you’d like to configure
92+ which plugins to use exactly, both packages have an argument for
93+ this:
94+ </para>
95+ <programlisting>
96wingpanel-with-indicators.override {
97 useDefaultIndicators = false;
98 indicators = specialListOfIndicators;
···103 plugs = specialListOfPlugs;
104};
105</programlisting>
106+ <para>
107+ this could be most useful for testing a particular plug-in in
108+ isolation.
109+ </para>
110+ </section>
111+ <section xml:id="sec-pantheon-faq">
112+ <title>FAQ</title>
113+ <variablelist spacing="compact">
114+ <varlistentry>
115+ <term>
116+ <anchor xml:id="sec-pantheon-faq-messed-up-theme" />I have
117+ switched from a different desktop and Pantheon’s theming looks
118+ messed up.
119+ </term>
120+ <listitem>
121+ <para>
122+ Open Switchboard and go to: Administration → About → Restore
123+ Default Settings → Restore Settings. This will reset any
124+ dconf settings to their Pantheon defaults. Note this could
125+ reset certain GNOME specific preferences if that desktop was
126+ used prior.
127+ </para>
128+ </listitem>
129+ </varlistentry>
130+ <varlistentry>
131+ <term>
132+ <anchor xml:id="sec-pantheon-faq-gnome-and-pantheon" />I
133+ cannot enable both GNOME and Pantheon.
134+ </term>
135+ <listitem>
136+ <para>
137+ This is a known
138+ <link xlink:href="https://github.com/NixOS/nixpkgs/issues/64611">issue</link>
139+ and there is no known workaround.
140+ </para>
141+ </listitem>
142+ </varlistentry>
143+ <varlistentry>
144+ <term>
145+ <anchor xml:id="sec-pantheon-faq-appcenter" />Does AppCenter
146+ work, or is it available?
147+ </term>
148+ <listitem>
149+ <para>
150+ AppCenter has been available since 20.03. Starting from
151+ 21.11, the Flatpak backend should work so you can install
152+ some Flatpak applications using it. However, due to missing
153+ appstream metadata, the Packagekit backend does not function
154+ currently. See this
155+ <link xlink:href="https://github.com/NixOS/nixpkgs/issues/15932">issue</link>.
156+ </para>
157+ <para>
158+ If you are using Pantheon, AppCenter should be installed by
159+ default if you have
160+ <link linkend="module-services-flatpak">Flatpak
161+ support</link> enabled. If you also wish to add the
162+ <literal>appcenter</literal> Flatpak remote:
163+ </para>
164+ <programlisting>
165+$ flatpak remote-add --if-not-exists appcenter https://flatpak.elementary.io/repo.flatpakrepo
166+</programlisting>
167+ </listitem>
168+ </varlistentry>
169+ </variablelist>
170+ </section>
171</chapter>
···20}
21```
2223-## Developing Custom Bootloader Backends
2425Bootloaders should use [RFC-0125](https://github.com/NixOS/rfcs/pull/125)'s Bootspec format and synthesis tools to identify the key properties for bootable system generations.
26
···20}
21```
2223+## Developing Custom Bootloader Backends {#sec-bootloader-external-developing}
2425Bootloaders should use [RFC-0125](https://github.com/NixOS/rfcs/pull/125)'s Bootspec format and synthesis tools to identify the key properties for bootable system generations.
26
···28, buildPackages ? {}
29, targetPackages ? {}
30, useMacosReexportHack ? false
03132# Darwin code signing support utilities
33, postLinkSignHook ? null, signingUtils ? null
···159 exec="$ldPath/${targetPrefix}ld"
160 wrap ld-solaris ${./ld-solaris-wrapper.sh}
161 '')
000000000000162163 # Create symlinks for rest of the binaries.
164 + ''
···28, buildPackages ? {}
29, targetPackages ? {}
30, useMacosReexportHack ? false
31+, wrapGas ? false
3233# Darwin code signing support utilities
34, postLinkSignHook ? null, signingUtils ? null
···160 exec="$ldPath/${targetPrefix}ld"
161 wrap ld-solaris ${./ld-solaris-wrapper.sh}
162 '')
163+164+ # If we are asked to wrap `gas` and this bintools has it,
165+ # then symlink it (`as` will be symlinked next).
166+ # This is mainly for the wrapped gnatboot on x86-64 Darwin,
167+ # as it must have both the GNU assembler from cctools (installed as `gas`)
168+ # and the Clang integrated assembler (installed as `as`).
169+ # See pkgs/os-specific/darwin/binutils/default.nix for details.
170+ + lib.optionalString wrapGas ''
171+ if [ -e $ldPath/${targetPrefix}gas ]; then
172+ ln -s $ldPath/${targetPrefix}gas $out/bin/${targetPrefix}gas
173+ fi
174+ ''
175176 # Create symlinks for rest of the binaries.
177 + ''
···1+# See add-flags.sh in cc-wrapper for comments.
2+var_templates_list=(
3+ NIX_GNATMAKE_CARGS
4+)
5+6+accumulateRoles
7+8+for var in "${var_templates_list[@]}"; do
9+ mangleVarList "$var" ${role_suffixes[@]+"${role_suffixes[@]}"}
10+done
11+12+# `-B@out@/bin' forces cc to use wrapped as instead of the system one.
13+NIX_GNATMAKE_CARGS_@suffixSalt@="$NIX_GNATMAKE_CARGS_@suffixSalt@ -B@out@/bin/"
14+15+# Only add darwin min version flag if a default darwin min version is set,
16+# which is a signal that we're targetting darwin.
17+if [ "@darwinMinVersion@" ]; then
18+ mangleVarSingle @darwinMinVersionVariable@ ${role_suffixes[@]+"${role_suffixes[@]}"}
19+20+ NIX_GNATMAKE_CARGS_@suffixSalt@="-m@darwinPlatformForCC@-version-min=${@darwinMinVersionVariable@_@suffixSalt@:-@darwinMinVersion@} $NIX_GNATMAKE_CARGS_@suffixSalt@"
21+fi
22+23+export NIX_GNAT_WRAPPER_EXTRA_FLAGS_SET_@suffixSalt@=1
+12-3
pkgs/build-support/cc-wrapper/default.nix
···231 fi
232 ''
2330234 + optionalString cc.langAda or false ''
235- wrap ${targetPrefix}gnatmake ${./gnat-wrapper.sh} $ccPath/${targetPrefix}gnatmake
236- wrap ${targetPrefix}gnatbind ${./gnat-wrapper.sh} $ccPath/${targetPrefix}gnatbind
237- wrap ${targetPrefix}gnatlink ${./gnat-wrapper.sh} $ccPath/${targetPrefix}gnatlink
0000238239 # this symlink points to the unwrapped gnat's output "out". It is used by
240 # our custom gprconfig compiler description to find GNAT's ada runtime. See
···511 substituteAll ${./add-flags.sh} $out/nix-support/add-flags.sh
512 substituteAll ${./add-hardening.sh} $out/nix-support/add-hardening.sh
513 substituteAll ${../wrapper-common/utils.bash} $out/nix-support/utils.bash
0000514 ''
515516 ##
···231 fi
232 ''
233234+ # No need to wrap gnat, gnatkr, gnatname or gnatprep; we can just symlink them in
235 + optionalString cc.langAda or false ''
236+ for cmd in gnatbind gnatchop gnatclean gnatlink gnatls gnatmake; do
237+ wrap ${targetPrefix}$cmd ${./gnat-wrapper.sh} $ccPath/${targetPrefix}$cmd
238+ done
239+240+ for cmd in gnat gnatkr gnatname gnatprep; do
241+ ln -s $ccPath/${targetPrefix}$cmd $out/bin/${targetPrefix}$cmd
242+ done
243244 # this symlink points to the unwrapped gnat's output "out". It is used by
245 # our custom gprconfig compiler description to find GNAT's ada runtime. See
···516 substituteAll ${./add-flags.sh} $out/nix-support/add-flags.sh
517 substituteAll ${./add-hardening.sh} $out/nix-support/add-hardening.sh
518 substituteAll ${../wrapper-common/utils.bash} $out/nix-support/utils.bash
519+ ''
520+521+ + optionalString cc.langAda or false ''
522+ substituteAll ${./add-gnat-extra-flags.sh} $out/nix-support/add-gnat-extra-flags.sh
523 ''
524525 ##
+29-14
pkgs/build-support/cc-wrapper/gnat-wrapper.sh
···29 source @out@/nix-support/add-flags.sh
30fi
310003233# Parse command line options and set several variables.
34# For instance, figure out if linker flags should be passed.
···124 params=(${rest+"${rest[@]}"})
125fi
126127-if [ "$(basename $0)x" = "gnatmakex" ]; then
128- extraBefore=("--GNATBIND=@out@/bin/gnatbind" "--GNATLINK=@out@/bin/gnatlink")
129- extraAfter=($NIX_GNATFLAGS_COMPILE_@suffixSalt@)
130-fi
131-132-if [ "$(basename $0)x" = "gnatbindx" ]; then
133- extraBefore=()
134- extraAfter=($NIX_GNATFLAGS_COMPILE_@suffixSalt@)
135-fi
136-137-if [ "$(basename $0)x" = "gnatlinkx" ]; then
138- extraBefore=()
139- extraAfter=("--GCC=@out@/bin/gcc")
140-fi
000000000000141142# As a very special hack, if the arguments are just `-v', then don't
143# add anything. This is to prevent `gcc -v' (which normally prints
···29 source @out@/nix-support/add-flags.sh
30fi
3132+if [ -z "${NIX_GNAT_WRAPPER_EXTRA_FLAGS_SET_@suffixSalt@:-}" ]; then
33+ source @out@/nix-support/add-gnat-extra-flags.sh
34+fi
3536# Parse command line options and set several variables.
37# For instance, figure out if linker flags should be passed.
···127 params=(${rest+"${rest[@]}"})
128fi
129130+case "$(basename $0)x" in
131+ "gnatbindx")
132+ extraBefore=()
133+ extraAfter=($NIX_GNATFLAGS_COMPILE_@suffixSalt@)
134+ ;;
135+ "gnatchopx")
136+ extraBefore=("--GCC=@out@/bin/gcc")
137+ extraAfter=()
138+ ;;
139+ "gnatcleanx")
140+ extraBefore=($NIX_GNATFLAGS_COMPILE_@suffixSalt@)
141+ extraAfter=()
142+ ;;
143+ "gnatlinkx")
144+ extraBefore=()
145+ extraAfter=("--GCC=@out@/bin/gcc")
146+ ;;
147+ "gnatlsx")
148+ extraBefore=()
149+ extraAfter=($NIX_GNATFLAGS_COMPILE_@suffixSalt@)
150+ ;;
151+ "gnatmakex")
152+ extraBefore=("--GNATBIND=@out@/bin/gnatbind" "--GNATLINK=@out@/bin/gnatlink")
153+ extraAfter=($NIX_GNATFLAGS_COMPILE_@suffixSalt@ -cargs $NIX_GNATMAKE_CARGS_@suffixSalt@)
154+ ;;
155+esac
156157# As a very special hack, if the arguments are just `-v', then don't
158# add anything. This is to prevent `gcc -v' (which normally prints
···1+As originally implemented, the error message check
2+described in the configure script
3+breaks detection of Ada compiler support on x86_64-darwin,
4+because the assembler in the version of cctools currently used
5+unconditionally emits a deprecation message to stdout,
6+with no way to disable it.
7+8+Furthermore, GCC 3.4 was the minimum version needed to build GNAT
9+as far back as GCC 4.4 (see the GCC git repo, tags/releases/gcc-4.4.0,
10+gcc/doc/install.texi, lines 2052-2053 [1]);
11+GCC 3.4 is newer than any of the broken GCC versions
12+that the configure script works around
13+(see the part of the comment in the configure script
14+before the context in the patch below),
15+and GCC 4.4 is older than any GCC that Nix currently packages (GCC 4.8).
16+17+We therefore choose to not check for error messages,
18+and just check for an error code.
19+There's no harm in still checking for an object file being created, though.
20+21+[1]: https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/doc/install.texi;h=6bdfbece981f7fb6c26da672d45e5d3ba7879c69;hb=b7fc996728085c0591ea7c5d0e1c84a8f6a29bd8#l2052
22+--- a/configure 2022-08-19 18:09:52.000000000 +1000
23++++ b/configure 2022-12-26 17:30:49.000000000 +1100
24+@@ -5622,8 +5622,7 @@
25+ # Other compilers, like HP Tru64 UNIX cc, exit successfully when
26+ # given a .adb file, but produce no object file. So we must check
27+ # if an object file was really produced to guard against this.
28+-errors=`(${CC} -c conftest.adb) 2>&1 || echo failure`
29+-if test x"$errors" = x && test -f conftest.$ac_objext; then
30++if ${CC} -c conftest.adb && test -f conftest.$ac_objext; then
31+ acx_cv_cc_gcc_supports_ada=yes
32+ fi
33+ rm -f conftest.*
···1+{ lib, version, buildPlatform, hostPlatform, targetPlatform
2, gnatboot ? null
3, langAda ? false
4, langJava ? false
···22 export lib=$out;
23'' + lib.optionalString langAda ''
24 export PATH=${gnatboot}/bin:$PATH
25+''
26+27+# On x86_64-darwin, the gnatboot bootstrap compiler that we need to build a
28+# native GCC with Ada support emits assembly that is accepted by the Clang
29+# integrated assembler, but not by the GNU assembler in cctools-port that Nix
30+# usually in the x86_64-darwin stdenv. In particular, x86_64-darwin gnatboot
31+# emits MOVQ as the mnemonic for quadword interunit moves, such as between XMM
32+# and general registers (e.g "movq %xmm0, %rbp"); the cctools-port assembler,
33+# however, only recognises MOVD for such moves.
34+#
35+# Therefore, for native x86_64-darwin builds that support Ada, we have to use
36+# the Clang integrated assembler to build (at least stage 1 of) GCC, but have to
37+# target GCC at the cctools-port GNU assembler. In the wrapped x86_64-darwin
38+# gnatboot, the former is provided as `as`, while the latter is provided as
39+# `gas`.
40+#
41++ lib.optionalString (
42+ langAda
43+ && buildPlatform == hostPlatform
44+ && hostPlatform == targetPlatform
45+ && targetPlatform.isx86_64
46+ && targetPlatform.isDarwin
47+ ) ''
48+ export AS_FOR_BUILD=${gnatboot}/bin/as
49+ export AS_FOR_TARGET=${gnatboot}/bin/gas
50''
5152# NOTE 2020/3/18: This environment variable prevents configure scripts from
···1-{ lib, stdenv, makeWrapper, binutils-unwrapped, cctools, llvm, clang-unwrapped }:
23# Make sure both underlying packages claim to have prepended their binaries
4# with the same targetPrefix.
···1516# TODO: loop over targetPrefixed binaries too
17stdenv.mkDerivation {
18- pname = "${targetPrefix}cctools-binutils-darwin";
19 inherit (cctools) version;
20 outputs = [ "out" "man" ];
21 buildCommand = ''
···59 rm $out/bin/${targetPrefix}as
60 makeWrapper "${clang-unwrapped}/bin/clang" "$out/bin/${targetPrefix}as" \
61 --add-flags "-x assembler -integrated-as -c"
00000000000000000000000062 '';
6364- nativeBuildInputs = lib.optionals stdenv.isAarch64 [ makeWrapper ];
6566 passthru = {
67 inherit targetPrefix;
···1+{ lib, stdenv, makeWrapper, binutils-unwrapped, cctools, llvm, clang-unwrapped, dualAs ? false }:
23# Make sure both underlying packages claim to have prepended their binaries
4# with the same targetPrefix.
···1516# TODO: loop over targetPrefixed binaries too
17stdenv.mkDerivation {
18+ pname = "${targetPrefix}cctools-binutils-darwin" + lib.optionalString dualAs "-dualas";
19 inherit (cctools) version;
20 outputs = [ "out" "man" ];
21 buildCommand = ''
···59 rm $out/bin/${targetPrefix}as
60 makeWrapper "${clang-unwrapped}/bin/clang" "$out/bin/${targetPrefix}as" \
61 --add-flags "-x assembler -integrated-as -c"
62+ ''
63+ # x86-64 Darwin gnatboot emits assembly
64+ # with MOVQ as the mnemonic for quadword interunit moves
65+ # such as `movq %rbp, %xmm0`.
66+ # The clang integrated assembler recognises this as valid,
67+ # but unfortunately the cctools-port GNU assembler does not;
68+ # it instead uses MOVD as the mnemonic.
69+ # The assembly that a GCC build emits is determined at build time
70+ # and cannot be changed afterwards.
71+ #
72+ # To build GNAT on x86-64 Darwin, therefore,
73+ # we need both the clang _and_ the cctools-port assemblers to be available:
74+ # the former to build at least the stage1 compiler,
75+ # and the latter at least to be detectable
76+ # as the target for the final compiler.
77+ #
78+ # We choose to match the Aarch64 case above,
79+ # wrapping the clang integrated assembler as `as`.
80+ # It then seems sensible to wrap the cctools GNU assembler as `gas`.
81+ #
82+ + lib.optionalString (stdenv.isx86_64 && dualAs) ''
83+ mv $out/bin/${targetPrefix}as $out/bin/${targetPrefix}gas
84+ makeWrapper "${clang-unwrapped}/bin/clang" "$out/bin/${targetPrefix}as" \
85+ --add-flags "-x assembler -integrated-as -c"
86 '';
8788+ nativeBuildInputs = lib.optionals (stdenv.isAarch64 || dualAs) [ makeWrapper ];
8990 passthru = {
91 inherit targetPrefix;