2023-01-10 12:34:37 +01:00
|
|
|
|
<!-- Do not edit this file directly, edit its companion .md instead
|
|
|
|
|
and regenerate this file using nixos/doc/manual/md-to-db.sh -->
|
2023-01-03 06:54:04 +01:00
|
|
|
|
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-discourse">
|
|
|
|
|
<title>Discourse</title>
|
|
|
|
|
<para>
|
|
|
|
|
<link xlink:href="https://www.discourse.org/">Discourse</link> is a
|
|
|
|
|
modern and open source discussion platform.
|
|
|
|
|
</para>
|
|
|
|
|
<section xml:id="module-services-discourse-basic-usage">
|
|
|
|
|
<title>Basic usage</title>
|
|
|
|
|
<para>
|
2023-01-04 06:56:24 +01:00
|
|
|
|
A minimal configuration using Let’s Encrypt for TLS certificates
|
2023-01-03 06:54:04 +01:00
|
|
|
|
looks like this:
|
|
|
|
|
</para>
|
|
|
|
|
<programlisting>
|
2021-03-15 16:55:05 +01:00
|
|
|
|
services.discourse = {
|
2023-01-02 22:57:19 +01:00
|
|
|
|
enable = true;
|
2023-01-03 06:54:04 +01:00
|
|
|
|
hostname = "discourse.example.com";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
admin = {
|
2023-01-03 06:54:04 +01:00
|
|
|
|
email = "admin@example.com";
|
|
|
|
|
username = "admin";
|
|
|
|
|
fullName = "Administrator";
|
|
|
|
|
passwordFile = "/path/to/password_file";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
};
|
2023-01-03 06:54:04 +01:00
|
|
|
|
secretKeyBaseFile = "/path/to/secret_key_base_file";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
};
|
2023-01-03 06:54:04 +01:00
|
|
|
|
security.acme.email = "me@example.com";
|
2023-01-02 22:57:19 +01:00
|
|
|
|
security.acme.acceptTerms = true;
|
2021-03-15 16:55:05 +01:00
|
|
|
|
</programlisting>
|
2023-01-03 06:54:04 +01:00
|
|
|
|
<para>
|
2023-01-04 06:56:24 +01:00
|
|
|
|
Provided a proper DNS setup, you’ll be able to connect to the
|
2023-01-03 06:54:04 +01:00
|
|
|
|
instance at <literal>discourse.example.com</literal> and log in
|
|
|
|
|
using the credentials provided in
|
|
|
|
|
<literal>services.discourse.admin</literal>.
|
|
|
|
|
</para>
|
|
|
|
|
</section>
|
|
|
|
|
<section xml:id="module-services-discourse-tls">
|
|
|
|
|
<title>Using a regular TLS certificate</title>
|
|
|
|
|
<para>
|
|
|
|
|
To set up TLS using a regular certificate and key on file, use the
|
2023-01-05 06:16:46 +01:00
|
|
|
|
<xref linkend="opt-services.discourse.sslCertificate" /> and
|
|
|
|
|
<xref linkend="opt-services.discourse.sslCertificateKey" />
|
2023-01-03 06:54:04 +01:00
|
|
|
|
options:
|
|
|
|
|
</para>
|
|
|
|
|
<programlisting>
|
2021-03-15 16:55:05 +01:00
|
|
|
|
services.discourse = {
|
2023-01-02 22:57:19 +01:00
|
|
|
|
enable = true;
|
2023-01-03 06:54:04 +01:00
|
|
|
|
hostname = "discourse.example.com";
|
|
|
|
|
sslCertificate = "/path/to/ssl_certificate";
|
|
|
|
|
sslCertificateKey = "/path/to/ssl_certificate_key";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
admin = {
|
2023-01-03 06:54:04 +01:00
|
|
|
|
email = "admin@example.com";
|
|
|
|
|
username = "admin";
|
|
|
|
|
fullName = "Administrator";
|
|
|
|
|
passwordFile = "/path/to/password_file";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
};
|
2023-01-03 06:54:04 +01:00
|
|
|
|
secretKeyBaseFile = "/path/to/secret_key_base_file";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
};
|
|
|
|
|
</programlisting>
|
2023-01-03 06:54:04 +01:00
|
|
|
|
</section>
|
|
|
|
|
<section xml:id="module-services-discourse-database">
|
|
|
|
|
<title>Database access</title>
|
|
|
|
|
<para>
|
|
|
|
|
Discourse uses PostgreSQL to store most of its data. A database
|
|
|
|
|
will automatically be enabled and a database and role created
|
2023-01-05 06:16:46 +01:00
|
|
|
|
unless <xref linkend="opt-services.discourse.database.host" /> is
|
2023-01-03 06:54:04 +01:00
|
|
|
|
changed from its default of <literal>null</literal> or
|
2023-01-05 06:16:46 +01:00
|
|
|
|
<xref linkend="opt-services.discourse.database.createLocally" />
|
2023-01-03 06:54:04 +01:00
|
|
|
|
is set to <literal>false</literal>.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
External database access can also be configured by setting
|
2023-01-05 06:16:46 +01:00
|
|
|
|
<xref linkend="opt-services.discourse.database.host" />,
|
|
|
|
|
<xref linkend="opt-services.discourse.database.username" /> and
|
|
|
|
|
<xref linkend="opt-services.discourse.database.passwordFile" /> as
|
|
|
|
|
appropriate. Note that you need to manually create a database
|
2023-01-03 06:54:04 +01:00
|
|
|
|
called <literal>discourse</literal> (or the name you chose in
|
2023-01-05 06:16:46 +01:00
|
|
|
|
<xref linkend="opt-services.discourse.database.name" />) and allow
|
|
|
|
|
the configured database user full access to it.
|
2023-01-03 06:54:04 +01:00
|
|
|
|
</para>
|
|
|
|
|
</section>
|
|
|
|
|
<section xml:id="module-services-discourse-mail">
|
|
|
|
|
<title>Email</title>
|
|
|
|
|
<para>
|
2023-01-04 06:56:24 +01:00
|
|
|
|
In addition to the basic setup, you’ll want to configure an SMTP
|
2023-01-03 06:54:04 +01:00
|
|
|
|
server Discourse can use to send user registration and password
|
|
|
|
|
reset emails, among others. You can also optionally let Discourse
|
|
|
|
|
receive email, which enables people to reply to threads and
|
|
|
|
|
conversations via email.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
A basic setup which assumes you want to use your configured
|
|
|
|
|
<link linkend="opt-services.discourse.hostname">hostname</link> as
|
|
|
|
|
email domain can be done like this:
|
|
|
|
|
</para>
|
|
|
|
|
<programlisting>
|
2021-03-15 16:55:05 +01:00
|
|
|
|
services.discourse = {
|
2023-01-02 22:57:19 +01:00
|
|
|
|
enable = true;
|
2023-01-03 06:54:04 +01:00
|
|
|
|
hostname = "discourse.example.com";
|
|
|
|
|
sslCertificate = "/path/to/ssl_certificate";
|
|
|
|
|
sslCertificateKey = "/path/to/ssl_certificate_key";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
admin = {
|
2023-01-03 06:54:04 +01:00
|
|
|
|
email = "admin@example.com";
|
|
|
|
|
username = "admin";
|
|
|
|
|
fullName = "Administrator";
|
|
|
|
|
passwordFile = "/path/to/password_file";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
};
|
|
|
|
|
mail.outgoing = {
|
2023-01-03 06:54:04 +01:00
|
|
|
|
serverAddress = "smtp.emailprovider.com";
|
2023-01-02 22:57:19 +01:00
|
|
|
|
port = 587;
|
2023-01-03 06:54:04 +01:00
|
|
|
|
username = "user@emailprovider.com";
|
|
|
|
|
passwordFile = "/path/to/smtp_password_file";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
};
|
2023-01-02 22:57:19 +01:00
|
|
|
|
mail.incoming.enable = true;
|
2023-01-03 06:54:04 +01:00
|
|
|
|
secretKeyBaseFile = "/path/to/secret_key_base_file";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
};
|
|
|
|
|
</programlisting>
|
2023-01-03 06:54:04 +01:00
|
|
|
|
<para>
|
2023-01-04 06:56:24 +01:00
|
|
|
|
This assumes you have set up an MX record for the address you’ve
|
2023-01-03 06:54:04 +01:00
|
|
|
|
set in
|
|
|
|
|
<link linkend="opt-services.discourse.hostname">hostname</link>
|
|
|
|
|
and requires proper SPF, DKIM and DMARC configuration to be done
|
2023-01-04 06:56:24 +01:00
|
|
|
|
for the domain you’re sending from, in order for email to be
|
2023-01-03 06:54:04 +01:00
|
|
|
|
reliably delivered.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
If you want to use a different domain for your outgoing email (for
|
|
|
|
|
example <literal>example.com</literal> instead of
|
|
|
|
|
<literal>discourse.example.com</literal>) you should set
|
2023-01-05 06:16:46 +01:00
|
|
|
|
<xref linkend="opt-services.discourse.mail.notificationEmailAddress" />
|
2023-01-03 06:54:04 +01:00
|
|
|
|
and
|
2023-01-05 06:16:46 +01:00
|
|
|
|
<xref linkend="opt-services.discourse.mail.contactEmailAddress" />
|
2023-01-03 06:54:04 +01:00
|
|
|
|
manually.
|
|
|
|
|
</para>
|
|
|
|
|
<note>
|
|
|
|
|
<para>
|
|
|
|
|
Setup of TLS for incoming email is currently only configured
|
2023-01-05 06:16:46 +01:00
|
|
|
|
automatically when a regular TLS certificate is used, i.e. when
|
|
|
|
|
<xref linkend="opt-services.discourse.sslCertificate" /> and
|
|
|
|
|
<xref linkend="opt-services.discourse.sslCertificateKey" /> are
|
|
|
|
|
set.
|
2023-01-03 06:54:04 +01:00
|
|
|
|
</para>
|
|
|
|
|
</note>
|
|
|
|
|
</section>
|
|
|
|
|
<section xml:id="module-services-discourse-settings">
|
|
|
|
|
<title>Additional settings</title>
|
|
|
|
|
<para>
|
|
|
|
|
Additional site settings and backend settings, for which no
|
|
|
|
|
explicit NixOS options are provided, can be set in
|
2023-01-05 06:16:46 +01:00
|
|
|
|
<xref linkend="opt-services.discourse.siteSettings" /> and
|
|
|
|
|
<xref linkend="opt-services.discourse.backendSettings" />
|
2023-01-03 06:54:04 +01:00
|
|
|
|
respectively.
|
|
|
|
|
</para>
|
|
|
|
|
<section xml:id="module-services-discourse-site-settings">
|
|
|
|
|
<title>Site settings</title>
|
|
|
|
|
<para>
|
2023-01-04 06:56:24 +01:00
|
|
|
|
<quote>Site settings</quote> are the settings that can be
|
|
|
|
|
changed through the Discourse UI. Their
|
|
|
|
|
<emphasis>default</emphasis> values can be set using
|
2023-01-05 06:16:46 +01:00
|
|
|
|
<xref linkend="opt-services.discourse.siteSettings" />.
|
2023-01-03 06:54:04 +01:00
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
Settings are expressed as a Nix attribute set which matches the
|
|
|
|
|
structure of the configuration in
|
|
|
|
|
<link xlink:href="https://github.com/discourse/discourse/blob/master/config/site_settings.yml">config/site_settings.yml</link>.
|
2023-01-04 06:56:24 +01:00
|
|
|
|
To find a setting’s path, you only need to care about the first
|
2023-01-05 06:16:46 +01:00
|
|
|
|
two levels; i.e. its category (e.g. <literal>login</literal>)
|
|
|
|
|
and name (e.g. <literal>invite_only</literal>).
|
2023-01-03 06:54:04 +01:00
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
Settings containing secret data should be set to an attribute
|
|
|
|
|
set containing the attribute <literal>_secret</literal> - a
|
|
|
|
|
string pointing to a file containing the value the option should
|
|
|
|
|
be set to. See the example.
|
|
|
|
|
</para>
|
|
|
|
|
</section>
|
|
|
|
|
<section xml:id="module-services-discourse-backend-settings">
|
|
|
|
|
<title>Backend settings</title>
|
|
|
|
|
<para>
|
|
|
|
|
Settings are expressed as a Nix attribute set which matches the
|
|
|
|
|
structure of the configuration in
|
|
|
|
|
<link xlink:href="https://github.com/discourse/discourse/blob/stable/config/discourse_defaults.conf">config/discourse.conf</link>.
|
|
|
|
|
Empty parameters can be defined by setting them to
|
|
|
|
|
<literal>null</literal>.
|
|
|
|
|
</para>
|
|
|
|
|
</section>
|
|
|
|
|
<section xml:id="module-services-discourse-settings-example">
|
|
|
|
|
<title>Example</title>
|
|
|
|
|
<para>
|
|
|
|
|
The following example sets the title and description of the
|
|
|
|
|
Discourse instance and enables GitHub login in the site
|
|
|
|
|
settings, and changes a few request limits in the backend
|
|
|
|
|
settings:
|
|
|
|
|
</para>
|
|
|
|
|
<programlisting>
|
2021-03-15 16:55:05 +01:00
|
|
|
|
services.discourse = {
|
2023-01-02 22:57:19 +01:00
|
|
|
|
enable = true;
|
2023-01-03 06:54:04 +01:00
|
|
|
|
hostname = "discourse.example.com";
|
|
|
|
|
sslCertificate = "/path/to/ssl_certificate";
|
|
|
|
|
sslCertificateKey = "/path/to/ssl_certificate_key";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
admin = {
|
2023-01-03 06:54:04 +01:00
|
|
|
|
email = "admin@example.com";
|
|
|
|
|
username = "admin";
|
|
|
|
|
fullName = "Administrator";
|
|
|
|
|
passwordFile = "/path/to/password_file";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
};
|
|
|
|
|
mail.outgoing = {
|
2023-01-03 06:54:04 +01:00
|
|
|
|
serverAddress = "smtp.emailprovider.com";
|
2023-01-02 22:57:19 +01:00
|
|
|
|
port = 587;
|
2023-01-03 06:54:04 +01:00
|
|
|
|
username = "user@emailprovider.com";
|
|
|
|
|
passwordFile = "/path/to/smtp_password_file";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
};
|
2023-01-02 22:57:19 +01:00
|
|
|
|
mail.incoming.enable = true;
|
|
|
|
|
siteSettings = {
|
2021-03-15 16:55:05 +01:00
|
|
|
|
required = {
|
2023-01-03 06:54:04 +01:00
|
|
|
|
title = "My Cats";
|
|
|
|
|
site_description = "Discuss My Cats (and be nice plz)";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
};
|
|
|
|
|
login = {
|
|
|
|
|
enable_github_logins = true;
|
2023-01-03 06:54:04 +01:00
|
|
|
|
github_client_id = "a2f6dfe838cb3206ce20";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
github_client_secret._secret = /run/keys/discourse_github_client_secret;
|
|
|
|
|
};
|
|
|
|
|
};
|
2023-01-02 22:57:19 +01:00
|
|
|
|
backendSettings = {
|
2021-03-15 16:55:05 +01:00
|
|
|
|
max_reqs_per_ip_per_minute = 300;
|
|
|
|
|
max_reqs_per_ip_per_10_seconds = 60;
|
|
|
|
|
max_asset_reqs_per_ip_per_10_seconds = 250;
|
2023-01-03 06:54:04 +01:00
|
|
|
|
max_reqs_per_ip_mode = "warn+block";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
};
|
2023-01-03 06:54:04 +01:00
|
|
|
|
secretKeyBaseFile = "/path/to/secret_key_base_file";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
};
|
|
|
|
|
</programlisting>
|
2023-01-03 06:54:04 +01:00
|
|
|
|
<para>
|
|
|
|
|
In the resulting site settings file, the
|
|
|
|
|
<literal>login.github_client_secret</literal> key will be set to
|
|
|
|
|
the contents of the
|
|
|
|
|
<filename>/run/keys/discourse_github_client_secret</filename>
|
|
|
|
|
file.
|
|
|
|
|
</para>
|
|
|
|
|
</section>
|
|
|
|
|
</section>
|
2021-03-15 16:55:05 +01:00
|
|
|
|
<section xml:id="module-services-discourse-plugins">
|
|
|
|
|
<title>Plugins</title>
|
|
|
|
|
<para>
|
2023-01-03 06:54:04 +01:00
|
|
|
|
You can install Discourse plugins using the
|
2023-01-05 06:16:46 +01:00
|
|
|
|
<xref linkend="opt-services.discourse.plugins" /> option.
|
2023-01-03 06:54:04 +01:00
|
|
|
|
Pre-packaged plugins are provided in
|
2021-07-06 18:37:00 +02:00
|
|
|
|
<literal><your_discourse_package_here>.plugins</literal>. If
|
|
|
|
|
you want the full suite of plugins provided through
|
2023-01-03 06:54:04 +01:00
|
|
|
|
<literal>nixpkgs</literal>, you can also set the
|
2023-01-05 06:16:46 +01:00
|
|
|
|
<xref linkend="opt-services.discourse.package" /> option to
|
2021-07-06 18:37:00 +02:00
|
|
|
|
<literal>pkgs.discourseAllPlugins</literal>.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
Plugins can be built with the
|
|
|
|
|
<literal><your_discourse_package_here>.mkDiscoursePlugin</literal>
|
|
|
|
|
function. Normally, it should suffice to provide a
|
|
|
|
|
<literal>name</literal> and <literal>src</literal> attribute. If
|
|
|
|
|
the plugin has Ruby dependencies, however, they need to be
|
2023-01-03 06:54:04 +01:00
|
|
|
|
packaged in accordance with the
|
|
|
|
|
<link xlink:href="https://nixos.org/manual/nixpkgs/stable/#developing-with-ruby">Developing
|
|
|
|
|
with Ruby</link> section of the Nixpkgs manual and the appropriate
|
|
|
|
|
gem options set in <literal>bundlerEnvArgs</literal> (normally
|
2023-01-04 06:56:24 +01:00
|
|
|
|
<literal>gemdir</literal> is sufficient). A plugin’s Ruby
|
2023-01-03 06:54:04 +01:00
|
|
|
|
dependencies are listed in its <filename>plugin.rb</filename> file
|
|
|
|
|
as function calls to <literal>gem</literal>. To construct the
|
|
|
|
|
corresponding <filename>Gemfile</filename> manually, run
|
|
|
|
|
<command>bundle init</command>, then add the
|
|
|
|
|
<literal>gem</literal> lines to it verbatim.
|
2021-03-15 16:55:05 +01:00
|
|
|
|
</para>
|
2021-08-13 18:42:56 +02:00
|
|
|
|
<para>
|
|
|
|
|
Much of the packaging can be done automatically by the
|
|
|
|
|
<filename>nixpkgs/pkgs/servers/web-apps/discourse/update.py</filename>
|
|
|
|
|
script - just add the plugin to the <literal>plugins</literal>
|
2023-01-03 06:54:04 +01:00
|
|
|
|
list in the <literal>update_plugins</literal> function and run the
|
|
|
|
|
script:
|
|
|
|
|
</para>
|
|
|
|
|
<programlisting language="bash">
|
2021-08-13 18:42:56 +02:00
|
|
|
|
./update.py update-plugins
|
2021-11-26 14:59:09 +01:00
|
|
|
|
</programlisting>
|
2021-03-15 16:55:05 +01:00
|
|
|
|
<para>
|
2023-01-03 06:54:04 +01:00
|
|
|
|
Some plugins provide
|
|
|
|
|
<link linkend="module-services-discourse-site-settings">site
|
|
|
|
|
settings</link>. Their defaults can be configured using
|
2023-01-05 06:16:46 +01:00
|
|
|
|
<xref linkend="opt-services.discourse.siteSettings" />, just like
|
|
|
|
|
regular site settings. To find the names of these settings, look
|
|
|
|
|
in the <literal>config/settings.yml</literal> file of the plugin
|
|
|
|
|
repo.
|
2021-03-15 16:55:05 +01:00
|
|
|
|
</para>
|
|
|
|
|
<para>
|
2023-01-03 06:54:04 +01:00
|
|
|
|
For example, to add the
|
|
|
|
|
<link xlink:href="https://github.com/discourse/discourse-spoiler-alert">discourse-spoiler-alert</link>
|
|
|
|
|
and
|
|
|
|
|
<link xlink:href="https://github.com/discourse/discourse-solved">discourse-solved</link>
|
|
|
|
|
plugins, and disable <literal>discourse-spoiler-alert</literal> by
|
|
|
|
|
default:
|
|
|
|
|
</para>
|
|
|
|
|
<programlisting>
|
2021-03-15 16:55:05 +01:00
|
|
|
|
services.discourse = {
|
2023-01-02 22:57:19 +01:00
|
|
|
|
enable = true;
|
2023-01-03 06:54:04 +01:00
|
|
|
|
hostname = "discourse.example.com";
|
|
|
|
|
sslCertificate = "/path/to/ssl_certificate";
|
|
|
|
|
sslCertificateKey = "/path/to/ssl_certificate_key";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
admin = {
|
2023-01-03 06:54:04 +01:00
|
|
|
|
email = "admin@example.com";
|
|
|
|
|
username = "admin";
|
|
|
|
|
fullName = "Administrator";
|
|
|
|
|
passwordFile = "/path/to/password_file";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
};
|
|
|
|
|
mail.outgoing = {
|
2023-01-03 06:54:04 +01:00
|
|
|
|
serverAddress = "smtp.emailprovider.com";
|
2023-01-02 22:57:19 +01:00
|
|
|
|
port = 587;
|
2023-01-03 06:54:04 +01:00
|
|
|
|
username = "user@emailprovider.com";
|
|
|
|
|
passwordFile = "/path/to/smtp_password_file";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
};
|
2023-01-02 22:57:19 +01:00
|
|
|
|
mail.incoming.enable = true;
|
|
|
|
|
plugins = with config.services.discourse.package.plugins; [
|
2021-07-06 18:37:00 +02:00
|
|
|
|
discourse-spoiler-alert
|
|
|
|
|
discourse-solved
|
2021-03-15 16:55:05 +01:00
|
|
|
|
];
|
2023-01-02 22:57:19 +01:00
|
|
|
|
siteSettings = {
|
2021-03-15 16:55:05 +01:00
|
|
|
|
plugins = {
|
|
|
|
|
spoiler_enabled = false;
|
|
|
|
|
};
|
|
|
|
|
};
|
2023-01-03 06:54:04 +01:00
|
|
|
|
secretKeyBaseFile = "/path/to/secret_key_base_file";
|
2021-03-15 16:55:05 +01:00
|
|
|
|
};
|
|
|
|
|
</programlisting>
|
|
|
|
|
</section>
|
|
|
|
|
</chapter>
|