···11+# Discourse {#module-services-discourse}
22+33+[Discourse](https://www.discourse.org/) is a
44+modern and open source discussion platform.
55+66+## Basic usage {#module-services-discourse-basic-usage}
77+88+A minimal configuration using Let's Encrypt for TLS certificates looks like this:
99+```
1010+services.discourse = {
1111+ enable = true;
1212+ hostname = "discourse.example.com";
1313+ admin = {
1414+ email = "admin@example.com";
1515+ username = "admin";
1616+ fullName = "Administrator";
1717+ passwordFile = "/path/to/password_file";
1818+ };
1919+ secretKeyBaseFile = "/path/to/secret_key_base_file";
2020+};
2121+security.acme.email = "me@example.com";
2222+security.acme.acceptTerms = true;
2323+```
2424+2525+Provided a proper DNS setup, you'll be able to connect to the
2626+instance at `discourse.example.com` and log in
2727+using the credentials provided in
2828+`services.discourse.admin`.
2929+3030+## Using a regular TLS certificate {#module-services-discourse-tls}
3131+3232+To set up TLS using a regular certificate and key on file, use
3333+the [](#opt-services.discourse.sslCertificate)
3434+and [](#opt-services.discourse.sslCertificateKey)
3535+options:
3636+3737+```
3838+services.discourse = {
3939+ enable = true;
4040+ hostname = "discourse.example.com";
4141+ sslCertificate = "/path/to/ssl_certificate";
4242+ sslCertificateKey = "/path/to/ssl_certificate_key";
4343+ admin = {
4444+ email = "admin@example.com";
4545+ username = "admin";
4646+ fullName = "Administrator";
4747+ passwordFile = "/path/to/password_file";
4848+ };
4949+ secretKeyBaseFile = "/path/to/secret_key_base_file";
5050+};
5151+```
5252+5353+## Database access {#module-services-discourse-database}
5454+5555+Discourse uses PostgreSQL to store most of its
5656+data. A database will automatically be enabled and a database
5757+and role created unless [](#opt-services.discourse.database.host) is changed from
5858+its default of `null` or [](#opt-services.discourse.database.createLocally) is set
5959+to `false`.
6060+6161+External database access can also be configured by setting
6262+[](#opt-services.discourse.database.host),
6363+[](#opt-services.discourse.database.username) and
6464+[](#opt-services.discourse.database.passwordFile) as
6565+appropriate. Note that you need to manually create a database
6666+called `discourse` (or the name you chose in
6767+[](#opt-services.discourse.database.name)) and
6868+allow the configured database user full access to it.
6969+7070+## Email {#module-services-discourse-mail}
7171+7272+In addition to the basic setup, you'll want to configure an SMTP
7373+server Discourse can use to send user
7474+registration and password reset emails, among others. You can
7575+also optionally let Discourse receive
7676+email, which enables people to reply to threads and conversations
7777+via email.
7878+7979+A basic setup which assumes you want to use your configured
8080+[hostname](#opt-services.discourse.hostname) as
8181+email domain can be done like this:
8282+8383+```
8484+services.discourse = {
8585+ enable = true;
8686+ hostname = "discourse.example.com";
8787+ sslCertificate = "/path/to/ssl_certificate";
8888+ sslCertificateKey = "/path/to/ssl_certificate_key";
8989+ admin = {
9090+ email = "admin@example.com";
9191+ username = "admin";
9292+ fullName = "Administrator";
9393+ passwordFile = "/path/to/password_file";
9494+ };
9595+ mail.outgoing = {
9696+ serverAddress = "smtp.emailprovider.com";
9797+ port = 587;
9898+ username = "user@emailprovider.com";
9999+ passwordFile = "/path/to/smtp_password_file";
100100+ };
101101+ mail.incoming.enable = true;
102102+ secretKeyBaseFile = "/path/to/secret_key_base_file";
103103+};
104104+```
105105+106106+This assumes you have set up an MX record for the address you've
107107+set in [hostname](#opt-services.discourse.hostname) and
108108+requires proper SPF, DKIM and DMARC configuration to be done for
109109+the domain you're sending from, in order for email to be reliably delivered.
110110+111111+If you want to use a different domain for your outgoing email
112112+(for example `example.com` instead of
113113+`discourse.example.com`) you should set
114114+[](#opt-services.discourse.mail.notificationEmailAddress) and
115115+[](#opt-services.discourse.mail.contactEmailAddress) manually.
116116+117117+::: {.note}
118118+Setup of TLS for incoming email is currently only configured
119119+automatically when a regular TLS certificate is used, i.e. when
120120+[](#opt-services.discourse.sslCertificate) and
121121+[](#opt-services.discourse.sslCertificateKey) are
122122+set.
123123+:::
124124+125125+## Additional settings {#module-services-discourse-settings}
126126+127127+Additional site settings and backend settings, for which no
128128+explicit NixOS options are provided,
129129+can be set in [](#opt-services.discourse.siteSettings) and
130130+[](#opt-services.discourse.backendSettings) respectively.
131131+132132+### Site settings {#module-services-discourse-site-settings}
133133+134134+"Site settings" are the settings that can be
135135+changed through the Discourse
136136+UI. Their *default* values can be set using
137137+[](#opt-services.discourse.siteSettings).
138138+139139+Settings are expressed as a Nix attribute set which matches the
140140+structure of the configuration in
141141+[config/site_settings.yml](https://github.com/discourse/discourse/blob/master/config/site_settings.yml).
142142+To find a setting's path, you only need to care about the first
143143+two levels; i.e. its category (e.g. `login`)
144144+and name (e.g. `invite_only`).
145145+146146+Settings containing secret data should be set to an attribute
147147+set containing the attribute `_secret` - a
148148+string pointing to a file containing the value the option
149149+should be set to. See the example.
150150+151151+### Backend settings {#module-services-discourse-backend-settings}
152152+153153+Settings are expressed as a Nix attribute set which matches the
154154+structure of the configuration in
155155+[config/discourse.conf](https://github.com/discourse/discourse/blob/stable/config/discourse_defaults.conf).
156156+Empty parameters can be defined by setting them to
157157+`null`.
158158+159159+### Example {#module-services-discourse-settings-example}
160160+161161+The following example sets the title and description of the
162162+Discourse instance and enables
163163+GitHub login in the site settings,
164164+and changes a few request limits in the backend settings:
165165+```
166166+services.discourse = {
167167+ enable = true;
168168+ hostname = "discourse.example.com";
169169+ sslCertificate = "/path/to/ssl_certificate";
170170+ sslCertificateKey = "/path/to/ssl_certificate_key";
171171+ admin = {
172172+ email = "admin@example.com";
173173+ username = "admin";
174174+ fullName = "Administrator";
175175+ passwordFile = "/path/to/password_file";
176176+ };
177177+ mail.outgoing = {
178178+ serverAddress = "smtp.emailprovider.com";
179179+ port = 587;
180180+ username = "user@emailprovider.com";
181181+ passwordFile = "/path/to/smtp_password_file";
182182+ };
183183+ mail.incoming.enable = true;
184184+ siteSettings = {
185185+ required = {
186186+ title = "My Cats";
187187+ site_description = "Discuss My Cats (and be nice plz)";
188188+ };
189189+ login = {
190190+ enable_github_logins = true;
191191+ github_client_id = "a2f6dfe838cb3206ce20";
192192+ github_client_secret._secret = /run/keys/discourse_github_client_secret;
193193+ };
194194+ };
195195+ backendSettings = {
196196+ max_reqs_per_ip_per_minute = 300;
197197+ max_reqs_per_ip_per_10_seconds = 60;
198198+ max_asset_reqs_per_ip_per_10_seconds = 250;
199199+ max_reqs_per_ip_mode = "warn+block";
200200+ };
201201+ secretKeyBaseFile = "/path/to/secret_key_base_file";
202202+};
203203+```
204204+205205+In the resulting site settings file, the
206206+`login.github_client_secret` key will be set
207207+to the contents of the
208208+{file}`/run/keys/discourse_github_client_secret`
209209+file.
210210+211211+## Plugins {#module-services-discourse-plugins}
212212+213213+You can install Discourse plugins
214214+using the [](#opt-services.discourse.plugins)
215215+option. Pre-packaged plugins are provided in
216216+`<your_discourse_package_here>.plugins`. If
217217+you want the full suite of plugins provided through
218218+`nixpkgs`, you can also set the [](#opt-services.discourse.package) option to
219219+`pkgs.discourseAllPlugins`.
220220+221221+Plugins can be built with the
222222+`<your_discourse_package_here>.mkDiscoursePlugin`
223223+function. Normally, it should suffice to provide a
224224+`name` and `src` attribute. If
225225+the plugin has Ruby dependencies, however, they need to be
226226+packaged in accordance with the [Developing with Ruby](https://nixos.org/manual/nixpkgs/stable/#developing-with-ruby)
227227+section of the Nixpkgs manual and the
228228+appropriate gem options set in `bundlerEnvArgs`
229229+(normally `gemdir` is sufficient). A plugin's
230230+Ruby dependencies are listed in its
231231+{file}`plugin.rb` file as function calls to
232232+`gem`. To construct the corresponding
233233+{file}`Gemfile` manually, run {command}`bundle init`, then add the `gem` lines to it
234234+verbatim.
235235+236236+Much of the packaging can be done automatically by the
237237+{file}`nixpkgs/pkgs/servers/web-apps/discourse/update.py`
238238+script - just add the plugin to the `plugins`
239239+list in the `update_plugins` function and run
240240+the script:
241241+```bash
242242+./update.py update-plugins
243243+```
244244+245245+Some plugins provide [site settings](#module-services-discourse-site-settings).
246246+Their defaults can be configured using [](#opt-services.discourse.siteSettings), just like
247247+regular site settings. To find the names of these settings, look
248248+in the `config/settings.yml` file of the plugin
249249+repo.
250250+251251+For example, to add the [discourse-spoiler-alert](https://github.com/discourse/discourse-spoiler-alert)
252252+and [discourse-solved](https://github.com/discourse/discourse-solved)
253253+plugins, and disable `discourse-spoiler-alert`
254254+by default:
255255+256256+```
257257+services.discourse = {
258258+ enable = true;
259259+ hostname = "discourse.example.com";
260260+ sslCertificate = "/path/to/ssl_certificate";
261261+ sslCertificateKey = "/path/to/ssl_certificate_key";
262262+ admin = {
263263+ email = "admin@example.com";
264264+ username = "admin";
265265+ fullName = "Administrator";
266266+ passwordFile = "/path/to/password_file";
267267+ };
268268+ mail.outgoing = {
269269+ serverAddress = "smtp.emailprovider.com";
270270+ port = 587;
271271+ username = "user@emailprovider.com";
272272+ passwordFile = "/path/to/smtp_password_file";
273273+ };
274274+ mail.incoming.enable = true;
275275+ plugins = with config.services.discourse.package.plugins; [
276276+ discourse-spoiler-alert
277277+ discourse-solved
278278+ ];
279279+ siteSettings = {
280280+ plugins = {
281281+ spoiler_enabled = false;
282282+ };
283283+ };
284284+ secretKeyBaseFile = "/path/to/secret_key_base_file";
285285+};
286286+```
···11-<chapter xmlns="http://docbook.org/ns/docbook"
22- xmlns:xlink="http://www.w3.org/1999/xlink"
33- xmlns:xi="http://www.w3.org/2001/XInclude"
44- version="5.0"
55- xml:id="module-services-discourse">
66- <title>Discourse</title>
77- <para>
88- <link xlink:href="https://www.discourse.org/">Discourse</link> is a
99- modern and open source discussion platform.
1010- </para>
1111-1212- <section xml:id="module-services-discourse-basic-usage">
1313- <title>Basic usage</title>
1414- <para>
1515- A minimal configuration using Let's Encrypt for TLS certificates looks like this:
1616-<programlisting>
11+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-discourse">
22+ <title>Discourse</title>
33+ <para>
44+ <link xlink:href="https://www.discourse.org/">Discourse</link> is a
55+ modern and open source discussion platform.
66+ </para>
77+ <section xml:id="module-services-discourse-basic-usage">
88+ <title>Basic usage</title>
99+ <para>
1010+ A minimal configuration using Let's Encrypt for TLS certificates
1111+ looks like this:
1212+ </para>
1313+ <programlisting>
1714services.discourse = {
1815 enable = true;
1919- hostname = "discourse.example.com";
1616+ hostname = "discourse.example.com";
2017 admin = {
2121- email = "admin@example.com";
2222- username = "admin";
2323- fullName = "Administrator";
2424- passwordFile = "/path/to/password_file";
1818+ email = "admin@example.com";
1919+ username = "admin";
2020+ fullName = "Administrator";
2121+ passwordFile = "/path/to/password_file";
2522 };
2626- secretKeyBaseFile = "/path/to/secret_key_base_file";
2323+ secretKeyBaseFile = "/path/to/secret_key_base_file";
2724};
2828-security.acme.email = "me@example.com";
2525+security.acme.email = "me@example.com";
2926security.acme.acceptTerms = true;
3027</programlisting>
3131- </para>
3232-3333- <para>
3434- Provided a proper DNS setup, you'll be able to connect to the
3535- instance at <literal>discourse.example.com</literal> and log in
3636- using the credentials provided in
3737- <literal>services.discourse.admin</literal>.
3838- </para>
3939- </section>
4040-4141- <section xml:id="module-services-discourse-tls">
4242- <title>Using a regular TLS certificate</title>
4343- <para>
4444- To set up TLS using a regular certificate and key on file, use
4545- the <xref linkend="opt-services.discourse.sslCertificate" />
4646- and <xref linkend="opt-services.discourse.sslCertificateKey" />
4747- options:
4848-4949-<programlisting>
2828+ <para>
2929+ Provided a proper DNS setup, you'll be able to connect to the
3030+ instance at <literal>discourse.example.com</literal> and log in
3131+ using the credentials provided in
3232+ <literal>services.discourse.admin</literal>.
3333+ </para>
3434+ </section>
3535+ <section xml:id="module-services-discourse-tls">
3636+ <title>Using a regular TLS certificate</title>
3737+ <para>
3838+ To set up TLS using a regular certificate and key on file, use the
3939+ <xref linkend="opt-services.discourse.sslCertificate"></xref> and
4040+ <xref linkend="opt-services.discourse.sslCertificateKey"></xref>
4141+ options:
4242+ </para>
4343+ <programlisting>
5044services.discourse = {
5145 enable = true;
5252- hostname = "discourse.example.com";
5353- sslCertificate = "/path/to/ssl_certificate";
5454- sslCertificateKey = "/path/to/ssl_certificate_key";
4646+ hostname = "discourse.example.com";
4747+ sslCertificate = "/path/to/ssl_certificate";
4848+ sslCertificateKey = "/path/to/ssl_certificate_key";
5549 admin = {
5656- email = "admin@example.com";
5757- username = "admin";
5858- fullName = "Administrator";
5959- passwordFile = "/path/to/password_file";
5050+ email = "admin@example.com";
5151+ username = "admin";
5252+ fullName = "Administrator";
5353+ passwordFile = "/path/to/password_file";
6054 };
6161- secretKeyBaseFile = "/path/to/secret_key_base_file";
5555+ secretKeyBaseFile = "/path/to/secret_key_base_file";
6256};
6357</programlisting>
6464-6565- </para>
6666- </section>
6767-6868- <section xml:id="module-services-discourse-database">
6969- <title>Database access</title>
7070- <para>
7171- Discourse uses
7272- PostgreSQL to store most of its
7373- data. A database will automatically be enabled and a database
7474- and role created unless <xref
7575- linkend="opt-services.discourse.database.host" /> is changed from
7676- its default of <literal>null</literal> or <xref
7777- linkend="opt-services.discourse.database.createLocally" /> is set
7878- to <literal>false</literal>.
7979- </para>
8080-8181- <para>
8282- External database access can also be configured by setting
8383- <xref linkend="opt-services.discourse.database.host" />, <xref
8484- linkend="opt-services.discourse.database.username" /> and <xref
8585- linkend="opt-services.discourse.database.passwordFile" /> as
8686- appropriate. Note that you need to manually create a database
8787- called <literal>discourse</literal> (or the name you chose in
8888- <xref linkend="opt-services.discourse.database.name" />) and
8989- allow the configured database user full access to it.
9090- </para>
9191- </section>
9292-9393- <section xml:id="module-services-discourse-mail">
9494- <title>Email</title>
9595- <para>
9696- In addition to the basic setup, you'll want to configure an SMTP
9797- server Discourse can use to send user
9898- registration and password reset emails, among others. You can
9999- also optionally let Discourse receive
100100- email, which enables people to reply to threads and conversations
101101- via email.
102102- </para>
103103-104104- <para>
105105- A basic setup which assumes you want to use your configured <link
106106- linkend="opt-services.discourse.hostname">hostname</link> as
107107- email domain can be done like this:
108108-109109-<programlisting>
5858+ </section>
5959+ <section xml:id="module-services-discourse-database">
6060+ <title>Database access</title>
6161+ <para>
6262+ Discourse uses PostgreSQL to store most of its data. A database
6363+ will automatically be enabled and a database and role created
6464+ unless
6565+ <xref linkend="opt-services.discourse.database.host"></xref> is
6666+ changed from its default of <literal>null</literal> or
6767+ <xref linkend="opt-services.discourse.database.createLocally"></xref>
6868+ is set to <literal>false</literal>.
6969+ </para>
7070+ <para>
7171+ External database access can also be configured by setting
7272+ <xref linkend="opt-services.discourse.database.host"></xref>,
7373+ <xref linkend="opt-services.discourse.database.username"></xref>
7474+ and
7575+ <xref linkend="opt-services.discourse.database.passwordFile"></xref>
7676+ as appropriate. Note that you need to manually create a database
7777+ called <literal>discourse</literal> (or the name you chose in
7878+ <xref linkend="opt-services.discourse.database.name"></xref>) and
7979+ allow the configured database user full access to it.
8080+ </para>
8181+ </section>
8282+ <section xml:id="module-services-discourse-mail">
8383+ <title>Email</title>
8484+ <para>
8585+ In addition to the basic setup, you'll want to configure an SMTP
8686+ server Discourse can use to send user registration and password
8787+ reset emails, among others. You can also optionally let Discourse
8888+ receive email, which enables people to reply to threads and
8989+ conversations via email.
9090+ </para>
9191+ <para>
9292+ A basic setup which assumes you want to use your configured
9393+ <link linkend="opt-services.discourse.hostname">hostname</link> as
9494+ email domain can be done like this:
9595+ </para>
9696+ <programlisting>
11097services.discourse = {
11198 enable = true;
112112- hostname = "discourse.example.com";
113113- sslCertificate = "/path/to/ssl_certificate";
114114- sslCertificateKey = "/path/to/ssl_certificate_key";
9999+ hostname = "discourse.example.com";
100100+ sslCertificate = "/path/to/ssl_certificate";
101101+ sslCertificateKey = "/path/to/ssl_certificate_key";
115102 admin = {
116116- email = "admin@example.com";
117117- username = "admin";
118118- fullName = "Administrator";
119119- passwordFile = "/path/to/password_file";
103103+ email = "admin@example.com";
104104+ username = "admin";
105105+ fullName = "Administrator";
106106+ passwordFile = "/path/to/password_file";
120107 };
121108 mail.outgoing = {
122122- serverAddress = "smtp.emailprovider.com";
109109+ serverAddress = "smtp.emailprovider.com";
123110 port = 587;
124124- username = "user@emailprovider.com";
125125- passwordFile = "/path/to/smtp_password_file";
111111+ username = "user@emailprovider.com";
112112+ passwordFile = "/path/to/smtp_password_file";
126113 };
127114 mail.incoming.enable = true;
128128- secretKeyBaseFile = "/path/to/secret_key_base_file";
115115+ secretKeyBaseFile = "/path/to/secret_key_base_file";
129116};
130117</programlisting>
131131-132132- This assumes you have set up an MX record for the address you've
133133- set in <link linkend="opt-services.discourse.hostname">hostname</link> and
134134- requires proper SPF, DKIM and DMARC configuration to be done for
135135- the domain you're sending from, in order for email to be reliably delivered.
136136- </para>
137137-138138- <para>
139139- If you want to use a different domain for your outgoing email
140140- (for example <literal>example.com</literal> instead of
141141- <literal>discourse.example.com</literal>) you should set
142142- <xref linkend="opt-services.discourse.mail.notificationEmailAddress" /> and
143143- <xref linkend="opt-services.discourse.mail.contactEmailAddress" /> manually.
144144- </para>
145145-146146- <note>
147147- <para>
148148- Setup of TLS for incoming email is currently only configured
149149- automatically when a regular TLS certificate is used, i.e. when
150150- <xref linkend="opt-services.discourse.sslCertificate" /> and
151151- <xref linkend="opt-services.discourse.sslCertificateKey" /> are
152152- set.
153153- </para>
154154- </note>
155155-156156- </section>
157157-158158- <section xml:id="module-services-discourse-settings">
159159- <title>Additional settings</title>
160160- <para>
161161- Additional site settings and backend settings, for which no
162162- explicit NixOS options are provided,
163163- can be set in <xref linkend="opt-services.discourse.siteSettings" /> and
164164- <xref linkend="opt-services.discourse.backendSettings" /> respectively.
165165- </para>
166166-167167- <section xml:id="module-services-discourse-site-settings">
168168- <title>Site settings</title>
169169- <para>
170170- "Site settings" are the settings that can be
171171- changed through the Discourse
172172- UI. Their <emphasis>default</emphasis> values can be set using
173173- <xref linkend="opt-services.discourse.siteSettings" />.
174174- </para>
175175-176176- <para>
177177- Settings are expressed as a Nix attribute set which matches the
178178- structure of the configuration in
179179- <link xlink:href="https://github.com/discourse/discourse/blob/master/config/site_settings.yml">config/site_settings.yml</link>.
180180- To find a setting's path, you only need to care about the first
181181- two levels; i.e. its category (e.g. <literal>login</literal>)
182182- and name (e.g. <literal>invite_only</literal>).
183183- </para>
184184-185185- <para>
186186- Settings containing secret data should be set to an attribute
187187- set containing the attribute <literal>_secret</literal> - a
188188- string pointing to a file containing the value the option
189189- should be set to. See the example.
190190- </para>
191191- </section>
192192-193193- <section xml:id="module-services-discourse-backend-settings">
194194- <title>Backend settings</title>
195195- <para>
196196- Settings are expressed as a Nix attribute set which matches the
197197- structure of the configuration in
198198- <link xlink:href="https://github.com/discourse/discourse/blob/stable/config/discourse_defaults.conf">config/discourse.conf</link>.
199199- Empty parameters can be defined by setting them to
200200- <literal>null</literal>.
201201- </para>
202202- </section>
203203-204204- <section xml:id="module-services-discourse-settings-example">
205205- <title>Example</title>
206206- <para>
207207- The following example sets the title and description of the
208208- Discourse instance and enables
209209- GitHub login in the site settings,
210210- and changes a few request limits in the backend settings:
211211-<programlisting>
118118+ <para>
119119+ This assumes you have set up an MX record for the address you've
120120+ set in
121121+ <link linkend="opt-services.discourse.hostname">hostname</link>
122122+ and requires proper SPF, DKIM and DMARC configuration to be done
123123+ for the domain you're sending from, in order for email to be
124124+ reliably delivered.
125125+ </para>
126126+ <para>
127127+ If you want to use a different domain for your outgoing email (for
128128+ example <literal>example.com</literal> instead of
129129+ <literal>discourse.example.com</literal>) you should set
130130+ <xref linkend="opt-services.discourse.mail.notificationEmailAddress"></xref>
131131+ and
132132+ <xref linkend="opt-services.discourse.mail.contactEmailAddress"></xref>
133133+ manually.
134134+ </para>
135135+ <note>
136136+ <para>
137137+ Setup of TLS for incoming email is currently only configured
138138+ automatically when a regular TLS certificate is used, i.e. when
139139+ <xref linkend="opt-services.discourse.sslCertificate"></xref>
140140+ and
141141+ <xref linkend="opt-services.discourse.sslCertificateKey"></xref>
142142+ are set.
143143+ </para>
144144+ </note>
145145+ </section>
146146+ <section xml:id="module-services-discourse-settings">
147147+ <title>Additional settings</title>
148148+ <para>
149149+ Additional site settings and backend settings, for which no
150150+ explicit NixOS options are provided, can be set in
151151+ <xref linkend="opt-services.discourse.siteSettings"></xref> and
152152+ <xref linkend="opt-services.discourse.backendSettings"></xref>
153153+ respectively.
154154+ </para>
155155+ <section xml:id="module-services-discourse-site-settings">
156156+ <title>Site settings</title>
157157+ <para>
158158+ "Site settings" are the settings that can be changed
159159+ through the Discourse UI. Their <emphasis>default</emphasis>
160160+ values can be set using
161161+ <xref linkend="opt-services.discourse.siteSettings"></xref>.
162162+ </para>
163163+ <para>
164164+ Settings are expressed as a Nix attribute set which matches the
165165+ structure of the configuration in
166166+ <link xlink:href="https://github.com/discourse/discourse/blob/master/config/site_settings.yml">config/site_settings.yml</link>.
167167+ To find a setting's path, you only need to care about the first
168168+ two levels; i.e. its category (e.g. <literal>login</literal>)
169169+ and name (e.g. <literal>invite_only</literal>).
170170+ </para>
171171+ <para>
172172+ Settings containing secret data should be set to an attribute
173173+ set containing the attribute <literal>_secret</literal> - a
174174+ string pointing to a file containing the value the option should
175175+ be set to. See the example.
176176+ </para>
177177+ </section>
178178+ <section xml:id="module-services-discourse-backend-settings">
179179+ <title>Backend settings</title>
180180+ <para>
181181+ Settings are expressed as a Nix attribute set which matches the
182182+ structure of the configuration in
183183+ <link xlink:href="https://github.com/discourse/discourse/blob/stable/config/discourse_defaults.conf">config/discourse.conf</link>.
184184+ Empty parameters can be defined by setting them to
185185+ <literal>null</literal>.
186186+ </para>
187187+ </section>
188188+ <section xml:id="module-services-discourse-settings-example">
189189+ <title>Example</title>
190190+ <para>
191191+ The following example sets the title and description of the
192192+ Discourse instance and enables GitHub login in the site
193193+ settings, and changes a few request limits in the backend
194194+ settings:
195195+ </para>
196196+ <programlisting>
212197services.discourse = {
213198 enable = true;
214214- hostname = "discourse.example.com";
215215- sslCertificate = "/path/to/ssl_certificate";
216216- sslCertificateKey = "/path/to/ssl_certificate_key";
199199+ hostname = "discourse.example.com";
200200+ sslCertificate = "/path/to/ssl_certificate";
201201+ sslCertificateKey = "/path/to/ssl_certificate_key";
217202 admin = {
218218- email = "admin@example.com";
219219- username = "admin";
220220- fullName = "Administrator";
221221- passwordFile = "/path/to/password_file";
203203+ email = "admin@example.com";
204204+ username = "admin";
205205+ fullName = "Administrator";
206206+ passwordFile = "/path/to/password_file";
222207 };
223208 mail.outgoing = {
224224- serverAddress = "smtp.emailprovider.com";
209209+ serverAddress = "smtp.emailprovider.com";
225210 port = 587;
226226- username = "user@emailprovider.com";
227227- passwordFile = "/path/to/smtp_password_file";
211211+ username = "user@emailprovider.com";
212212+ passwordFile = "/path/to/smtp_password_file";
228213 };
229214 mail.incoming.enable = true;
230215 siteSettings = {
231216 required = {
232232- title = "My Cats";
233233- site_description = "Discuss My Cats (and be nice plz)";
217217+ title = "My Cats";
218218+ site_description = "Discuss My Cats (and be nice plz)";
234219 };
235220 login = {
236221 enable_github_logins = true;
237237- github_client_id = "a2f6dfe838cb3206ce20";
222222+ github_client_id = "a2f6dfe838cb3206ce20";
238223 github_client_secret._secret = /run/keys/discourse_github_client_secret;
239224 };
240225 };
···242227 max_reqs_per_ip_per_minute = 300;
243228 max_reqs_per_ip_per_10_seconds = 60;
244229 max_asset_reqs_per_ip_per_10_seconds = 250;
245245- max_reqs_per_ip_mode = "warn+block";
230230+ max_reqs_per_ip_mode = "warn+block";
246231 };
247247- secretKeyBaseFile = "/path/to/secret_key_base_file";
232232+ secretKeyBaseFile = "/path/to/secret_key_base_file";
248233};
249234</programlisting>
250250- </para>
251251- <para>
252252- In the resulting site settings file, the
253253- <literal>login.github_client_secret</literal> key will be set
254254- to the contents of the
255255- <filename>/run/keys/discourse_github_client_secret</filename>
256256- file.
257257- </para>
258258- </section>
259259- </section>
235235+ <para>
236236+ In the resulting site settings file, the
237237+ <literal>login.github_client_secret</literal> key will be set to
238238+ the contents of the
239239+ <filename>/run/keys/discourse_github_client_secret</filename>
240240+ file.
241241+ </para>
242242+ </section>
243243+ </section>
260244 <section xml:id="module-services-discourse-plugins">
261245 <title>Plugins</title>
262246 <para>
263263- You can install Discourse plugins
264264- using the <xref linkend="opt-services.discourse.plugins" />
265265- option. Pre-packaged plugins are provided in
247247+ You can install Discourse plugins using the
248248+ <xref linkend="opt-services.discourse.plugins"></xref> option.
249249+ Pre-packaged plugins are provided in
266250 <literal><your_discourse_package_here>.plugins</literal>. If
267251 you want the full suite of plugins provided through
268268- <literal>nixpkgs</literal>, you can also set the <xref
269269- linkend="opt-services.discourse.package" /> option to
252252+ <literal>nixpkgs</literal>, you can also set the
253253+ <xref linkend="opt-services.discourse.package"></xref> option to
270254 <literal>pkgs.discourseAllPlugins</literal>.
271255 </para>
272272-273256 <para>
274257 Plugins can be built with the
275258 <literal><your_discourse_package_here>.mkDiscoursePlugin</literal>
276259 function. Normally, it should suffice to provide a
277260 <literal>name</literal> and <literal>src</literal> attribute. If
278261 the plugin has Ruby dependencies, however, they need to be
279279- packaged in accordance with the <link
280280- xlink:href="https://nixos.org/manual/nixpkgs/stable/#developing-with-ruby">Developing
281281- with Ruby</link> section of the Nixpkgs manual and the
282282- appropriate gem options set in <literal>bundlerEnvArgs</literal>
283283- (normally <literal>gemdir</literal> is sufficient). A plugin's
284284- Ruby dependencies are listed in its
285285- <filename>plugin.rb</filename> file as function calls to
286286- <literal>gem</literal>. To construct the corresponding
287287- <filename>Gemfile</filename> manually, run <command>bundle
288288- init</command>, then add the <literal>gem</literal> lines to it
289289- verbatim.
262262+ packaged in accordance with the
263263+ <link xlink:href="https://nixos.org/manual/nixpkgs/stable/#developing-with-ruby">Developing
264264+ with Ruby</link> section of the Nixpkgs manual and the appropriate
265265+ gem options set in <literal>bundlerEnvArgs</literal> (normally
266266+ <literal>gemdir</literal> is sufficient). A plugin's Ruby
267267+ dependencies are listed in its <filename>plugin.rb</filename> file
268268+ as function calls to <literal>gem</literal>. To construct the
269269+ corresponding <filename>Gemfile</filename> manually, run
270270+ <command>bundle init</command>, then add the
271271+ <literal>gem</literal> lines to it verbatim.
290272 </para>
291291-292273 <para>
293274 Much of the packaging can be done automatically by the
294275 <filename>nixpkgs/pkgs/servers/web-apps/discourse/update.py</filename>
295276 script - just add the plugin to the <literal>plugins</literal>
296296- list in the <literal>update_plugins</literal> function and run
297297- the script:
298298- <programlisting language="bash">
277277+ list in the <literal>update_plugins</literal> function and run the
278278+ script:
279279+ </para>
280280+ <programlisting language="bash">
299281./update.py update-plugins
300282</programlisting>
301301- </para>
302302-303283 <para>
304304- Some plugins provide <link
305305- linkend="module-services-discourse-site-settings">site
306306- settings</link>. Their defaults can be configured using <xref
307307- linkend="opt-services.discourse.siteSettings" />, just like
308308- regular site settings. To find the names of these settings, look
309309- in the <literal>config/settings.yml</literal> file of the plugin
310310- repo.
284284+ Some plugins provide
285285+ <link linkend="module-services-discourse-site-settings">site
286286+ settings</link>. Their defaults can be configured using
287287+ <xref linkend="opt-services.discourse.siteSettings"></xref>, just
288288+ like regular site settings. To find the names of these settings,
289289+ look in the <literal>config/settings.yml</literal> file of the
290290+ plugin repo.
311291 </para>
312312-313292 <para>
314314- For example, to add the <link
315315- xlink:href="https://github.com/discourse/discourse-spoiler-alert">discourse-spoiler-alert</link>
316316- and <link
317317- xlink:href="https://github.com/discourse/discourse-solved">discourse-solved</link>
318318- plugins, and disable <literal>discourse-spoiler-alert</literal>
319319- by default:
320320-321321-<programlisting>
293293+ For example, to add the
294294+ <link xlink:href="https://github.com/discourse/discourse-spoiler-alert">discourse-spoiler-alert</link>
295295+ and
296296+ <link xlink:href="https://github.com/discourse/discourse-solved">discourse-solved</link>
297297+ plugins, and disable <literal>discourse-spoiler-alert</literal> by
298298+ default:
299299+ </para>
300300+ <programlisting>
322301services.discourse = {
323302 enable = true;
324324- hostname = "discourse.example.com";
325325- sslCertificate = "/path/to/ssl_certificate";
326326- sslCertificateKey = "/path/to/ssl_certificate_key";
303303+ hostname = "discourse.example.com";
304304+ sslCertificate = "/path/to/ssl_certificate";
305305+ sslCertificateKey = "/path/to/ssl_certificate_key";
327306 admin = {
328328- email = "admin@example.com";
329329- username = "admin";
330330- fullName = "Administrator";
331331- passwordFile = "/path/to/password_file";
307307+ email = "admin@example.com";
308308+ username = "admin";
309309+ fullName = "Administrator";
310310+ passwordFile = "/path/to/password_file";
332311 };
333312 mail.outgoing = {
334334- serverAddress = "smtp.emailprovider.com";
313313+ serverAddress = "smtp.emailprovider.com";
335314 port = 587;
336336- username = "user@emailprovider.com";
337337- passwordFile = "/path/to/smtp_password_file";
315315+ username = "user@emailprovider.com";
316316+ passwordFile = "/path/to/smtp_password_file";
338317 };
339318 mail.incoming.enable = true;
340319 plugins = with config.services.discourse.package.plugins; [
···346325 spoiler_enabled = false;
347326 };
348327 };
349349- secretKeyBaseFile = "/path/to/secret_key_base_file";
328328+ secretKeyBaseFile = "/path/to/secret_key_base_file";
350329};
351330</programlisting>
352352-353353- </para>
354331 </section>
355332</chapter>