From 7318430f928fe014902374e9b41970331fd5922f Mon Sep 17 00:00:00 2001 From: pennae Date: Tue, 3 Jan 2023 06:54:04 +0100 Subject: nixos/discourse: convert manual chapter to MD --- nixos/modules/services/web-apps/discourse.md | 286 +++++++++++++++ nixos/modules/services/web-apps/discourse.nix | 2 + nixos/modules/services/web-apps/discourse.xml | 507 ++++++++++++-------------- 3 files changed, 530 insertions(+), 265 deletions(-) create mode 100644 nixos/modules/services/web-apps/discourse.md (limited to 'nixos') diff --git a/nixos/modules/services/web-apps/discourse.md b/nixos/modules/services/web-apps/discourse.md new file mode 100644 index 00000000000..35180bea87d --- /dev/null +++ b/nixos/modules/services/web-apps/discourse.md @@ -0,0 +1,286 @@ +# Discourse {#module-services-discourse} + +[Discourse](https://www.discourse.org/) is a +modern and open source discussion platform. + +## Basic usage {#module-services-discourse-basic-usage} + +A minimal configuration using Let's Encrypt for TLS certificates looks like this: +``` +services.discourse = { + enable = true; + hostname = "discourse.example.com"; + admin = { + email = "admin@example.com"; + username = "admin"; + fullName = "Administrator"; + passwordFile = "/path/to/password_file"; + }; + secretKeyBaseFile = "/path/to/secret_key_base_file"; +}; +security.acme.email = "me@example.com"; +security.acme.acceptTerms = true; +``` + +Provided a proper DNS setup, you'll be able to connect to the +instance at `discourse.example.com` and log in +using the credentials provided in +`services.discourse.admin`. + +## Using a regular TLS certificate {#module-services-discourse-tls} + +To set up TLS using a regular certificate and key on file, use +the [](#opt-services.discourse.sslCertificate) +and [](#opt-services.discourse.sslCertificateKey) +options: + +``` +services.discourse = { + enable = true; + hostname = "discourse.example.com"; + sslCertificate = "/path/to/ssl_certificate"; + sslCertificateKey = "/path/to/ssl_certificate_key"; + admin = { + email = "admin@example.com"; + username = "admin"; + fullName = "Administrator"; + passwordFile = "/path/to/password_file"; + }; + secretKeyBaseFile = "/path/to/secret_key_base_file"; +}; +``` + +## Database access {#module-services-discourse-database} + +Discourse uses PostgreSQL to store most of its +data. A database will automatically be enabled and a database +and role created unless [](#opt-services.discourse.database.host) is changed from +its default of `null` or [](#opt-services.discourse.database.createLocally) is set +to `false`. + +External database access can also be configured by setting +[](#opt-services.discourse.database.host), +[](#opt-services.discourse.database.username) and +[](#opt-services.discourse.database.passwordFile) as +appropriate. Note that you need to manually create a database +called `discourse` (or the name you chose in +[](#opt-services.discourse.database.name)) and +allow the configured database user full access to it. + +## Email {#module-services-discourse-mail} + +In addition to the basic setup, you'll want to configure an SMTP +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. + +A basic setup which assumes you want to use your configured +[hostname](#opt-services.discourse.hostname) as +email domain can be done like this: + +``` +services.discourse = { + enable = true; + hostname = "discourse.example.com"; + sslCertificate = "/path/to/ssl_certificate"; + sslCertificateKey = "/path/to/ssl_certificate_key"; + admin = { + email = "admin@example.com"; + username = "admin"; + fullName = "Administrator"; + passwordFile = "/path/to/password_file"; + }; + mail.outgoing = { + serverAddress = "smtp.emailprovider.com"; + port = 587; + username = "user@emailprovider.com"; + passwordFile = "/path/to/smtp_password_file"; + }; + mail.incoming.enable = true; + secretKeyBaseFile = "/path/to/secret_key_base_file"; +}; +``` + +This assumes you have set up an MX record for the address you've +set in [hostname](#opt-services.discourse.hostname) and +requires proper SPF, DKIM and DMARC configuration to be done for +the domain you're sending from, in order for email to be reliably delivered. + +If you want to use a different domain for your outgoing email +(for example `example.com` instead of +`discourse.example.com`) you should set +[](#opt-services.discourse.mail.notificationEmailAddress) and +[](#opt-services.discourse.mail.contactEmailAddress) manually. + +::: {.note} +Setup of TLS for incoming email is currently only configured +automatically when a regular TLS certificate is used, i.e. when +[](#opt-services.discourse.sslCertificate) and +[](#opt-services.discourse.sslCertificateKey) are +set. +::: + +## Additional settings {#module-services-discourse-settings} + +Additional site settings and backend settings, for which no +explicit NixOS options are provided, +can be set in [](#opt-services.discourse.siteSettings) and +[](#opt-services.discourse.backendSettings) respectively. + +### Site settings {#module-services-discourse-site-settings} + +"Site settings" are the settings that can be +changed through the Discourse +UI. Their *default* values can be set using +[](#opt-services.discourse.siteSettings). + +Settings are expressed as a Nix attribute set which matches the +structure of the configuration in +[config/site_settings.yml](https://github.com/discourse/discourse/blob/master/config/site_settings.yml). +To find a setting's path, you only need to care about the first +two levels; i.e. its category (e.g. `login`) +and name (e.g. `invite_only`). + +Settings containing secret data should be set to an attribute +set containing the attribute `_secret` - a +string pointing to a file containing the value the option +should be set to. See the example. + +### Backend settings {#module-services-discourse-backend-settings} + +Settings are expressed as a Nix attribute set which matches the +structure of the configuration in +[config/discourse.conf](https://github.com/discourse/discourse/blob/stable/config/discourse_defaults.conf). +Empty parameters can be defined by setting them to +`null`. + +### Example {#module-services-discourse-settings-example} + +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: +``` +services.discourse = { + enable = true; + hostname = "discourse.example.com"; + sslCertificate = "/path/to/ssl_certificate"; + sslCertificateKey = "/path/to/ssl_certificate_key"; + admin = { + email = "admin@example.com"; + username = "admin"; + fullName = "Administrator"; + passwordFile = "/path/to/password_file"; + }; + mail.outgoing = { + serverAddress = "smtp.emailprovider.com"; + port = 587; + username = "user@emailprovider.com"; + passwordFile = "/path/to/smtp_password_file"; + }; + mail.incoming.enable = true; + siteSettings = { + required = { + title = "My Cats"; + site_description = "Discuss My Cats (and be nice plz)"; + }; + login = { + enable_github_logins = true; + github_client_id = "a2f6dfe838cb3206ce20"; + github_client_secret._secret = /run/keys/discourse_github_client_secret; + }; + }; + backendSettings = { + max_reqs_per_ip_per_minute = 300; + max_reqs_per_ip_per_10_seconds = 60; + max_asset_reqs_per_ip_per_10_seconds = 250; + max_reqs_per_ip_mode = "warn+block"; + }; + secretKeyBaseFile = "/path/to/secret_key_base_file"; +}; +``` + +In the resulting site settings file, the +`login.github_client_secret` key will be set +to the contents of the +{file}`/run/keys/discourse_github_client_secret` +file. + +## Plugins {#module-services-discourse-plugins} + +You can install Discourse plugins +using the [](#opt-services.discourse.plugins) +option. Pre-packaged plugins are provided in +`.plugins`. If +you want the full suite of plugins provided through +`nixpkgs`, you can also set the [](#opt-services.discourse.package) option to +`pkgs.discourseAllPlugins`. + +Plugins can be built with the +`.mkDiscoursePlugin` +function. Normally, it should suffice to provide a +`name` and `src` attribute. If +the plugin has Ruby dependencies, however, they need to be +packaged in accordance with the [Developing with Ruby](https://nixos.org/manual/nixpkgs/stable/#developing-with-ruby) +section of the Nixpkgs manual and the +appropriate gem options set in `bundlerEnvArgs` +(normally `gemdir` is sufficient). A plugin's +Ruby dependencies are listed in its +{file}`plugin.rb` file as function calls to +`gem`. To construct the corresponding +{file}`Gemfile` manually, run {command}`bundle init`, then add the `gem` lines to it +verbatim. + +Much of the packaging can be done automatically by the +{file}`nixpkgs/pkgs/servers/web-apps/discourse/update.py` +script - just add the plugin to the `plugins` +list in the `update_plugins` function and run +the script: +```bash +./update.py update-plugins +``` + +Some plugins provide [site settings](#module-services-discourse-site-settings). +Their defaults can be configured using [](#opt-services.discourse.siteSettings), just like +regular site settings. To find the names of these settings, look +in the `config/settings.yml` file of the plugin +repo. + +For example, to add the [discourse-spoiler-alert](https://github.com/discourse/discourse-spoiler-alert) +and [discourse-solved](https://github.com/discourse/discourse-solved) +plugins, and disable `discourse-spoiler-alert` +by default: + +``` +services.discourse = { + enable = true; + hostname = "discourse.example.com"; + sslCertificate = "/path/to/ssl_certificate"; + sslCertificateKey = "/path/to/ssl_certificate_key"; + admin = { + email = "admin@example.com"; + username = "admin"; + fullName = "Administrator"; + passwordFile = "/path/to/password_file"; + }; + mail.outgoing = { + serverAddress = "smtp.emailprovider.com"; + port = 587; + username = "user@emailprovider.com"; + passwordFile = "/path/to/smtp_password_file"; + }; + mail.incoming.enable = true; + plugins = with config.services.discourse.package.plugins; [ + discourse-spoiler-alert + discourse-solved + ]; + siteSettings = { + plugins = { + spoiler_enabled = false; + }; + }; + secretKeyBaseFile = "/path/to/secret_key_base_file"; +}; +``` diff --git a/nixos/modules/services/web-apps/discourse.nix b/nixos/modules/services/web-apps/discourse.nix index b8104ade467..834e0f12340 100644 --- a/nixos/modules/services/web-apps/discourse.nix +++ b/nixos/modules/services/web-apps/discourse.nix @@ -1080,6 +1080,8 @@ in ]; }; + # Don't edit the docbook xml directly, edit the md and generate it: + # `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` meta.doc = ./discourse.xml; meta.maintainers = [ lib.maintainers.talyz ]; } diff --git a/nixos/modules/services/web-apps/discourse.xml b/nixos/modules/services/web-apps/discourse.xml index 628881a9a1c..c33cf7eaf73 100644 --- a/nixos/modules/services/web-apps/discourse.xml +++ b/nixos/modules/services/web-apps/discourse.xml @@ -1,240 +1,225 @@ - - Discourse - - Discourse is a - modern and open source discussion platform. - - -
- Basic usage - - A minimal configuration using Let's Encrypt for TLS certificates looks like this: - + + Discourse + + Discourse is a + modern and open source discussion platform. + +
+ Basic usage + + A minimal configuration using Let's Encrypt for TLS certificates + looks like this: + + services.discourse = { enable = true; - hostname = "discourse.example.com"; + hostname = "discourse.example.com"; admin = { - email = "admin@example.com"; - username = "admin"; - fullName = "Administrator"; - passwordFile = "/path/to/password_file"; + email = "admin@example.com"; + username = "admin"; + fullName = "Administrator"; + passwordFile = "/path/to/password_file"; }; - secretKeyBaseFile = "/path/to/secret_key_base_file"; + secretKeyBaseFile = "/path/to/secret_key_base_file"; }; -security.acme.email = "me@example.com"; +security.acme.email = "me@example.com"; security.acme.acceptTerms = true; - - - - Provided a proper DNS setup, you'll be able to connect to the - instance at discourse.example.com and log in - using the credentials provided in - services.discourse.admin. - -
- -
- Using a regular TLS certificate - - To set up TLS using a regular certificate and key on file, use - the - and - options: - - + + Provided a proper DNS setup, you'll be able to connect to the + instance at discourse.example.com and log in + using the credentials provided in + services.discourse.admin. + +
+
+ Using a regular TLS certificate + + To set up TLS using a regular certificate and key on file, use the + and + + options: + + services.discourse = { enable = true; - hostname = "discourse.example.com"; - sslCertificate = "/path/to/ssl_certificate"; - sslCertificateKey = "/path/to/ssl_certificate_key"; + hostname = "discourse.example.com"; + sslCertificate = "/path/to/ssl_certificate"; + sslCertificateKey = "/path/to/ssl_certificate_key"; admin = { - email = "admin@example.com"; - username = "admin"; - fullName = "Administrator"; - passwordFile = "/path/to/password_file"; + email = "admin@example.com"; + username = "admin"; + fullName = "Administrator"; + passwordFile = "/path/to/password_file"; }; - secretKeyBaseFile = "/path/to/secret_key_base_file"; + secretKeyBaseFile = "/path/to/secret_key_base_file"; }; - - -
- -
- Database access - - Discourse uses - PostgreSQL to store most of its - data. A database will automatically be enabled and a database - and role created unless is changed from - its default of null or is set - to false. - - - - External database access can also be configured by setting - , and as - appropriate. Note that you need to manually create a database - called discourse (or the name you chose in - ) and - allow the configured database user full access to it. - -
- -
- Email - - In addition to the basic setup, you'll want to configure an SMTP - 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. - - - - A basic setup which assumes you want to use your configured hostname as - email domain can be done like this: - - +
+
+ Database access + + Discourse uses PostgreSQL to store most of its data. A database + will automatically be enabled and a database and role created + unless + is + changed from its default of null or + + is set to false. + + + External database access can also be configured by setting + , + + and + + as appropriate. Note that you need to manually create a database + called discourse (or the name you chose in + ) and + allow the configured database user full access to it. + +
+
+ Email + + In addition to the basic setup, you'll want to configure an SMTP + 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. + + + A basic setup which assumes you want to use your configured + hostname as + email domain can be done like this: + + services.discourse = { enable = true; - hostname = "discourse.example.com"; - sslCertificate = "/path/to/ssl_certificate"; - sslCertificateKey = "/path/to/ssl_certificate_key"; + hostname = "discourse.example.com"; + sslCertificate = "/path/to/ssl_certificate"; + sslCertificateKey = "/path/to/ssl_certificate_key"; admin = { - email = "admin@example.com"; - username = "admin"; - fullName = "Administrator"; - passwordFile = "/path/to/password_file"; + email = "admin@example.com"; + username = "admin"; + fullName = "Administrator"; + passwordFile = "/path/to/password_file"; }; mail.outgoing = { - serverAddress = "smtp.emailprovider.com"; + serverAddress = "smtp.emailprovider.com"; port = 587; - username = "user@emailprovider.com"; - passwordFile = "/path/to/smtp_password_file"; + username = "user@emailprovider.com"; + passwordFile = "/path/to/smtp_password_file"; }; mail.incoming.enable = true; - secretKeyBaseFile = "/path/to/secret_key_base_file"; + secretKeyBaseFile = "/path/to/secret_key_base_file"; }; - - This assumes you have set up an MX record for the address you've - set in hostname and - requires proper SPF, DKIM and DMARC configuration to be done for - the domain you're sending from, in order for email to be reliably delivered. - - - - If you want to use a different domain for your outgoing email - (for example example.com instead of - discourse.example.com) you should set - and - manually. - - - - - Setup of TLS for incoming email is currently only configured - automatically when a regular TLS certificate is used, i.e. when - and - are - set. - - - -
- -
- Additional settings - - Additional site settings and backend settings, for which no - explicit NixOS options are provided, - can be set in and - respectively. - - -
- Site settings - - "Site settings" are the settings that can be - changed through the Discourse - UI. Their default values can be set using - . - - - - Settings are expressed as a Nix attribute set which matches the - structure of the configuration in - config/site_settings.yml. - To find a setting's path, you only need to care about the first - two levels; i.e. its category (e.g. login) - and name (e.g. invite_only). - - - - Settings containing secret data should be set to an attribute - set containing the attribute _secret - a - string pointing to a file containing the value the option - should be set to. See the example. - -
- -
- Backend settings - - Settings are expressed as a Nix attribute set which matches the - structure of the configuration in - config/discourse.conf. - Empty parameters can be defined by setting them to - null. - -
- -
- Example - - 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: - + + This assumes you have set up an MX record for the address you've + set in + hostname + and requires proper SPF, DKIM and DMARC configuration to be done + for the domain you're sending from, in order for email to be + reliably delivered. + + + If you want to use a different domain for your outgoing email (for + example example.com instead of + discourse.example.com) you should set + + and + + manually. + + + + Setup of TLS for incoming email is currently only configured + automatically when a regular TLS certificate is used, i.e. when + + and + + are set. + + +
+
+ Additional settings + + Additional site settings and backend settings, for which no + explicit NixOS options are provided, can be set in + and + + respectively. + +
+ Site settings + + "Site settings" are the settings that can be changed + through the Discourse UI. Their default + values can be set using + . + + + Settings are expressed as a Nix attribute set which matches the + structure of the configuration in + config/site_settings.yml. + To find a setting's path, you only need to care about the first + two levels; i.e. its category (e.g. login) + and name (e.g. invite_only). + + + Settings containing secret data should be set to an attribute + set containing the attribute _secret - a + string pointing to a file containing the value the option should + be set to. See the example. + +
+
+ Backend settings + + Settings are expressed as a Nix attribute set which matches the + structure of the configuration in + config/discourse.conf. + Empty parameters can be defined by setting them to + null. + +
+
+ Example + + 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: + + services.discourse = { enable = true; - hostname = "discourse.example.com"; - sslCertificate = "/path/to/ssl_certificate"; - sslCertificateKey = "/path/to/ssl_certificate_key"; + hostname = "discourse.example.com"; + sslCertificate = "/path/to/ssl_certificate"; + sslCertificateKey = "/path/to/ssl_certificate_key"; admin = { - email = "admin@example.com"; - username = "admin"; - fullName = "Administrator"; - passwordFile = "/path/to/password_file"; + email = "admin@example.com"; + username = "admin"; + fullName = "Administrator"; + passwordFile = "/path/to/password_file"; }; mail.outgoing = { - serverAddress = "smtp.emailprovider.com"; + serverAddress = "smtp.emailprovider.com"; port = 587; - username = "user@emailprovider.com"; - passwordFile = "/path/to/smtp_password_file"; + username = "user@emailprovider.com"; + passwordFile = "/path/to/smtp_password_file"; }; mail.incoming.enable = true; siteSettings = { required = { - title = "My Cats"; - site_description = "Discuss My Cats (and be nice plz)"; + title = "My Cats"; + site_description = "Discuss My Cats (and be nice plz)"; }; login = { enable_github_logins = true; - github_client_id = "a2f6dfe838cb3206ce20"; + github_client_id = "a2f6dfe838cb3206ce20"; github_client_secret._secret = /run/keys/discourse_github_client_secret; }; }; @@ -242,99 +227,93 @@ services.discourse = { max_reqs_per_ip_per_minute = 300; max_reqs_per_ip_per_10_seconds = 60; max_asset_reqs_per_ip_per_10_seconds = 250; - max_reqs_per_ip_mode = "warn+block"; + max_reqs_per_ip_mode = "warn+block"; }; - secretKeyBaseFile = "/path/to/secret_key_base_file"; + secretKeyBaseFile = "/path/to/secret_key_base_file"; }; - - - In the resulting site settings file, the - login.github_client_secret key will be set - to the contents of the - /run/keys/discourse_github_client_secret - file. - -
-
+ + In the resulting site settings file, the + login.github_client_secret key will be set to + the contents of the + /run/keys/discourse_github_client_secret + file. + +
+
Plugins - You can install Discourse plugins - using the - option. Pre-packaged plugins are provided in + You can install Discourse plugins using the + option. + Pre-packaged plugins are provided in <your_discourse_package_here>.plugins. If you want the full suite of plugins provided through - nixpkgs, you can also set the option to + nixpkgs, you can also set the + option to pkgs.discourseAllPlugins. - Plugins can be built with the <your_discourse_package_here>.mkDiscoursePlugin function. Normally, it should suffice to provide a name and src attribute. If the plugin has Ruby dependencies, however, they need to be - packaged in accordance with the Developing - with Ruby section of the Nixpkgs manual and the - appropriate gem options set in bundlerEnvArgs - (normally gemdir is sufficient). A plugin's - Ruby dependencies are listed in its - plugin.rb file as function calls to - gem. To construct the corresponding - Gemfile manually, run bundle - init, then add the gem lines to it - verbatim. + packaged in accordance with the + Developing + with Ruby section of the Nixpkgs manual and the appropriate + gem options set in bundlerEnvArgs (normally + gemdir is sufficient). A plugin's Ruby + dependencies are listed in its plugin.rb file + as function calls to gem. To construct the + corresponding Gemfile manually, run + bundle init, then add the + gem lines to it verbatim. - Much of the packaging can be done automatically by the nixpkgs/pkgs/servers/web-apps/discourse/update.py script - just add the plugin to the plugins - list in the update_plugins function and run - the script: - + list in the update_plugins function and run the + script: + + ./update.py update-plugins - - - Some plugins provide site - settings. Their defaults can be configured using , just like - regular site settings. To find the names of these settings, look - in the config/settings.yml file of the plugin - repo. + Some plugins provide + site + settings. Their defaults can be configured using + , just + like regular site settings. To find the names of these settings, + look in the config/settings.yml file of the + plugin repo. - - For example, to add the discourse-spoiler-alert - and discourse-solved - plugins, and disable discourse-spoiler-alert - by default: - - + For example, to add the + discourse-spoiler-alert + and + discourse-solved + plugins, and disable discourse-spoiler-alert by + default: + + services.discourse = { enable = true; - hostname = "discourse.example.com"; - sslCertificate = "/path/to/ssl_certificate"; - sslCertificateKey = "/path/to/ssl_certificate_key"; + hostname = "discourse.example.com"; + sslCertificate = "/path/to/ssl_certificate"; + sslCertificateKey = "/path/to/ssl_certificate_key"; admin = { - email = "admin@example.com"; - username = "admin"; - fullName = "Administrator"; - passwordFile = "/path/to/password_file"; + email = "admin@example.com"; + username = "admin"; + fullName = "Administrator"; + passwordFile = "/path/to/password_file"; }; mail.outgoing = { - serverAddress = "smtp.emailprovider.com"; + serverAddress = "smtp.emailprovider.com"; port = 587; - username = "user@emailprovider.com"; - passwordFile = "/path/to/smtp_password_file"; + username = "user@emailprovider.com"; + passwordFile = "/path/to/smtp_password_file"; }; mail.incoming.enable = true; plugins = with config.services.discourse.package.plugins; [ @@ -346,10 +325,8 @@ services.discourse = { spoiler_enabled = false; }; }; - secretKeyBaseFile = "/path/to/secret_key_base_file"; + secretKeyBaseFile = "/path/to/secret_key_base_file"; }; - -
-- cgit 1.4.1