lol

nixos/discourse: convert manual chapter to MD

pennae 7318430f e4897cdf

+530 -265
+286
nixos/modules/services/web-apps/discourse.md
··· 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 + ```
+2
nixos/modules/services/web-apps/discourse.nix
··· 1080 1080 ]; 1081 1081 }; 1082 1082 1083 + # Don't edit the docbook xml directly, edit the md and generate it: 1084 + # `pandoc discourse.md -t docbook --top-level-division=chapter --extract-media=media -f markdown-smart --lua-filter ../../../../doc/build-aux/pandoc-filters/myst-reader/roles.lua --lua-filter ../../../../doc/build-aux/pandoc-filters/docbook-writer/rst-roles.lua > discourse.xml` 1083 1085 meta.doc = ./discourse.xml; 1084 1086 meta.maintainers = [ lib.maintainers.talyz ]; 1085 1087 }
+242 -265
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> 1 + <chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-discourse"> 2 + <title>Discourse</title> 3 + <para> 4 + <link xlink:href="https://www.discourse.org/">Discourse</link> is a 5 + modern and open source discussion platform. 6 + </para> 7 + <section xml:id="module-services-discourse-basic-usage"> 8 + <title>Basic usage</title> 9 + <para> 10 + A minimal configuration using Let's Encrypt for TLS certificates 11 + looks like this: 12 + </para> 13 + <programlisting> 17 14 services.discourse = { 18 15 enable = true; 19 - hostname = "discourse.example.com"; 16 + hostname = &quot;discourse.example.com&quot;; 20 17 admin = { 21 - email = "admin@example.com"; 22 - username = "admin"; 23 - fullName = "Administrator"; 24 - passwordFile = "/path/to/password_file"; 18 + email = &quot;admin@example.com&quot;; 19 + username = &quot;admin&quot;; 20 + fullName = &quot;Administrator&quot;; 21 + passwordFile = &quot;/path/to/password_file&quot;; 25 22 }; 26 - secretKeyBaseFile = "/path/to/secret_key_base_file"; 23 + secretKeyBaseFile = &quot;/path/to/secret_key_base_file&quot;; 27 24 }; 28 - security.acme.email = "me@example.com"; 25 + security.acme.email = &quot;me@example.com&quot;; 29 26 security.acme.acceptTerms = true; 30 27 </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> 28 + <para> 29 + Provided a proper DNS setup, you'll be able to connect to the 30 + instance at <literal>discourse.example.com</literal> and log in 31 + using the credentials provided in 32 + <literal>services.discourse.admin</literal>. 33 + </para> 34 + </section> 35 + <section xml:id="module-services-discourse-tls"> 36 + <title>Using a regular TLS certificate</title> 37 + <para> 38 + To set up TLS using a regular certificate and key on file, use the 39 + <xref linkend="opt-services.discourse.sslCertificate"></xref> and 40 + <xref linkend="opt-services.discourse.sslCertificateKey"></xref> 41 + options: 42 + </para> 43 + <programlisting> 50 44 services.discourse = { 51 45 enable = true; 52 - hostname = "discourse.example.com"; 53 - sslCertificate = "/path/to/ssl_certificate"; 54 - sslCertificateKey = "/path/to/ssl_certificate_key"; 46 + hostname = &quot;discourse.example.com&quot;; 47 + sslCertificate = &quot;/path/to/ssl_certificate&quot;; 48 + sslCertificateKey = &quot;/path/to/ssl_certificate_key&quot;; 55 49 admin = { 56 - email = "admin@example.com"; 57 - username = "admin"; 58 - fullName = "Administrator"; 59 - passwordFile = "/path/to/password_file"; 50 + email = &quot;admin@example.com&quot;; 51 + username = &quot;admin&quot;; 52 + fullName = &quot;Administrator&quot;; 53 + passwordFile = &quot;/path/to/password_file&quot;; 60 54 }; 61 - secretKeyBaseFile = "/path/to/secret_key_base_file"; 55 + secretKeyBaseFile = &quot;/path/to/secret_key_base_file&quot;; 62 56 }; 63 57 </programlisting> 64 - 65 - </para> 66 - </section> 67 - 68 - <section xml:id="module-services-discourse-database"> 69 - <title>Database access</title> 70 - <para> 71 - Discourse uses 72 - PostgreSQL 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 Discourse can use to send user 98 - registration and password reset emails, among others. You can 99 - also optionally let Discourse 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> 58 + </section> 59 + <section xml:id="module-services-discourse-database"> 60 + <title>Database access</title> 61 + <para> 62 + Discourse uses PostgreSQL to store most of its data. A database 63 + will automatically be enabled and a database and role created 64 + unless 65 + <xref linkend="opt-services.discourse.database.host"></xref> is 66 + changed from its default of <literal>null</literal> or 67 + <xref linkend="opt-services.discourse.database.createLocally"></xref> 68 + is set to <literal>false</literal>. 69 + </para> 70 + <para> 71 + External database access can also be configured by setting 72 + <xref linkend="opt-services.discourse.database.host"></xref>, 73 + <xref linkend="opt-services.discourse.database.username"></xref> 74 + and 75 + <xref linkend="opt-services.discourse.database.passwordFile"></xref> 76 + as 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"></xref>) and 79 + allow 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> 110 97 services.discourse = { 111 98 enable = true; 112 - hostname = "discourse.example.com"; 113 - sslCertificate = "/path/to/ssl_certificate"; 114 - sslCertificateKey = "/path/to/ssl_certificate_key"; 99 + hostname = &quot;discourse.example.com&quot;; 100 + sslCertificate = &quot;/path/to/ssl_certificate&quot;; 101 + sslCertificateKey = &quot;/path/to/ssl_certificate_key&quot;; 115 102 admin = { 116 - email = "admin@example.com"; 117 - username = "admin"; 118 - fullName = "Administrator"; 119 - passwordFile = "/path/to/password_file"; 103 + email = &quot;admin@example.com&quot;; 104 + username = &quot;admin&quot;; 105 + fullName = &quot;Administrator&quot;; 106 + passwordFile = &quot;/path/to/password_file&quot;; 120 107 }; 121 108 mail.outgoing = { 122 - serverAddress = "smtp.emailprovider.com"; 109 + serverAddress = &quot;smtp.emailprovider.com&quot;; 123 110 port = 587; 124 - username = "user@emailprovider.com"; 125 - passwordFile = "/path/to/smtp_password_file"; 111 + username = &quot;user@emailprovider.com&quot;; 112 + passwordFile = &quot;/path/to/smtp_password_file&quot;; 126 113 }; 127 114 mail.incoming.enable = true; 128 - secretKeyBaseFile = "/path/to/secret_key_base_file"; 115 + secretKeyBaseFile = &quot;/path/to/secret_key_base_file&quot;; 129 116 }; 130 117 </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 NixOS 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 - "Site settings" are the settings that can be 171 - changed through the Discourse 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 - Discourse instance and enables 209 - GitHub login in the site settings, 210 - and changes a few request limits in the backend settings: 211 - <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"></xref> 131 + and 132 + <xref linkend="opt-services.discourse.mail.contactEmailAddress"></xref> 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"></xref> 140 + and 141 + <xref linkend="opt-services.discourse.sslCertificateKey"></xref> 142 + are set. 143 + </para> 144 + </note> 145 + </section> 146 + <section xml:id="module-services-discourse-settings"> 147 + <title>Additional settings</title> 148 + <para> 149 + Additional site settings and backend settings, for which no 150 + explicit NixOS options are provided, can be set in 151 + <xref linkend="opt-services.discourse.siteSettings"></xref> and 152 + <xref linkend="opt-services.discourse.backendSettings"></xref> 153 + respectively. 154 + </para> 155 + <section xml:id="module-services-discourse-site-settings"> 156 + <title>Site settings</title> 157 + <para> 158 + &quot;Site settings&quot; are the settings that can be changed 159 + through the Discourse UI. Their <emphasis>default</emphasis> 160 + values can be set using 161 + <xref linkend="opt-services.discourse.siteSettings"></xref>. 162 + </para> 163 + <para> 164 + Settings are expressed as a Nix attribute set which matches the 165 + structure of the configuration in 166 + <link xlink:href="https://github.com/discourse/discourse/blob/master/config/site_settings.yml">config/site_settings.yml</link>. 167 + To find a setting's path, you only need to care about the first 168 + two levels; i.e. its category (e.g. <literal>login</literal>) 169 + and name (e.g. <literal>invite_only</literal>). 170 + </para> 171 + <para> 172 + Settings containing secret data should be set to an attribute 173 + set containing the attribute <literal>_secret</literal> - a 174 + string pointing to a file containing the value the option should 175 + be set to. See the example. 176 + </para> 177 + </section> 178 + <section xml:id="module-services-discourse-backend-settings"> 179 + <title>Backend settings</title> 180 + <para> 181 + Settings are expressed as a Nix attribute set which matches the 182 + structure of the configuration in 183 + <link xlink:href="https://github.com/discourse/discourse/blob/stable/config/discourse_defaults.conf">config/discourse.conf</link>. 184 + Empty parameters can be defined by setting them to 185 + <literal>null</literal>. 186 + </para> 187 + </section> 188 + <section xml:id="module-services-discourse-settings-example"> 189 + <title>Example</title> 190 + <para> 191 + The following example sets the title and description of the 192 + Discourse instance and enables GitHub login in the site 193 + settings, and changes a few request limits in the backend 194 + settings: 195 + </para> 196 + <programlisting> 212 197 services.discourse = { 213 198 enable = true; 214 - hostname = "discourse.example.com"; 215 - sslCertificate = "/path/to/ssl_certificate"; 216 - sslCertificateKey = "/path/to/ssl_certificate_key"; 199 + hostname = &quot;discourse.example.com&quot;; 200 + sslCertificate = &quot;/path/to/ssl_certificate&quot;; 201 + sslCertificateKey = &quot;/path/to/ssl_certificate_key&quot;; 217 202 admin = { 218 - email = "admin@example.com"; 219 - username = "admin"; 220 - fullName = "Administrator"; 221 - passwordFile = "/path/to/password_file"; 203 + email = &quot;admin@example.com&quot;; 204 + username = &quot;admin&quot;; 205 + fullName = &quot;Administrator&quot;; 206 + passwordFile = &quot;/path/to/password_file&quot;; 222 207 }; 223 208 mail.outgoing = { 224 - serverAddress = "smtp.emailprovider.com"; 209 + serverAddress = &quot;smtp.emailprovider.com&quot;; 225 210 port = 587; 226 - username = "user@emailprovider.com"; 227 - passwordFile = "/path/to/smtp_password_file"; 211 + username = &quot;user@emailprovider.com&quot;; 212 + passwordFile = &quot;/path/to/smtp_password_file&quot;; 228 213 }; 229 214 mail.incoming.enable = true; 230 215 siteSettings = { 231 216 required = { 232 - title = "My Cats"; 233 - site_description = "Discuss My Cats (and be nice plz)"; 217 + title = &quot;My Cats&quot;; 218 + site_description = &quot;Discuss My Cats (and be nice plz)&quot;; 234 219 }; 235 220 login = { 236 221 enable_github_logins = true; 237 - github_client_id = "a2f6dfe838cb3206ce20"; 222 + github_client_id = &quot;a2f6dfe838cb3206ce20&quot;; 238 223 github_client_secret._secret = /run/keys/discourse_github_client_secret; 239 224 }; 240 225 }; ··· 242 227 max_reqs_per_ip_per_minute = 300; 243 228 max_reqs_per_ip_per_10_seconds = 60; 244 229 max_asset_reqs_per_ip_per_10_seconds = 250; 245 - max_reqs_per_ip_mode = "warn+block"; 230 + max_reqs_per_ip_mode = &quot;warn+block&quot;; 246 231 }; 247 - secretKeyBaseFile = "/path/to/secret_key_base_file"; 232 + secretKeyBaseFile = &quot;/path/to/secret_key_base_file&quot;; 248 233 }; 249 234 </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> 235 + <para> 236 + In the resulting site settings file, the 237 + <literal>login.github_client_secret</literal> key will be set to 238 + the contents of the 239 + <filename>/run/keys/discourse_github_client_secret</filename> 240 + file. 241 + </para> 242 + </section> 243 + </section> 260 244 <section xml:id="module-services-discourse-plugins"> 261 245 <title>Plugins</title> 262 246 <para> 263 - You can install Discourse plugins 264 - using the <xref linkend="opt-services.discourse.plugins" /> 265 - option. Pre-packaged plugins are provided in 247 + You can install Discourse plugins using the 248 + <xref linkend="opt-services.discourse.plugins"></xref> option. 249 + Pre-packaged plugins are provided in 266 250 <literal>&lt;your_discourse_package_here&gt;.plugins</literal>. If 267 251 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 252 + <literal>nixpkgs</literal>, you can also set the 253 + <xref linkend="opt-services.discourse.package"></xref> option to 270 254 <literal>pkgs.discourseAllPlugins</literal>. 271 255 </para> 272 - 273 256 <para> 274 257 Plugins can be built with the 275 258 <literal>&lt;your_discourse_package_here&gt;.mkDiscoursePlugin</literal> 276 259 function. Normally, it should suffice to provide a 277 260 <literal>name</literal> and <literal>src</literal> attribute. If 278 261 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. 262 + packaged in accordance with the 263 + <link xlink:href="https://nixos.org/manual/nixpkgs/stable/#developing-with-ruby">Developing 264 + with Ruby</link> section of the Nixpkgs manual and the appropriate 265 + gem options set in <literal>bundlerEnvArgs</literal> (normally 266 + <literal>gemdir</literal> is sufficient). A plugin's Ruby 267 + dependencies are listed in its <filename>plugin.rb</filename> file 268 + as function calls to <literal>gem</literal>. To construct the 269 + corresponding <filename>Gemfile</filename> manually, run 270 + <command>bundle init</command>, then add the 271 + <literal>gem</literal> lines to it verbatim. 290 272 </para> 291 - 292 273 <para> 293 274 Much of the packaging can be done automatically by the 294 275 <filename>nixpkgs/pkgs/servers/web-apps/discourse/update.py</filename> 295 276 script - just add the plugin to the <literal>plugins</literal> 296 - list in the <literal>update_plugins</literal> function and run 297 - the script: 298 - <programlisting language="bash"> 277 + list in the <literal>update_plugins</literal> function and run the 278 + script: 279 + </para> 280 + <programlisting language="bash"> 299 281 ./update.py update-plugins 300 282 </programlisting> 301 - </para> 302 - 303 283 <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. 284 + Some plugins provide 285 + <link linkend="module-services-discourse-site-settings">site 286 + settings</link>. Their defaults can be configured using 287 + <xref linkend="opt-services.discourse.siteSettings"></xref>, just 288 + like regular site settings. To find the names of these settings, 289 + look in the <literal>config/settings.yml</literal> file of the 290 + plugin repo. 311 291 </para> 312 - 313 292 <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> 293 + For example, to add the 294 + <link xlink:href="https://github.com/discourse/discourse-spoiler-alert">discourse-spoiler-alert</link> 295 + and 296 + <link xlink:href="https://github.com/discourse/discourse-solved">discourse-solved</link> 297 + plugins, and disable <literal>discourse-spoiler-alert</literal> by 298 + default: 299 + </para> 300 + <programlisting> 322 301 services.discourse = { 323 302 enable = true; 324 - hostname = "discourse.example.com"; 325 - sslCertificate = "/path/to/ssl_certificate"; 326 - sslCertificateKey = "/path/to/ssl_certificate_key"; 303 + hostname = &quot;discourse.example.com&quot;; 304 + sslCertificate = &quot;/path/to/ssl_certificate&quot;; 305 + sslCertificateKey = &quot;/path/to/ssl_certificate_key&quot;; 327 306 admin = { 328 - email = "admin@example.com"; 329 - username = "admin"; 330 - fullName = "Administrator"; 331 - passwordFile = "/path/to/password_file"; 307 + email = &quot;admin@example.com&quot;; 308 + username = &quot;admin&quot;; 309 + fullName = &quot;Administrator&quot;; 310 + passwordFile = &quot;/path/to/password_file&quot;; 332 311 }; 333 312 mail.outgoing = { 334 - serverAddress = "smtp.emailprovider.com"; 313 + serverAddress = &quot;smtp.emailprovider.com&quot;; 335 314 port = 587; 336 - username = "user@emailprovider.com"; 337 - passwordFile = "/path/to/smtp_password_file"; 315 + username = &quot;user@emailprovider.com&quot;; 316 + passwordFile = &quot;/path/to/smtp_password_file&quot;; 338 317 }; 339 318 mail.incoming.enable = true; 340 319 plugins = with config.services.discourse.package.plugins; [ ··· 346 325 spoiler_enabled = false; 347 326 }; 348 327 }; 349 - secretKeyBaseFile = "/path/to/secret_key_base_file"; 328 + secretKeyBaseFile = &quot;/path/to/secret_key_base_file&quot;; 350 329 }; 351 330 </programlisting> 352 - 353 - </para> 354 331 </section> 355 332 </chapter>