diff options
author | github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> | 2023-01-13 18:01:34 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-13 18:01:34 +0000 |
commit | 49722fd14a26ca6a751932949491a87afe592d0d (patch) | |
tree | 39ef79595d5b0e4c5cafb3fd7f73e95cd3500d66 /nixos/modules/services/web-apps | |
parent | 54cb39a3f5cd6a1b1138ec8dcc90ffaf7e8f0927 (diff) | |
parent | befc83905c965adfd33e5cae49acb0351f6e0404 (diff) |
Merge master into staging-next
Diffstat (limited to 'nixos/modules/services/web-apps')
22 files changed, 1878 insertions, 987 deletions
diff --git a/nixos/modules/services/web-apps/akkoma.xml b/nixos/modules/services/web-apps/akkoma.xml index 76e6b806f30fe..49cbcc911e1d1 100644 --- a/nixos/modules/services/web-apps/akkoma.xml +++ b/nixos/modules/services/web-apps/akkoma.xml @@ -1,3 +1,5 @@ +<!-- Do not edit this file directly, edit its companion .md instead + and regenerate this file using nixos/doc/manual/md-to-db.sh --> <chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-akkoma"> <title>Akkoma</title> <para> @@ -371,7 +373,7 @@ services.systemd.akkoma.confinement.enable = true; and <option>services.systemd.akkoma.serviceConfig.BindReadOnlyPaths</option> permit access to outside paths through bind mounts. Refer to - <link xlink:href="https://www.freedesktop.org/software/systemd/man/systemd.exec.html#BindPaths="><link xlink:href="https://www.freedesktop.org/software/systemd/man/systemd.exec.html"><citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry></link></link> + <link xlink:href="https://www.freedesktop.org/software/systemd/man/systemd.exec.html#BindPaths="><citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry></link> for details. </para> </section> diff --git a/nixos/modules/services/web-apps/discourse.md b/nixos/modules/services/web-apps/discourse.md new file mode 100644 index 0000000000000..35180bea87d90 --- /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 +`<your_discourse_package_here>.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 +`<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](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.xml b/nixos/modules/services/web-apps/discourse.xml index ad9b65abf51e0..a5e8b3656b7de 100644 --- a/nixos/modules/services/web-apps/discourse.xml +++ b/nixos/modules/services/web-apps/discourse.xml @@ -1,355 +1,331 @@ -<chapter xmlns="http://docbook.org/ns/docbook" - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:xi="http://www.w3.org/2001/XInclude" - version="5.0" - xml:id="module-services-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> - A minimal configuration using Let's Encrypt for TLS certificates looks like this: -<programlisting> +<!-- Do not edit this file directly, edit its companion .md instead + and regenerate this file using nixos/doc/manual/md-to-db.sh --> +<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> + A minimal configuration using Let’s Encrypt for TLS certificates + looks like this: + </para> + <programlisting> services.discourse = { - <link linkend="opt-services.discourse.enable">enable</link> = true; - <link linkend="opt-services.discourse.hostname">hostname</link> = "discourse.example.com"; + enable = true; + hostname = "discourse.example.com"; admin = { - <link linkend="opt-services.discourse.admin.email">email</link> = "admin@example.com"; - <link linkend="opt-services.discourse.admin.username">username</link> = "admin"; - <link linkend="opt-services.discourse.admin.fullName">fullName</link> = "Administrator"; - <link linkend="opt-services.discourse.admin.passwordFile">passwordFile</link> = "/path/to/password_file"; + email = "admin@example.com"; + username = "admin"; + fullName = "Administrator"; + passwordFile = "/path/to/password_file"; }; - <link linkend="opt-services.discourse.secretKeyBaseFile">secretKeyBaseFile</link> = "/path/to/secret_key_base_file"; + secretKeyBaseFile = "/path/to/secret_key_base_file"; }; -<link linkend="opt-security.acme.defaults.email">security.acme.email</link> = "me@example.com"; -<link linkend="opt-security.acme.acceptTerms">security.acme.acceptTerms</link> = true; +security.acme.email = "me@example.com"; +security.acme.acceptTerms = true; </programlisting> - </para> - - <para> - Provided a proper DNS setup, you'll be able to connect to the - 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 <xref linkend="opt-services.discourse.sslCertificate" /> - and <xref linkend="opt-services.discourse.sslCertificateKey" /> - options: - -<programlisting> + <para> + Provided a proper DNS setup, you’ll be able to connect to the + 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 + <xref linkend="opt-services.discourse.sslCertificate" /> and + <xref linkend="opt-services.discourse.sslCertificateKey" /> + options: + </para> + <programlisting> services.discourse = { - <link linkend="opt-services.discourse.enable">enable</link> = true; - <link linkend="opt-services.discourse.hostname">hostname</link> = "discourse.example.com"; - <link linkend="opt-services.discourse.sslCertificate">sslCertificate</link> = "/path/to/ssl_certificate"; - <link linkend="opt-services.discourse.sslCertificateKey">sslCertificateKey</link> = "/path/to/ssl_certificate_key"; + enable = true; + hostname = "discourse.example.com"; + sslCertificate = "/path/to/ssl_certificate"; + sslCertificateKey = "/path/to/ssl_certificate_key"; admin = { - <link linkend="opt-services.discourse.admin.email">email</link> = "admin@example.com"; - <link linkend="opt-services.discourse.admin.username">username</link> = "admin"; - <link linkend="opt-services.discourse.admin.fullName">fullName</link> = "Administrator"; - <link linkend="opt-services.discourse.admin.passwordFile">passwordFile</link> = "/path/to/password_file"; + email = "admin@example.com"; + username = "admin"; + fullName = "Administrator"; + passwordFile = "/path/to/password_file"; }; - <link linkend="opt-services.discourse.secretKeyBaseFile">secretKeyBaseFile</link> = "/path/to/secret_key_base_file"; + secretKeyBaseFile = "/path/to/secret_key_base_file"; }; </programlisting> - - </para> - </section> - - <section xml:id="module-services-discourse-database"> - <title>Database access</title> - <para> - <productname>Discourse</productname> uses - <productname>PostgreSQL</productname> to store most of its - data. A database will automatically be enabled and a database - and role created unless <xref - linkend="opt-services.discourse.database.host" /> is changed from - its default of <literal>null</literal> or <xref - linkend="opt-services.discourse.database.createLocally" /> is set - to <literal>false</literal>. - </para> - - <para> - External database access can also be configured by setting - <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 - called <literal>discourse</literal> (or the name you chose in - <xref linkend="opt-services.discourse.database.name" />) and - allow the configured database user full access to it. - </para> - </section> - - <section xml:id="module-services-discourse-mail"> - <title>Email</title> - <para> - In addition to the basic setup, you'll want to configure an SMTP - server <productname>Discourse</productname> can use to send user - registration and password reset emails, among others. You can - also optionally let <productname>Discourse</productname> 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: - -<programlisting> + </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 + unless <xref linkend="opt-services.discourse.database.host" /> is + changed from its default of <literal>null</literal> or + <xref linkend="opt-services.discourse.database.createLocally" /> + is set to <literal>false</literal>. + </para> + <para> + External database access can also be configured by setting + <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 + called <literal>discourse</literal> (or the name you chose in + <xref linkend="opt-services.discourse.database.name" />) and allow + the configured database user full access to it. + </para> + </section> + <section xml:id="module-services-discourse-mail"> + <title>Email</title> + <para> + 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. + </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> services.discourse = { - <link linkend="opt-services.discourse.enable">enable</link> = true; - <link linkend="opt-services.discourse.hostname">hostname</link> = "discourse.example.com"; - <link linkend="opt-services.discourse.sslCertificate">sslCertificate</link> = "/path/to/ssl_certificate"; - <link linkend="opt-services.discourse.sslCertificateKey">sslCertificateKey</link> = "/path/to/ssl_certificate_key"; + enable = true; + hostname = "discourse.example.com"; + sslCertificate = "/path/to/ssl_certificate"; + sslCertificateKey = "/path/to/ssl_certificate_key"; admin = { - <link linkend="opt-services.discourse.admin.email">email</link> = "admin@example.com"; - <link linkend="opt-services.discourse.admin.username">username</link> = "admin"; - <link linkend="opt-services.discourse.admin.fullName">fullName</link> = "Administrator"; - <link linkend="opt-services.discourse.admin.passwordFile">passwordFile</link> = "/path/to/password_file"; + email = "admin@example.com"; + username = "admin"; + fullName = "Administrator"; + passwordFile = "/path/to/password_file"; }; mail.outgoing = { - <link linkend="opt-services.discourse.mail.outgoing.serverAddress">serverAddress</link> = "smtp.emailprovider.com"; - <link linkend="opt-services.discourse.mail.outgoing.port">port</link> = 587; - <link linkend="opt-services.discourse.mail.outgoing.username">username</link> = "user@emailprovider.com"; - <link linkend="opt-services.discourse.mail.outgoing.passwordFile">passwordFile</link> = "/path/to/smtp_password_file"; + serverAddress = "smtp.emailprovider.com"; + port = 587; + username = "user@emailprovider.com"; + passwordFile = "/path/to/smtp_password_file"; }; - <link linkend="opt-services.discourse.mail.incoming.enable">mail.incoming.enable</link> = true; - <link linkend="opt-services.discourse.secretKeyBaseFile">secretKeyBaseFile</link> = "/path/to/secret_key_base_file"; + mail.incoming.enable = true; + secretKeyBaseFile = "/path/to/secret_key_base_file"; }; </programlisting> - - This assumes you have set up an MX record for the address you've - set in <link linkend="opt-services.discourse.hostname">hostname</link> 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. - </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 - <xref linkend="opt-services.discourse.mail.notificationEmailAddress" /> and - <xref linkend="opt-services.discourse.mail.contactEmailAddress" /> manually. - </para> - - <note> - <para> - Setup of TLS for incoming email is currently only configured - 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. - </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 <productname>NixOS</productname> options are provided, - can be set in <xref linkend="opt-services.discourse.siteSettings" /> and - <xref linkend="opt-services.discourse.backendSettings" /> respectively. - </para> - - <section xml:id="module-services-discourse-site-settings"> - <title>Site settings</title> - <para> - <quote>Site settings</quote> are the settings that can be - changed through the <productname>Discourse</productname> - UI. Their <emphasis>default</emphasis> values can be set using - <xref linkend="opt-services.discourse.siteSettings" />. - </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>. - To find a setting's path, you only need to care about the first - two levels; i.e. its category (e.g. <literal>login</literal>) - and name (e.g. <literal>invite_only</literal>). - </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 - <productname>Discourse</productname> instance and enables - <productname>GitHub</productname> login in the site settings, - and changes a few request limits in the backend settings: -<programlisting> + <para> + This assumes you have set up an MX record for the address you’ve + set in + <link linkend="opt-services.discourse.hostname">hostname</link> + 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. + </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 + <xref linkend="opt-services.discourse.mail.notificationEmailAddress" /> + and + <xref linkend="opt-services.discourse.mail.contactEmailAddress" /> + manually. + </para> + <note> + <para> + Setup of TLS for incoming email is currently only configured + 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. + </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 + <xref linkend="opt-services.discourse.siteSettings" /> and + <xref linkend="opt-services.discourse.backendSettings" /> + respectively. + </para> + <section xml:id="module-services-discourse-site-settings"> + <title>Site settings</title> + <para> + <quote>Site settings</quote> are the settings that can be + changed through the Discourse UI. Their + <emphasis>default</emphasis> values can be set using + <xref linkend="opt-services.discourse.siteSettings" />. + </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>. + To find a setting’s path, you only need to care about the first + two levels; i.e. its category (e.g. <literal>login</literal>) + and name (e.g. <literal>invite_only</literal>). + </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> services.discourse = { - <link linkend="opt-services.discourse.enable">enable</link> = true; - <link linkend="opt-services.discourse.hostname">hostname</link> = "discourse.example.com"; - <link linkend="opt-services.discourse.sslCertificate">sslCertificate</link> = "/path/to/ssl_certificate"; - <link linkend="opt-services.discourse.sslCertificateKey">sslCertificateKey</link> = "/path/to/ssl_certificate_key"; + enable = true; + hostname = "discourse.example.com"; + sslCertificate = "/path/to/ssl_certificate"; + sslCertificateKey = "/path/to/ssl_certificate_key"; admin = { - <link linkend="opt-services.discourse.admin.email">email</link> = "admin@example.com"; - <link linkend="opt-services.discourse.admin.username">username</link> = "admin"; - <link linkend="opt-services.discourse.admin.fullName">fullName</link> = "Administrator"; - <link linkend="opt-services.discourse.admin.passwordFile">passwordFile</link> = "/path/to/password_file"; + email = "admin@example.com"; + username = "admin"; + fullName = "Administrator"; + passwordFile = "/path/to/password_file"; }; mail.outgoing = { - <link linkend="opt-services.discourse.mail.outgoing.serverAddress">serverAddress</link> = "smtp.emailprovider.com"; - <link linkend="opt-services.discourse.mail.outgoing.port">port</link> = 587; - <link linkend="opt-services.discourse.mail.outgoing.username">username</link> = "user@emailprovider.com"; - <link linkend="opt-services.discourse.mail.outgoing.passwordFile">passwordFile</link> = "/path/to/smtp_password_file"; + serverAddress = "smtp.emailprovider.com"; + port = 587; + username = "user@emailprovider.com"; + passwordFile = "/path/to/smtp_password_file"; }; - <link linkend="opt-services.discourse.mail.incoming.enable">mail.incoming.enable</link> = true; - <link linkend="opt-services.discourse.siteSettings">siteSettings</link> = { + 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; }; }; - <link linkend="opt-services.discourse.backendSettings">backendSettings</link> = { + 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"; + max_reqs_per_ip_mode = "warn+block"; }; - <link linkend="opt-services.discourse.secretKeyBaseFile">secretKeyBaseFile</link> = "/path/to/secret_key_base_file"; + secretKeyBaseFile = "/path/to/secret_key_base_file"; }; </programlisting> - </para> - <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> + <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> <section xml:id="module-services-discourse-plugins"> <title>Plugins</title> <para> - You can install <productname>Discourse</productname> plugins - using the <xref linkend="opt-services.discourse.plugins" /> - option. Pre-packaged plugins are provided in + You can install Discourse plugins using the + <xref linkend="opt-services.discourse.plugins" /> option. + Pre-packaged plugins are provided in <literal><your_discourse_package_here>.plugins</literal>. If you want the full suite of plugins provided through - <literal>nixpkgs</literal>, you can also set the <xref - linkend="opt-services.discourse.package" /> option to + <literal>nixpkgs</literal>, you can also set the + <xref linkend="opt-services.discourse.package" /> option to <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 - 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 <literal>gemdir</literal> is sufficient). A plugin's - Ruby 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. + 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 + <literal>gemdir</literal> is sufficient). A plugin’s Ruby + 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. </para> - <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> - list in the <function>update_plugins</function> function and run - the script: - <programlisting language="bash"> + list in the <literal>update_plugins</literal> function and run the + script: + </para> + <programlisting language="bash"> ./update.py update-plugins </programlisting> - </para> - <para> - Some plugins provide <link - linkend="module-services-discourse-site-settings">site - settings</link>. Their defaults can be configured using <xref - linkend="opt-services.discourse.siteSettings" />, just like + Some plugins provide + <link linkend="module-services-discourse-site-settings">site + settings</link>. Their defaults can be configured using + <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. </para> - <para> - 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: - -<programlisting> + 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> services.discourse = { - <link linkend="opt-services.discourse.enable">enable</link> = true; - <link linkend="opt-services.discourse.hostname">hostname</link> = "discourse.example.com"; - <link linkend="opt-services.discourse.sslCertificate">sslCertificate</link> = "/path/to/ssl_certificate"; - <link linkend="opt-services.discourse.sslCertificateKey">sslCertificateKey</link> = "/path/to/ssl_certificate_key"; + enable = true; + hostname = "discourse.example.com"; + sslCertificate = "/path/to/ssl_certificate"; + sslCertificateKey = "/path/to/ssl_certificate_key"; admin = { - <link linkend="opt-services.discourse.admin.email">email</link> = "admin@example.com"; - <link linkend="opt-services.discourse.admin.username">username</link> = "admin"; - <link linkend="opt-services.discourse.admin.fullName">fullName</link> = "Administrator"; - <link linkend="opt-services.discourse.admin.passwordFile">passwordFile</link> = "/path/to/password_file"; + email = "admin@example.com"; + username = "admin"; + fullName = "Administrator"; + passwordFile = "/path/to/password_file"; }; mail.outgoing = { - <link linkend="opt-services.discourse.mail.outgoing.serverAddress">serverAddress</link> = "smtp.emailprovider.com"; - <link linkend="opt-services.discourse.mail.outgoing.port">port</link> = 587; - <link linkend="opt-services.discourse.mail.outgoing.username">username</link> = "user@emailprovider.com"; - <link linkend="opt-services.discourse.mail.outgoing.passwordFile">passwordFile</link> = "/path/to/smtp_password_file"; + serverAddress = "smtp.emailprovider.com"; + port = 587; + username = "user@emailprovider.com"; + passwordFile = "/path/to/smtp_password_file"; }; - <link linkend="opt-services.discourse.mail.incoming.enable">mail.incoming.enable</link> = true; - <link linkend="opt-services.discourse.mail.incoming.enable">plugins</link> = with config.services.discourse.package.plugins; [ + mail.incoming.enable = true; + plugins = with config.services.discourse.package.plugins; [ discourse-spoiler-alert discourse-solved ]; - <link linkend="opt-services.discourse.siteSettings">siteSettings</link> = { + siteSettings = { plugins = { spoiler_enabled = false; }; }; - <link linkend="opt-services.discourse.secretKeyBaseFile">secretKeyBaseFile</link> = "/path/to/secret_key_base_file"; + secretKeyBaseFile = "/path/to/secret_key_base_file"; }; </programlisting> - - </para> </section> </chapter> diff --git a/nixos/modules/services/web-apps/grocy.md b/nixos/modules/services/web-apps/grocy.md new file mode 100644 index 0000000000000..62aad4b103df1 --- /dev/null +++ b/nixos/modules/services/web-apps/grocy.md @@ -0,0 +1,66 @@ +# Grocy {#module-services-grocy} + +[Grocy](https://grocy.info/) is a web-based self-hosted groceries +& household management solution for your home. + +## Basic usage {#module-services-grocy-basic-usage} + +A very basic configuration may look like this: +``` +{ pkgs, ... }: +{ + services.grocy = { + enable = true; + hostName = "grocy.tld"; + }; +} +``` +This configures a simple vhost using [nginx](#opt-services.nginx.enable) +which listens to `grocy.tld` with fully configured ACME/LE (this can be +disabled by setting [services.grocy.nginx.enableSSL](#opt-services.grocy.nginx.enableSSL) +to `false`). After the initial setup the credentials `admin:admin` +can be used to login. + +The application's state is persisted at `/var/lib/grocy/grocy.db` in a +`sqlite3` database. The migration is applied when requesting the `/`-route +of the application. + +## Settings {#module-services-grocy-settings} + +The configuration for `grocy` is located at `/etc/grocy/config.php`. +By default, the following settings can be defined in the NixOS-configuration: +``` +{ pkgs, ... }: +{ + services.grocy.settings = { + # The default currency in the system for invoices etc. + # Please note that exchange rates aren't taken into account, this + # is just the setting for what's shown in the frontend. + currency = "EUR"; + + # The display language (and locale configuration) for grocy. + culture = "de"; + + calendar = { + # Whether or not to show the week-numbers + # in the calendar. + showWeekNumber = true; + + # Index of the first day to be shown in the calendar (0=Sunday, 1=Monday, + # 2=Tuesday and so on). + firstDayOfWeek = 2; + }; + }; +} +``` + +If you want to alter the configuration file on your own, you can do this manually with +an expression like this: +``` +{ lib, ... }: +{ + environment.etc."grocy/config.php".text = lib.mkAfter '' + // Arbitrary PHP code in grocy's configuration file + ''; +} +``` diff --git a/nixos/modules/services/web-apps/grocy.xml b/nixos/modules/services/web-apps/grocy.xml index fdf6d00f4b123..08de25b4ce2b8 100644 --- a/nixos/modules/services/web-apps/grocy.xml +++ b/nixos/modules/services/web-apps/grocy.xml @@ -1,77 +1,84 @@ -<chapter xmlns="http://docbook.org/ns/docbook" - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:xi="http://www.w3.org/2001/XInclude" - version="5.0" - xml:id="module-services-grocy"> - +<!-- Do not edit this file directly, edit its companion .md instead + and regenerate this file using nixos/doc/manual/md-to-db.sh --> +<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-grocy"> <title>Grocy</title> <para> - <link xlink:href="https://grocy.info/">Grocy</link> is a web-based self-hosted groceries - & household management solution for your home. + <link xlink:href="https://grocy.info/">Grocy</link> is a web-based + self-hosted groceries & household management solution for your + home. </para> - <section xml:id="module-services-grocy-basic-usage"> - <title>Basic usage</title> - <para> - A very basic configuration may look like this: -<programlisting>{ pkgs, ... }: + <title>Basic usage</title> + <para> + A very basic configuration may look like this: + </para> + <programlisting> +{ pkgs, ... }: { services.grocy = { - <link linkend="opt-services.grocy.enable">enable</link> = true; - <link linkend="opt-services.grocy.hostName">hostName</link> = "grocy.tld"; + enable = true; + hostName = "grocy.tld"; }; -}</programlisting> - This configures a simple vhost using <link linkend="opt-services.nginx.enable">nginx</link> - which listens to <literal>grocy.tld</literal> with fully configured ACME/LE (this can be - disabled by setting <link linkend="opt-services.grocy.nginx.enableSSL">services.grocy.nginx.enableSSL</link> - to <literal>false</literal>). After the initial setup the credentials <literal>admin:admin</literal> - can be used to login. - </para> - <para> - The application's state is persisted at <literal>/var/lib/grocy/grocy.db</literal> in a - <package>sqlite3</package> database. The migration is applied when requesting the <literal>/</literal>-route - of the application. - </para> +} +</programlisting> + <para> + This configures a simple vhost using + <link linkend="opt-services.nginx.enable">nginx</link> which + listens to <literal>grocy.tld</literal> with fully configured + ACME/LE (this can be disabled by setting + <link linkend="opt-services.grocy.nginx.enableSSL">services.grocy.nginx.enableSSL</link> + to <literal>false</literal>). After the initial setup the + credentials <literal>admin:admin</literal> can be used to login. + </para> + <para> + The application’s state is persisted at + <literal>/var/lib/grocy/grocy.db</literal> in a + <literal>sqlite3</literal> database. The migration is applied when + requesting the <literal>/</literal>-route of the application. + </para> </section> - <section xml:id="module-services-grocy-settings"> - <title>Settings</title> - <para> - The configuration for <literal>grocy</literal> is located at <literal>/etc/grocy/config.php</literal>. - By default, the following settings can be defined in the NixOS-configuration: -<programlisting>{ pkgs, ... }: + <title>Settings</title> + <para> + The configuration for <literal>grocy</literal> is located at + <literal>/etc/grocy/config.php</literal>. By default, the + following settings can be defined in the NixOS-configuration: + </para> + <programlisting> +{ pkgs, ... }: { services.grocy.settings = { # The default currency in the system for invoices etc. # Please note that exchange rates aren't taken into account, this # is just the setting for what's shown in the frontend. - <link linkend="opt-services.grocy.settings.currency">currency</link> = "EUR"; + currency = "EUR"; # The display language (and locale configuration) for grocy. - <link linkend="opt-services.grocy.settings.currency">culture</link> = "de"; + culture = "de"; calendar = { # Whether or not to show the week-numbers # in the calendar. - <link linkend="opt-services.grocy.settings.calendar.showWeekNumber">showWeekNumber</link> = true; + showWeekNumber = true; # Index of the first day to be shown in the calendar (0=Sunday, 1=Monday, # 2=Tuesday and so on). - <link linkend="opt-services.grocy.settings.calendar.firstDayOfWeek">firstDayOfWeek</link> = 2; + firstDayOfWeek = 2; }; }; -}</programlisting> - </para> - <para> - If you want to alter the configuration file on your own, you can do this manually with - an expression like this: -<programlisting>{ lib, ... }: +} +</programlisting> + <para> + If you want to alter the configuration file on your own, you can + do this manually with an expression like this: + </para> + <programlisting> +{ lib, ... }: { - environment.etc."grocy/config.php".text = lib.mkAfter '' + environment.etc."grocy/config.php".text = lib.mkAfter '' // Arbitrary PHP code in grocy's configuration file ''; -}</programlisting> - </para> +} +</programlisting> </section> - </chapter> diff --git a/nixos/modules/services/web-apps/jitsi-meet.md b/nixos/modules/services/web-apps/jitsi-meet.md new file mode 100644 index 0000000000000..060ef9752650a --- /dev/null +++ b/nixos/modules/services/web-apps/jitsi-meet.md @@ -0,0 +1,45 @@ +# Jitsi Meet {#module-services-jitsi-meet} + +With Jitsi Meet on NixOS you can quickly configure a complete, +private, self-hosted video conferencing solution. + +## Basic usage {#module-services-jitsi-basic-usage} + +A minimal configuration using Let's Encrypt for TLS certificates looks like this: +``` +{ + services.jitsi-meet = { + enable = true; + hostName = "jitsi.example.com"; + }; + services.jitsi-videobridge.openFirewall = true; + networking.firewall.allowedTCPPorts = [ 80 443 ]; + security.acme.email = "me@example.com"; + security.acme.acceptTerms = true; +} +``` + +## Configuration {#module-services-jitsi-configuration} + +Here is the minimal configuration with additional configurations: +``` +{ + services.jitsi-meet = { + enable = true; + hostName = "jitsi.example.com"; + config = { + enableWelcomePage = false; + prejoinPageEnabled = true; + defaultLang = "fi"; + }; + interfaceConfig = { + SHOW_JITSI_WATERMARK = false; + SHOW_WATERMARK_FOR_GUESTS = false; + }; + }; + services.jitsi-videobridge.openFirewall = true; + networking.firewall.allowedTCPPorts = [ 80 443 ]; + security.acme.email = "me@example.com"; + security.acme.acceptTerms = true; +} +``` diff --git a/nixos/modules/services/web-apps/jitsi-meet.xml b/nixos/modules/services/web-apps/jitsi-meet.xml index ff44c724adf44..4d2d8aa55e19f 100644 --- a/nixos/modules/services/web-apps/jitsi-meet.xml +++ b/nixos/modules/services/web-apps/jitsi-meet.xml @@ -1,55 +1,55 @@ -<chapter xmlns="http://docbook.org/ns/docbook" - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:xi="http://www.w3.org/2001/XInclude" - version="5.0" - xml:id="module-services-jitsi-meet"> - <title>Jitsi Meet</title> - <para> - With Jitsi Meet on NixOS you can quickly configure a complete, - private, self-hosted video conferencing solution. - </para> - - <section xml:id="module-services-jitsi-basic-usage"> - <title>Basic usage</title> - <para> - A minimal configuration using Let's Encrypt for TLS certificates looks like this: -<programlisting>{ +<!-- Do not edit this file directly, edit its companion .md instead + and regenerate this file using nixos/doc/manual/md-to-db.sh --> +<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-jitsi-meet"> + <title>Jitsi Meet</title> + <para> + With Jitsi Meet on NixOS you can quickly configure a complete, + private, self-hosted video conferencing solution. + </para> + <section xml:id="module-services-jitsi-basic-usage"> + <title>Basic usage</title> + <para> + A minimal configuration using Let’s Encrypt for TLS certificates + looks like this: + </para> + <programlisting> +{ services.jitsi-meet = { - <link linkend="opt-services.jitsi-meet.enable">enable</link> = true; - <link linkend="opt-services.jitsi-meet.enable">hostName</link> = "jitsi.example.com"; + enable = true; + hostName = "jitsi.example.com"; }; - <link linkend="opt-services.jitsi-videobridge.openFirewall">services.jitsi-videobridge.openFirewall</link> = true; - <link linkend="opt-networking.firewall.allowedTCPPorts">networking.firewall.allowedTCPPorts</link> = [ 80 443 ]; - <link linkend="opt-security.acme.defaults.email">security.acme.email</link> = "me@example.com"; - <link linkend="opt-security.acme.acceptTerms">security.acme.acceptTerms</link> = true; -}</programlisting> - </para> - </section> - - <section xml:id="module-services-jitsi-configuration"> - <title>Configuration</title> - <para> - Here is the minimal configuration with additional configurations: -<programlisting>{ + services.jitsi-videobridge.openFirewall = true; + networking.firewall.allowedTCPPorts = [ 80 443 ]; + security.acme.email = "me@example.com"; + security.acme.acceptTerms = true; +} +</programlisting> + </section> + <section xml:id="module-services-jitsi-configuration"> + <title>Configuration</title> + <para> + Here is the minimal configuration with additional configurations: + </para> + <programlisting> +{ services.jitsi-meet = { - <link linkend="opt-services.jitsi-meet.enable">enable</link> = true; - <link linkend="opt-services.jitsi-meet.enable">hostName</link> = "jitsi.example.com"; - <link linkend="opt-services.jitsi-meet.config">config</link> = { + enable = true; + hostName = "jitsi.example.com"; + config = { enableWelcomePage = false; prejoinPageEnabled = true; - defaultLang = "fi"; + defaultLang = "fi"; }; - <link linkend="opt-services.jitsi-meet.interfaceConfig">interfaceConfig</link> = { + interfaceConfig = { SHOW_JITSI_WATERMARK = false; SHOW_WATERMARK_FOR_GUESTS = false; }; }; - <link linkend="opt-services.jitsi-videobridge.openFirewall">services.jitsi-videobridge.openFirewall</link> = true; - <link linkend="opt-networking.firewall.allowedTCPPorts">networking.firewall.allowedTCPPorts</link> = [ 80 443 ]; - <link linkend="opt-security.acme.defaults.email">security.acme.email</link> = "me@example.com"; - <link linkend="opt-security.acme.acceptTerms">security.acme.acceptTerms</link> = true; -}</programlisting> - </para> - </section> - + services.jitsi-videobridge.openFirewall = true; + networking.firewall.allowedTCPPorts = [ 80 443 ]; + security.acme.email = "me@example.com"; + security.acme.acceptTerms = true; +} +</programlisting> + </section> </chapter> diff --git a/nixos/modules/services/web-apps/keycloak.md b/nixos/modules/services/web-apps/keycloak.md new file mode 100644 index 0000000000000..aa8de40d642b1 --- /dev/null +++ b/nixos/modules/services/web-apps/keycloak.md @@ -0,0 +1,141 @@ +# Keycloak {#module-services-keycloak} + +[Keycloak](https://www.keycloak.org/) is an +open source identity and access management server with support for +[OpenID Connect](https://openid.net/connect/), +[OAUTH 2.0](https://oauth.net/2/) and +[SAML 2.0](https://en.wikipedia.org/wiki/SAML_2.0). + +## Administration {#module-services-keycloak-admin} + +An administrative user with the username +`admin` is automatically created in the +`master` realm. Its initial password can be +configured by setting [](#opt-services.keycloak.initialAdminPassword) +and defaults to `changeme`. The password is +not stored safely and should be changed immediately in the +admin panel. + +Refer to the [Keycloak Server Administration Guide]( + https://www.keycloak.org/docs/latest/server_admin/index.html +) for information on +how to administer your Keycloak +instance. + +## Database access {#module-services-keycloak-database} + +Keycloak can be used with either PostgreSQL, MariaDB or +MySQL. Which one is used can be +configured in [](#opt-services.keycloak.database.type). The selected +database will automatically be enabled and a database and role +created unless [](#opt-services.keycloak.database.host) is changed +from its default of `localhost` or +[](#opt-services.keycloak.database.createLocally) is set to `false`. + +External database access can also be configured by setting +[](#opt-services.keycloak.database.host), +[](#opt-services.keycloak.database.name), +[](#opt-services.keycloak.database.username), +[](#opt-services.keycloak.database.useSSL) and +[](#opt-services.keycloak.database.caCert) as +appropriate. Note that you need to manually create the database +and allow the configured database user full access to it. + +[](#opt-services.keycloak.database.passwordFile) +must be set to the path to a file containing the password used +to log in to the database. If [](#opt-services.keycloak.database.host) +and [](#opt-services.keycloak.database.createLocally) +are kept at their defaults, the database role +`keycloak` with that password is provisioned +on the local database instance. + +::: {.warning} +The path should be provided as a string, not a Nix path, since Nix +paths are copied into the world readable Nix store. +::: + +## Hostname {#module-services-keycloak-hostname} + +The hostname is used to build the public URL used as base for +all frontend requests and must be configured through +[](#opt-services.keycloak.settings.hostname). + +::: {.note} +If you're migrating an old Wildfly based Keycloak instance +and want to keep compatibility with your current clients, +you'll likely want to set [](#opt-services.keycloak.settings.http-relative-path) +to `/auth`. See the option description +for more details. +::: + +[](#opt-services.keycloak.settings.hostname-strict-backchannel) +determines whether Keycloak should force all requests to go +through the frontend URL. By default, +Keycloak allows backend requests to +instead use its local hostname or IP address and may also +advertise it to clients through its OpenID Connect Discovery +endpoint. + +For more information on hostname configuration, see the [Hostname +section of the Keycloak Server Installation and Configuration +Guide](https://www.keycloak.org/server/hostname). + +## Setting up TLS/SSL {#module-services-keycloak-tls} + +By default, Keycloak won't accept +unsecured HTTP connections originating from outside its local +network. + +HTTPS support requires a TLS/SSL certificate and a private key, +both [PEM formatted](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail). +Their paths should be set through +[](#opt-services.keycloak.sslCertificate) and +[](#opt-services.keycloak.sslCertificateKey). + +::: {.warning} + The paths should be provided as a strings, not a Nix paths, +since Nix paths are copied into the world readable Nix store. +::: + +## Themes {#module-services-keycloak-themes} + +You can package custom themes and make them visible to +Keycloak through [](#opt-services.keycloak.themes). See the +[Themes section of the Keycloak Server Development Guide]( + https://www.keycloak.org/docs/latest/server_development/#_themes +) and the description of the aforementioned NixOS option for +more information. + +## Configuration file settings {#module-services-keycloak-settings} + +Keycloak server configuration parameters can be set in +[](#opt-services.keycloak.settings). These correspond +directly to options in +{file}`conf/keycloak.conf`. Some of the most +important parameters are documented as suboptions, the rest can +be found in the [All +configuration section of the Keycloak Server Installation and +Configuration Guide](https://www.keycloak.org/server/all-config). + +Options 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 description of +[](#opt-services.keycloak.settings) for an example. + +## Example configuration {#module-services-keycloak-example-config} + +A basic configuration with some custom settings could look like this: +``` +services.keycloak = { + enable = true; + settings = { + hostname = "keycloak.example.com"; + hostname-strict-backchannel = true; + }; + initialAdminPassword = "e6Wcm0RrtegMEHl"; # change on first login + sslCertificate = "/run/keys/ssl_cert"; + sslCertificateKey = "/run/keys/ssl_key"; + database.passwordFile = "/run/keys/db_password"; +}; +``` diff --git a/nixos/modules/services/web-apps/keycloak.xml b/nixos/modules/services/web-apps/keycloak.xml index 861756e33ac09..148782d30f39e 100644 --- a/nixos/modules/services/web-apps/keycloak.xml +++ b/nixos/modules/services/web-apps/keycloak.xml @@ -1,202 +1,177 @@ -<chapter xmlns="http://docbook.org/ns/docbook" - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:xi="http://www.w3.org/2001/XInclude" - version="5.0" - xml:id="module-services-keycloak"> - <title>Keycloak</title> - <para> - <link xlink:href="https://www.keycloak.org/">Keycloak</link> is an - open source identity and access management server with support for - <link xlink:href="https://openid.net/connect/">OpenID - Connect</link>, <link xlink:href="https://oauth.net/2/">OAUTH - 2.0</link> and <link - xlink:href="https://en.wikipedia.org/wiki/SAML_2.0">SAML - 2.0</link>. - </para> - <section xml:id="module-services-keycloak-admin"> - <title>Administration</title> - <para> - An administrative user with the username - <literal>admin</literal> is automatically created in the - <literal>master</literal> realm. Its initial password can be - configured by setting <xref linkend="opt-services.keycloak.initialAdminPassword" /> - and defaults to <literal>changeme</literal>. The password is - not stored safely and should be changed immediately in the - admin panel. - </para> - - <para> - Refer to the <link - xlink:href="https://www.keycloak.org/docs/latest/server_admin/index.html"> - Keycloak Server Administration Guide</link> for information on - how to administer your <productname>Keycloak</productname> - instance. - </para> - </section> - - <section xml:id="module-services-keycloak-database"> - <title>Database access</title> - <para> - <productname>Keycloak</productname> can be used with either - <productname>PostgreSQL</productname>, - <productname>MariaDB</productname> or - <productname>MySQL</productname>. Which one is used can be - configured in <xref - linkend="opt-services.keycloak.database.type" />. The selected - database will automatically be enabled and a database and role - created unless <xref - linkend="opt-services.keycloak.database.host" /> is changed - from its default of <literal>localhost</literal> or <xref - linkend="opt-services.keycloak.database.createLocally" /> is - set to <literal>false</literal>. - </para> - - <para> - External database access can also be configured by setting - <xref linkend="opt-services.keycloak.database.host" />, <xref - linkend="opt-services.keycloak.database.name" />, <xref - linkend="opt-services.keycloak.database.username" />, <xref - linkend="opt-services.keycloak.database.useSSL" /> and <xref - linkend="opt-services.keycloak.database.caCert" /> as - appropriate. Note that you need to manually create the database - and allow the configured database user full access to it. - </para> - - <para> - <xref linkend="opt-services.keycloak.database.passwordFile" /> - must be set to the path to a file containing the password used - to log in to the database. If <xref linkend="opt-services.keycloak.database.host" /> - and <xref linkend="opt-services.keycloak.database.createLocally" /> - are kept at their defaults, the database role - <literal>keycloak</literal> with that password is provisioned - on the local database instance. - </para> - - <warning> - <para> - The path should be provided as a string, not a Nix path, since Nix - paths are copied into the world readable Nix store. - </para> - </warning> - </section> - - <section xml:id="module-services-keycloak-hostname"> - <title>Hostname</title> - <para> - The hostname is used to build the public URL used as base for - all frontend requests and must be configured through <xref - linkend="opt-services.keycloak.settings.hostname" />. - </para> - - <note> - <para> - If you're migrating an old Wildfly based Keycloak instance - and want to keep compatibility with your current clients, - you'll likely want to set <xref - linkend="opt-services.keycloak.settings.http-relative-path" - /> to <literal>/auth</literal>. See the option description - for more details. - </para> - </note> - - <para> - <xref linkend="opt-services.keycloak.settings.hostname-strict-backchannel" /> - determines whether Keycloak should force all requests to go - through the frontend URL. By default, - <productname>Keycloak</productname> allows backend requests to - instead use its local hostname or IP address and may also - advertise it to clients through its OpenID Connect Discovery - endpoint. - </para> - - <para> - For more information on hostname configuration, see the <link - xlink:href="https://www.keycloak.org/server/hostname">Hostname - section of the Keycloak Server Installation and Configuration - Guide</link>. - </para> - </section> - - <section xml:id="module-services-keycloak-tls"> - <title>Setting up TLS/SSL</title> - <para> - By default, <productname>Keycloak</productname> won't accept - unsecured HTTP connections originating from outside its local - network. - </para> - - <para> - HTTPS support requires a TLS/SSL certificate and a private key, - both <link - xlink:href="https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail">PEM - formatted</link>. Their paths should be set through <xref - linkend="opt-services.keycloak.sslCertificate" /> and <xref - linkend="opt-services.keycloak.sslCertificateKey" />. - </para> - - <warning> - <para> - The paths should be provided as a strings, not a Nix paths, - since Nix paths are copied into the world readable Nix store. - </para> - </warning> - </section> - - <section xml:id="module-services-keycloak-themes"> - <title>Themes</title> - <para> - You can package custom themes and make them visible to - Keycloak through <xref linkend="opt-services.keycloak.themes" - />. See the <link - xlink:href="https://www.keycloak.org/docs/latest/server_development/#_themes"> - Themes section of the Keycloak Server Development Guide</link> - and the description of the aforementioned NixOS option for - more information. - </para> - </section> - - <section xml:id="module-services-keycloak-settings"> - <title>Configuration file settings</title> - <para> - Keycloak server configuration parameters can be set in <xref - linkend="opt-services.keycloak.settings" />. These correspond - directly to options in - <filename>conf/keycloak.conf</filename>. Some of the most - important parameters are documented as suboptions, the rest can - be found in the <link - xlink:href="https://www.keycloak.org/server/all-config">All - configuration section of the Keycloak Server Installation and - Configuration Guide</link>. - </para> - - <para> - Options 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 description of <xref - linkend="opt-services.keycloak.settings" /> for an example. - </para> - </section> - - - <section xml:id="module-services-keycloak-example-config"> - <title>Example configuration</title> - <para> - A basic configuration with some custom settings could look like this: -<programlisting> +<!-- Do not edit this file directly, edit its companion .md instead + and regenerate this file using nixos/doc/manual/md-to-db.sh --> +<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-keycloak"> + <title>Keycloak</title> + <para> + <link xlink:href="https://www.keycloak.org/">Keycloak</link> is an + open source identity and access management server with support for + <link xlink:href="https://openid.net/connect/">OpenID + Connect</link>, <link xlink:href="https://oauth.net/2/">OAUTH + 2.0</link> and + <link xlink:href="https://en.wikipedia.org/wiki/SAML_2.0">SAML + 2.0</link>. + </para> + <section xml:id="module-services-keycloak-admin"> + <title>Administration</title> + <para> + An administrative user with the username <literal>admin</literal> + is automatically created in the <literal>master</literal> realm. + Its initial password can be configured by setting + <xref linkend="opt-services.keycloak.initialAdminPassword" /> and + defaults to <literal>changeme</literal>. The password is not + stored safely and should be changed immediately in the admin + panel. + </para> + <para> + Refer to the + <link xlink:href="https://www.keycloak.org/docs/latest/server_admin/index.html">Keycloak + Server Administration Guide</link> for information on how to + administer your Keycloak instance. + </para> + </section> + <section xml:id="module-services-keycloak-database"> + <title>Database access</title> + <para> + Keycloak can be used with either PostgreSQL, MariaDB or MySQL. + Which one is used can be configured in + <xref linkend="opt-services.keycloak.database.type" />. The + selected database will automatically be enabled and a database and + role created unless + <xref linkend="opt-services.keycloak.database.host" /> is changed + from its default of <literal>localhost</literal> or + <xref linkend="opt-services.keycloak.database.createLocally" /> is + set to <literal>false</literal>. + </para> + <para> + External database access can also be configured by setting + <xref linkend="opt-services.keycloak.database.host" />, + <xref linkend="opt-services.keycloak.database.name" />, + <xref linkend="opt-services.keycloak.database.username" />, + <xref linkend="opt-services.keycloak.database.useSSL" /> and + <xref linkend="opt-services.keycloak.database.caCert" /> as + appropriate. Note that you need to manually create the database + and allow the configured database user full access to it. + </para> + <para> + <xref linkend="opt-services.keycloak.database.passwordFile" /> + must be set to the path to a file containing the password used to + log in to the database. If + <xref linkend="opt-services.keycloak.database.host" /> and + <xref linkend="opt-services.keycloak.database.createLocally" /> + are kept at their defaults, the database role + <literal>keycloak</literal> with that password is provisioned on + the local database instance. + </para> + <warning> + <para> + The path should be provided as a string, not a Nix path, since + Nix paths are copied into the world readable Nix store. + </para> + </warning> + </section> + <section xml:id="module-services-keycloak-hostname"> + <title>Hostname</title> + <para> + The hostname is used to build the public URL used as base for all + frontend requests and must be configured through + <xref linkend="opt-services.keycloak.settings.hostname" />. + </para> + <note> + <para> + If you’re migrating an old Wildfly based Keycloak instance and + want to keep compatibility with your current clients, you’ll + likely want to set + <xref linkend="opt-services.keycloak.settings.http-relative-path" /> + to <literal>/auth</literal>. See the option description for more + details. + </para> + </note> + <para> + <xref linkend="opt-services.keycloak.settings.hostname-strict-backchannel" /> + determines whether Keycloak should force all requests to go + through the frontend URL. By default, Keycloak allows backend + requests to instead use its local hostname or IP address and may + also advertise it to clients through its OpenID Connect Discovery + endpoint. + </para> + <para> + For more information on hostname configuration, see the + <link xlink:href="https://www.keycloak.org/server/hostname">Hostname + section of the Keycloak Server Installation and Configuration + Guide</link>. + </para> + </section> + <section xml:id="module-services-keycloak-tls"> + <title>Setting up TLS/SSL</title> + <para> + By default, Keycloak won’t accept unsecured HTTP connections + originating from outside its local network. + </para> + <para> + HTTPS support requires a TLS/SSL certificate and a private key, + both + <link xlink:href="https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail">PEM + formatted</link>. Their paths should be set through + <xref linkend="opt-services.keycloak.sslCertificate" /> and + <xref linkend="opt-services.keycloak.sslCertificateKey" />. + </para> + <warning> + <para> + The paths should be provided as a strings, not a Nix paths, + since Nix paths are copied into the world readable Nix store. + </para> + </warning> + </section> + <section xml:id="module-services-keycloak-themes"> + <title>Themes</title> + <para> + You can package custom themes and make them visible to Keycloak + through <xref linkend="opt-services.keycloak.themes" />. See the + <link xlink:href="https://www.keycloak.org/docs/latest/server_development/#_themes">Themes + section of the Keycloak Server Development Guide</link> and the + description of the aforementioned NixOS option for more + information. + </para> + </section> + <section xml:id="module-services-keycloak-settings"> + <title>Configuration file settings</title> + <para> + Keycloak server configuration parameters can be set in + <xref linkend="opt-services.keycloak.settings" />. These + correspond directly to options in + <filename>conf/keycloak.conf</filename>. Some of the most + important parameters are documented as suboptions, the rest can be + found in the + <link xlink:href="https://www.keycloak.org/server/all-config">All + configuration section of the Keycloak Server Installation and + Configuration Guide</link>. + </para> + <para> + Options 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 description of + <xref linkend="opt-services.keycloak.settings" /> for an example. + </para> + </section> + <section xml:id="module-services-keycloak-example-config"> + <title>Example configuration</title> + <para> + A basic configuration with some custom settings could look like + this: + </para> + <programlisting> services.keycloak = { - <link linkend="opt-services.keycloak.enable">enable</link> = true; + enable = true; settings = { - <link linkend="opt-services.keycloak.settings.hostname">hostname</link> = "keycloak.example.com"; - <link linkend="opt-services.keycloak.settings.hostname-strict-backchannel">hostname-strict-backchannel</link> = true; + hostname = "keycloak.example.com"; + hostname-strict-backchannel = true; }; - <link linkend="opt-services.keycloak.initialAdminPassword">initialAdminPassword</link> = "e6Wcm0RrtegMEHl"; # change on first login - <link linkend="opt-services.keycloak.sslCertificate">sslCertificate</link> = "/run/keys/ssl_cert"; - <link linkend="opt-services.keycloak.sslCertificateKey">sslCertificateKey</link> = "/run/keys/ssl_key"; - <link linkend="opt-services.keycloak.database.passwordFile">database.passwordFile</link> = "/run/keys/db_password"; + initialAdminPassword = "e6Wcm0RrtegMEHl"; # change on first login + sslCertificate = "/run/keys/ssl_cert"; + sslCertificateKey = "/run/keys/ssl_key"; + database.passwordFile = "/run/keys/db_password"; }; </programlisting> - </para> - - </section> - </chapter> + </section> +</chapter> diff --git a/nixos/modules/services/web-apps/lemmy.nix b/nixos/modules/services/web-apps/lemmy.nix index 267584dd0ca7f..f2eb6e726b903 100644 --- a/nixos/modules/services/web-apps/lemmy.nix +++ b/nixos/modules/services/web-apps/lemmy.nix @@ -6,8 +6,6 @@ let in { meta.maintainers = with maintainers; [ happysalada ]; - # Don't edit the docbook xml directly, edit the md and generate it: - # `pandoc lemmy.md -t docbook --top-level-division=chapter --extract-media=media -f markdown+smart > lemmy.xml` meta.doc = ./lemmy.xml; imports = [ diff --git a/nixos/modules/services/web-apps/lemmy.xml b/nixos/modules/services/web-apps/lemmy.xml index f04316b3c5159..114e11f3488ad 100644 --- a/nixos/modules/services/web-apps/lemmy.xml +++ b/nixos/modules/services/web-apps/lemmy.xml @@ -1,3 +1,5 @@ +<!-- Do not edit this file directly, edit its companion .md instead + and regenerate this file using nixos/doc/manual/md-to-db.sh --> <chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-lemmy"> <title>Lemmy</title> <para> diff --git a/nixos/modules/services/web-apps/matomo-doc.xml b/nixos/modules/services/web-apps/matomo-doc.xml deleted file mode 100644 index 69d1170e4523b..0000000000000 --- a/nixos/modules/services/web-apps/matomo-doc.xml +++ /dev/null @@ -1,107 +0,0 @@ -<chapter xmlns="http://docbook.org/ns/docbook" - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:xi="http://www.w3.org/2001/XInclude" - version="5.0" - xml:id="module-services-matomo"> - <title>Matomo</title> - <para> - Matomo is a real-time web analytics application. This module configures - php-fpm as backend for Matomo, optionally configuring an nginx vhost as well. - </para> - <para> - An automatic setup is not suported by Matomo, so you need to configure Matomo - itself in the browser-based Matomo setup. - </para> - <section xml:id="module-services-matomo-database-setup"> - <title>Database Setup</title> - - <para> - You also need to configure a MariaDB or MySQL database and -user for Matomo - yourself, and enter those credentials in your browser. You can use - passwordless database authentication via the UNIX_SOCKET authentication - plugin with the following SQL commands: -<programlisting> -# For MariaDB -INSTALL PLUGIN unix_socket SONAME 'auth_socket'; -CREATE DATABASE matomo; -CREATE USER 'matomo'@'localhost' IDENTIFIED WITH unix_socket; -GRANT ALL PRIVILEGES ON matomo.* TO 'matomo'@'localhost'; - -# For MySQL -INSTALL PLUGIN auth_socket SONAME 'auth_socket.so'; -CREATE DATABASE matomo; -CREATE USER 'matomo'@'localhost' IDENTIFIED WITH auth_socket; -GRANT ALL PRIVILEGES ON matomo.* TO 'matomo'@'localhost'; -</programlisting> - Then fill in <literal>matomo</literal> as database user and database name, - and leave the password field blank. This authentication works by allowing - only the <literal>matomo</literal> unix user to authenticate as the - <literal>matomo</literal> database user (without needing a password), but no - other users. For more information on passwordless login, see - <link xlink:href="https://mariadb.com/kb/en/mariadb/unix_socket-authentication-plugin/" />. - </para> - - <para> - Of course, you can use password based authentication as well, e.g. when the - database is not on the same host. - </para> - </section> - <section xml:id="module-services-matomo-archive-processing"> - <title>Archive Processing</title> - - <para> - This module comes with the systemd service - <literal>matomo-archive-processing.service</literal> and a timer that - automatically triggers archive processing every hour. This means that you - can safely - <link xlink:href="https://matomo.org/docs/setup-auto-archiving/#disable-browser-triggers-for-matomo-archiving-and-limit-matomo-reports-to-updating-every-hour"> - disable browser triggers for Matomo archiving </link> at - <literal>Administration > System > General Settings</literal>. - </para> - - <para> - With automatic archive processing, you can now also enable to - <link xlink:href="https://matomo.org/docs/privacy/#step-2-delete-old-visitors-logs"> - delete old visitor logs </link> at <literal>Administration > System > - Privacy</literal>, but make sure that you run <literal>systemctl start - matomo-archive-processing.service</literal> at least once without errors if - you have already collected data before, so that the reports get archived - before the source data gets deleted. - </para> - </section> - <section xml:id="module-services-matomo-backups"> - <title>Backup</title> - - <para> - You only need to take backups of your MySQL database and the - <filename>/var/lib/matomo/config/config.ini.php</filename> file. Use a user - in the <literal>matomo</literal> group or root to access the file. For more - information, see - <link xlink:href="https://matomo.org/faq/how-to-install/faq_138/" />. - </para> - </section> - <section xml:id="module-services-matomo-issues"> - <title>Issues</title> - - <itemizedlist> - <listitem> - <para> - Matomo will warn you that the JavaScript tracker is not writable. This is - because it's located in the read-only nix store. You can safely ignore - this, unless you need a plugin that needs JavaScript tracker access. - </para> - </listitem> - </itemizedlist> - </section> - <section xml:id="module-services-matomo-other-web-servers"> - <title>Using other Web Servers than nginx</title> - - <para> - You can use other web servers by forwarding calls for - <filename>index.php</filename> and <filename>piwik.php</filename> to the - <literal><link linkend="opt-services.phpfpm.pools._name_.socket">services.phpfpm.pools.<name>.socket</link></literal> fastcgi unix socket. You can use - the nginx configuration in the module code as a reference to what else - should be configured. - </para> - </section> -</chapter> diff --git a/nixos/modules/services/web-apps/matomo.md b/nixos/modules/services/web-apps/matomo.md new file mode 100644 index 0000000000000..f5536a35f7a89 --- /dev/null +++ b/nixos/modules/services/web-apps/matomo.md @@ -0,0 +1,77 @@ +# Matomo {#module-services-matomo} + +Matomo is a real-time web analytics application. This module configures +php-fpm as backend for Matomo, optionally configuring an nginx vhost as well. + +An automatic setup is not suported by Matomo, so you need to configure Matomo +itself in the browser-based Matomo setup. + +## Database Setup {#module-services-matomo-database-setup} + +You also need to configure a MariaDB or MySQL database and -user for Matomo +yourself, and enter those credentials in your browser. You can use +passwordless database authentication via the UNIX_SOCKET authentication +plugin with the following SQL commands: +``` +# For MariaDB +INSTALL PLUGIN unix_socket SONAME 'auth_socket'; +CREATE DATABASE matomo; +CREATE USER 'matomo'@'localhost' IDENTIFIED WITH unix_socket; +GRANT ALL PRIVILEGES ON matomo.* TO 'matomo'@'localhost'; + +# For MySQL +INSTALL PLUGIN auth_socket SONAME 'auth_socket.so'; +CREATE DATABASE matomo; +CREATE USER 'matomo'@'localhost' IDENTIFIED WITH auth_socket; +GRANT ALL PRIVILEGES ON matomo.* TO 'matomo'@'localhost'; +``` +Then fill in `matomo` as database user and database name, +and leave the password field blank. This authentication works by allowing +only the `matomo` unix user to authenticate as the +`matomo` database user (without needing a password), but no +other users. For more information on passwordless login, see +<https://mariadb.com/kb/en/mariadb/unix_socket-authentication-plugin/>. + +Of course, you can use password based authentication as well, e.g. when the +database is not on the same host. + +## Archive Processing {#module-services-matomo-archive-processing} + +This module comes with the systemd service +`matomo-archive-processing.service` and a timer that +automatically triggers archive processing every hour. This means that you +can safely +[disable browser triggers for Matomo archiving]( +https://matomo.org/docs/setup-auto-archiving/#disable-browser-triggers-for-matomo-archiving-and-limit-matomo-reports-to-updating-every-hour +) at +`Administration > System > General Settings`. + +With automatic archive processing, you can now also enable to +[delete old visitor logs](https://matomo.org/docs/privacy/#step-2-delete-old-visitors-logs) +at `Administration > System > Privacy`, but make sure that you run `systemctl start +matomo-archive-processing.service` at least once without errors if +you have already collected data before, so that the reports get archived +before the source data gets deleted. + +## Backup {#module-services-matomo-backups} + +You only need to take backups of your MySQL database and the +{file}`/var/lib/matomo/config/config.ini.php` file. Use a user +in the `matomo` group or root to access the file. For more +information, see +<https://matomo.org/faq/how-to-install/faq_138/>. + +## Issues {#module-services-matomo-issues} + + - Matomo will warn you that the JavaScript tracker is not writable. This is + because it's located in the read-only nix store. You can safely ignore + this, unless you need a plugin that needs JavaScript tracker access. + +## Using other Web Servers than nginx {#module-services-matomo-other-web-servers} + +You can use other web servers by forwarding calls for +{file}`index.php` and {file}`piwik.php` to the +[`services.phpfpm.pools.<name>.socket`](#opt-services.phpfpm.pools._name_.socket) +fastcgi unix socket. You can use +the nginx configuration in the module code as a reference to what else +should be configured. diff --git a/nixos/modules/services/web-apps/matomo.nix b/nixos/modules/services/web-apps/matomo.nix index 0435d21ce8a2b..9845106599527 100644 --- a/nixos/modules/services/web-apps/matomo.nix +++ b/nixos/modules/services/web-apps/matomo.nix @@ -325,7 +325,7 @@ in { }; meta = { - doc = ./matomo-doc.xml; + doc = ./matomo.xml; maintainers = with lib.maintainers; [ florianjacob ]; }; } diff --git a/nixos/modules/services/web-apps/matomo.xml b/nixos/modules/services/web-apps/matomo.xml new file mode 100644 index 0000000000000..30994cc9f1dad --- /dev/null +++ b/nixos/modules/services/web-apps/matomo.xml @@ -0,0 +1,107 @@ +<!-- Do not edit this file directly, edit its companion .md instead + and regenerate this file using nixos/doc/manual/md-to-db.sh --> +<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-matomo"> + <title>Matomo</title> + <para> + Matomo is a real-time web analytics application. This module + configures php-fpm as backend for Matomo, optionally configuring an + nginx vhost as well. + </para> + <para> + An automatic setup is not suported by Matomo, so you need to + configure Matomo itself in the browser-based Matomo setup. + </para> + <section xml:id="module-services-matomo-database-setup"> + <title>Database Setup</title> + <para> + You also need to configure a MariaDB or MySQL database and -user + for Matomo yourself, and enter those credentials in your browser. + You can use passwordless database authentication via the + UNIX_SOCKET authentication plugin with the following SQL commands: + </para> + <programlisting> +# For MariaDB +INSTALL PLUGIN unix_socket SONAME 'auth_socket'; +CREATE DATABASE matomo; +CREATE USER 'matomo'@'localhost' IDENTIFIED WITH unix_socket; +GRANT ALL PRIVILEGES ON matomo.* TO 'matomo'@'localhost'; + +# For MySQL +INSTALL PLUGIN auth_socket SONAME 'auth_socket.so'; +CREATE DATABASE matomo; +CREATE USER 'matomo'@'localhost' IDENTIFIED WITH auth_socket; +GRANT ALL PRIVILEGES ON matomo.* TO 'matomo'@'localhost'; +</programlisting> + <para> + Then fill in <literal>matomo</literal> as database user and + database name, and leave the password field blank. This + authentication works by allowing only the + <literal>matomo</literal> unix user to authenticate as the + <literal>matomo</literal> database user (without needing a + password), but no other users. For more information on + passwordless login, see + <link xlink:href="https://mariadb.com/kb/en/mariadb/unix_socket-authentication-plugin/">https://mariadb.com/kb/en/mariadb/unix_socket-authentication-plugin/</link>. + </para> + <para> + Of course, you can use password based authentication as well, e.g. + when the database is not on the same host. + </para> + </section> + <section xml:id="module-services-matomo-archive-processing"> + <title>Archive Processing</title> + <para> + This module comes with the systemd service + <literal>matomo-archive-processing.service</literal> and a timer + that automatically triggers archive processing every hour. This + means that you can safely + <link xlink:href="https://matomo.org/docs/setup-auto-archiving/#disable-browser-triggers-for-matomo-archiving-and-limit-matomo-reports-to-updating-every-hour">disable + browser triggers for Matomo archiving</link> at + <literal>Administration > System > General Settings</literal>. + </para> + <para> + With automatic archive processing, you can now also enable to + <link xlink:href="https://matomo.org/docs/privacy/#step-2-delete-old-visitors-logs">delete + old visitor logs</link> at + <literal>Administration > System > Privacy</literal>, but + make sure that you run + <literal>systemctl start matomo-archive-processing.service</literal> + at least once without errors if you have already collected data + before, so that the reports get archived before the source data + gets deleted. + </para> + </section> + <section xml:id="module-services-matomo-backups"> + <title>Backup</title> + <para> + You only need to take backups of your MySQL database and the + <filename>/var/lib/matomo/config/config.ini.php</filename> file. + Use a user in the <literal>matomo</literal> group or root to + access the file. For more information, see + <link xlink:href="https://matomo.org/faq/how-to-install/faq_138/">https://matomo.org/faq/how-to-install/faq_138/</link>. + </para> + </section> + <section xml:id="module-services-matomo-issues"> + <title>Issues</title> + <itemizedlist spacing="compact"> + <listitem> + <para> + Matomo will warn you that the JavaScript tracker is not + writable. This is because it’s located in the read-only nix + store. You can safely ignore this, unless you need a plugin + that needs JavaScript tracker access. + </para> + </listitem> + </itemizedlist> + </section> + <section xml:id="module-services-matomo-other-web-servers"> + <title>Using other Web Servers than nginx</title> + <para> + You can use other web servers by forwarding calls for + <filename>index.php</filename> and <filename>piwik.php</filename> + to the + <link linkend="opt-services.phpfpm.pools._name_.socket"><literal>services.phpfpm.pools.<name>.socket</literal></link> + fastcgi unix socket. You can use the nginx configuration in the + module code as a reference to what else should be configured. + </para> + </section> +</chapter> diff --git a/nixos/modules/services/web-apps/nextcloud.md b/nixos/modules/services/web-apps/nextcloud.md new file mode 100644 index 0000000000000..014807f3da23c --- /dev/null +++ b/nixos/modules/services/web-apps/nextcloud.md @@ -0,0 +1,237 @@ +# Nextcloud {#module-services-nextcloud} + +[Nextcloud](https://nextcloud.com/) is an open-source, +self-hostable cloud platform. The server setup can be automated using +[services.nextcloud](#opt-services.nextcloud.enable). A +desktop client is packaged at `pkgs.nextcloud-client`. + +The current default by NixOS is `nextcloud25` which is also the latest +major version available. + +## Basic usage {#module-services-nextcloud-basic-usage} + +Nextcloud is a PHP-based application which requires an HTTP server +([`services.nextcloud`](#opt-services.nextcloud.enable) +optionally supports +[`services.nginx`](#opt-services.nginx.enable)) +and a database (it's recommended to use +[`services.postgresql`](#opt-services.postgresql.enable)). + +A very basic configuration may look like this: +``` +{ pkgs, ... }: +{ + services.nextcloud = { + enable = true; + hostName = "nextcloud.tld"; + config = { + dbtype = "pgsql"; + dbuser = "nextcloud"; + dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself + dbname = "nextcloud"; + adminpassFile = "/path/to/admin-pass-file"; + adminuser = "root"; + }; + }; + + services.postgresql = { + enable = true; + ensureDatabases = [ "nextcloud" ]; + ensureUsers = [ + { name = "nextcloud"; + ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES"; + } + ]; + }; + + # ensure that postgres is running *before* running the setup + systemd.services."nextcloud-setup" = { + requires = ["postgresql.service"]; + after = ["postgresql.service"]; + }; + + networking.firewall.allowedTCPPorts = [ 80 443 ]; +} +``` + +The `hostName` option is used internally to configure an HTTP +server using [`PHP-FPM`](https://php-fpm.org/) +and `nginx`. The `config` attribute set is +used by the imperative installer and all values are written to an additional file +to ensure that changes can be applied by changing the module's options. + +In case the application serves multiple domains (those are checked with +[`$_SERVER['HTTP_HOST']`](http://php.net/manual/en/reserved.variables.server.php)) +it's needed to add them to +[`services.nextcloud.config.extraTrustedDomains`](#opt-services.nextcloud.config.extraTrustedDomains). + +Auto updates for Nextcloud apps can be enabled using +[`services.nextcloud.autoUpdateApps`](#opt-services.nextcloud.autoUpdateApps.enable). + +## Common problems {#module-services-nextcloud-pitfalls-during-upgrade} + + - **General notes.** + Unfortunately Nextcloud appears to be very stateful when it comes to + managing its own configuration. The config file lives in the home directory + of the `nextcloud` user (by default + `/var/lib/nextcloud/config/config.php`) and is also used to + track several states of the application (e.g., whether installed or not). + + All configuration parameters are also stored in + {file}`/var/lib/nextcloud/config/override.config.php` which is generated by + the module and linked from the store to ensure that all values from + {file}`config.php` can be modified by the module. + However {file}`config.php` manages the application's state and shouldn't be + touched manually because of that. + + ::: {.warning} + Don't delete {file}`config.php`! This file + tracks the application's state and a deletion can cause unwanted + side-effects! + ::: + + ::: {.warning} + Don't rerun `nextcloud-occ maintenance:install`! + This command tries to install the application + and can cause unwanted side-effects! + ::: + - **Multiple version upgrades.** + Nextcloud doesn't allow to move more than one major-version forward. E.g., if you're on + `v16`, you cannot upgrade to `v18`, you need to upgrade to + `v17` first. This is ensured automatically as long as the + [stateVersion](#opt-system.stateVersion) is declared properly. In that case + the oldest version available (one major behind the one from the previous NixOS + release) will be selected by default and the module will generate a warning that reminds + the user to upgrade to latest Nextcloud *after* that deploy. + - **`Error: Command "upgrade" is not defined.`** + This error usually occurs if the initial installation + ({command}`nextcloud-occ maintenance:install`) has failed. After that, the application + is not installed, but the upgrade is attempted to be executed. Further context can + be found in [NixOS/nixpkgs#111175](https://github.com/NixOS/nixpkgs/issues/111175). + + First of all, it makes sense to find out what went wrong by looking at the logs + of the installation via {command}`journalctl -u nextcloud-setup` and try to fix + the underlying issue. + + - If this occurs on an *existing* setup, this is most likely because + the maintenance mode is active. It can be deactivated by running + {command}`nextcloud-occ maintenance:mode --off`. It's advisable though to + check the logs first on why the maintenance mode was activated. + - ::: {.warning} + Only perform the following measures on + *freshly installed instances!* + ::: + + A re-run of the installer can be forced by *deleting* + {file}`/var/lib/nextcloud/config/config.php`. This is the only time + advisable because the fresh install doesn't have any state that can be lost. + In case that doesn't help, an entire re-creation can be forced via + {command}`rm -rf ~nextcloud/`. + + - **Server-side encryption.** + Nextcloud supports [server-side encryption (SSE)](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html). + This is not an end-to-end encryption, but can be used to encrypt files that will be persisted + to external storage such as S3. Please note that this won't work anymore when using OpenSSL 3 + for PHP's openssl extension because this is implemented using the legacy cipher RC4. + If [](#opt-system.stateVersion) is *above* `22.05`, + this is disabled by default. To turn it on again and for further information please refer to + [](#opt-services.nextcloud.enableBrokenCiphersForSSE). + +## Using an alternative webserver as reverse-proxy (e.g. `httpd`) {#module-services-nextcloud-httpd} + +By default, `nginx` is used as reverse-proxy for `nextcloud`. +However, it's possible to use e.g. `httpd` by explicitly disabling +`nginx` using [](#opt-services.nginx.enable) and fixing the +settings `listen.owner` & `listen.group` in the +[corresponding `phpfpm` pool](#opt-services.phpfpm.pools). + +An exemplary configuration may look like this: +``` +{ config, lib, pkgs, ... }: { + services.nginx.enable = false; + services.nextcloud = { + enable = true; + hostName = "localhost"; + + /* further, required options */ + }; + services.phpfpm.pools.nextcloud.settings = { + "listen.owner" = config.services.httpd.user; + "listen.group" = config.services.httpd.group; + }; + services.httpd = { + enable = true; + adminAddr = "webmaster@localhost"; + extraModules = [ "proxy_fcgi" ]; + virtualHosts."localhost" = { + documentRoot = config.services.nextcloud.package; + extraConfig = '' + <Directory "${config.services.nextcloud.package}"> + <FilesMatch "\.php$"> + <If "-f %{REQUEST_FILENAME}"> + SetHandler "proxy:unix:${config.services.phpfpm.pools.nextcloud.socket}|fcgi://localhost/" + </If> + </FilesMatch> + <IfModule mod_rewrite.c> + RewriteEngine On + RewriteBase / + RewriteRule ^index\.php$ - [L] + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule . /index.php [L] + </IfModule> + DirectoryIndex index.php + Require all granted + Options +FollowSymLinks + </Directory> + ''; + }; + }; +} +``` + +## Installing Apps and PHP extensions {#installing-apps-php-extensions-nextcloud} + +Nextcloud apps are installed statefully through the web interface. +Some apps may require extra PHP extensions to be installed. +This can be configured with the [](#opt-services.nextcloud.phpExtraExtensions) setting. + +Alternatively, extra apps can also be declared with the [](#opt-services.nextcloud.extraApps) setting. +When using this setting, apps can no longer be managed statefully because this can lead to Nextcloud updating apps +that are managed by Nix. If you want automatic updates it is recommended that you use web interface to install apps. + +## Maintainer information {#module-services-nextcloud-maintainer-info} + +As stated in the previous paragraph, we must provide a clean upgrade-path for Nextcloud +since it cannot move more than one major version forward on a single upgrade. This chapter +adds some notes how Nextcloud updates should be rolled out in the future. + +While minor and patch-level updates are no problem and can be done directly in the +package-expression (and should be backported to supported stable branches after that), +major-releases should be added in a new attribute (e.g. Nextcloud `v19.0.0` +should be available in `nixpkgs` as `pkgs.nextcloud19`). +To provide simple upgrade paths it's generally useful to backport those as well to stable +branches. As long as the package-default isn't altered, this won't break existing setups. +After that, the versioning-warning in the `nextcloud`-module should be +updated to make sure that the +[package](#opt-services.nextcloud.package)-option selects the latest version +on fresh setups. + +If major-releases will be abandoned by upstream, we should check first if those are needed +in NixOS for a safe upgrade-path before removing those. In that case we should keep those +packages, but mark them as insecure in an expression like this (in +`<nixpkgs/pkgs/servers/nextcloud/default.nix>`): +``` +/* ... */ +{ + nextcloud17 = generic { + version = "17.0.x"; + sha256 = "0000000000000000000000000000000000000000000000000000"; + eol = true; + }; +} +``` + +Ideally we should make sure that it's possible to jump two NixOS versions forward: +i.e. the warnings and the logic in the module should guard a user to upgrade from a +Nextcloud on e.g. 19.09 to a Nextcloud on 20.09. diff --git a/nixos/modules/services/web-apps/nextcloud.xml b/nixos/modules/services/web-apps/nextcloud.xml index 4207c4008d5b7..a5ac05723ef47 100644 --- a/nixos/modules/services/web-apps/nextcloud.xml +++ b/nixos/modules/services/web-apps/nextcloud.xml @@ -1,226 +1,249 @@ -<chapter xmlns="http://docbook.org/ns/docbook" - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:xi="http://www.w3.org/2001/XInclude" - version="5.0" - xml:id="module-services-nextcloud"> - <title>Nextcloud</title> - <para> - <link xlink:href="https://nextcloud.com/">Nextcloud</link> is an open-source, - self-hostable cloud platform. The server setup can be automated using - <link linkend="opt-services.nextcloud.enable">services.nextcloud</link>. A - desktop client is packaged at <literal>pkgs.nextcloud-client</literal>. - </para> - <para> - The current default by NixOS is <package>nextcloud25</package> which is also the latest - major version available. - </para> - <section xml:id="module-services-nextcloud-basic-usage"> - <title>Basic usage</title> - +<!-- Do not edit this file directly, edit its companion .md instead + and regenerate this file using nixos/doc/manual/md-to-db.sh --> +<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-nextcloud"> + <title>Nextcloud</title> <para> - Nextcloud is a PHP-based application which requires an HTTP server - (<literal><link linkend="opt-services.nextcloud.enable">services.nextcloud</link></literal> - optionally supports - <literal><link linkend="opt-services.nginx.enable">services.nginx</link></literal>) - and a database (it's recommended to use - <literal><link linkend="opt-services.postgresql.enable">services.postgresql</link></literal>). + <link xlink:href="https://nextcloud.com/">Nextcloud</link> is an + open-source, self-hostable cloud platform. The server setup can be + automated using + <link linkend="opt-services.nextcloud.enable">services.nextcloud</link>. + A desktop client is packaged at + <literal>pkgs.nextcloud-client</literal>. </para> - <para> - A very basic configuration may look like this: -<programlisting>{ pkgs, ... }: + The current default by NixOS is <literal>nextcloud25</literal> which + is also the latest major version available. + </para> + <section xml:id="module-services-nextcloud-basic-usage"> + <title>Basic usage</title> + <para> + Nextcloud is a PHP-based application which requires an HTTP server + (<link linkend="opt-services.nextcloud.enable"><literal>services.nextcloud</literal></link> + optionally supports + <link linkend="opt-services.nginx.enable"><literal>services.nginx</literal></link>) + and a database (it’s recommended to use + <link linkend="opt-services.postgresql.enable"><literal>services.postgresql</literal></link>). + </para> + <para> + A very basic configuration may look like this: + </para> + <programlisting> +{ pkgs, ... }: { services.nextcloud = { - <link linkend="opt-services.nextcloud.enable">enable</link> = true; - <link linkend="opt-services.nextcloud.hostName">hostName</link> = "nextcloud.tld"; + enable = true; + hostName = "nextcloud.tld"; config = { - <link linkend="opt-services.nextcloud.config.dbtype">dbtype</link> = "pgsql"; - <link linkend="opt-services.nextcloud.config.dbuser">dbuser</link> = "nextcloud"; - <link linkend="opt-services.nextcloud.config.dbhost">dbhost</link> = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself - <link linkend="opt-services.nextcloud.config.dbname">dbname</link> = "nextcloud"; - <link linkend="opt-services.nextcloud.config.adminpassFile">adminpassFile</link> = "/path/to/admin-pass-file"; - <link linkend="opt-services.nextcloud.config.adminuser">adminuser</link> = "root"; + dbtype = "pgsql"; + dbuser = "nextcloud"; + dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself + dbname = "nextcloud"; + adminpassFile = "/path/to/admin-pass-file"; + adminuser = "root"; }; }; services.postgresql = { - <link linkend="opt-services.postgresql.enable">enable</link> = true; - <link linkend="opt-services.postgresql.ensureDatabases">ensureDatabases</link> = [ "nextcloud" ]; - <link linkend="opt-services.postgresql.ensureUsers">ensureUsers</link> = [ - { name = "nextcloud"; - ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES"; + enable = true; + ensureDatabases = [ "nextcloud" ]; + ensureUsers = [ + { name = "nextcloud"; + ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES"; } ]; }; # ensure that postgres is running *before* running the setup - systemd.services."nextcloud-setup" = { - requires = ["postgresql.service"]; - after = ["postgresql.service"]; + systemd.services."nextcloud-setup" = { + requires = ["postgresql.service"]; + after = ["postgresql.service"]; }; - <link linkend="opt-networking.firewall.allowedTCPPorts">networking.firewall.allowedTCPPorts</link> = [ 80 443 ]; -}</programlisting> - </para> - - <para> - The <literal>hostName</literal> option is used internally to configure an HTTP - server using <literal><link xlink:href="https://php-fpm.org/">PHP-FPM</link></literal> - and <literal>nginx</literal>. The <literal>config</literal> attribute set is - used by the imperative installer and all values are written to an additional file - to ensure that changes can be applied by changing the module's options. - </para> - - <para> - In case the application serves multiple domains (those are checked with - <literal><link xlink:href="http://php.net/manual/en/reserved.variables.server.php">$_SERVER['HTTP_HOST']</link></literal>) - it's needed to add them to - <literal><link linkend="opt-services.nextcloud.config.extraTrustedDomains">services.nextcloud.config.extraTrustedDomains</link></literal>. - </para> - - <para> - Auto updates for Nextcloud apps can be enabled using - <literal><link linkend="opt-services.nextcloud.autoUpdateApps.enable">services.nextcloud.autoUpdateApps</link></literal>. -</para> - - </section> - - <section xml:id="module-services-nextcloud-pitfalls-during-upgrade"> - <title>Common problems</title> - <itemizedlist> - <listitem> - <formalpara> - <title>General notes</title> - <para> - Unfortunately Nextcloud appears to be very stateful when it comes to - managing its own configuration. The config file lives in the home directory - of the <literal>nextcloud</literal> user (by default - <literal>/var/lib/nextcloud/config/config.php</literal>) and is also used to - track several states of the application (e.g., whether installed or not). - </para> - </formalpara> + networking.firewall.allowedTCPPorts = [ 80 443 ]; +} +</programlisting> <para> - All configuration parameters are also stored in - <filename>/var/lib/nextcloud/config/override.config.php</filename> which is generated by - the module and linked from the store to ensure that all values from - <filename>config.php</filename> can be modified by the module. - However <filename>config.php</filename> manages the application's state and shouldn't be - touched manually because of that. + The <literal>hostName</literal> option is used internally to + configure an HTTP server using + <link xlink:href="https://php-fpm.org/"><literal>PHP-FPM</literal></link> + and <literal>nginx</literal>. The <literal>config</literal> + attribute set is used by the imperative installer and all values + are written to an additional file to ensure that changes can be + applied by changing the module’s options. + </para> + <para> + In case the application serves multiple domains (those are checked + with + <link xlink:href="http://php.net/manual/en/reserved.variables.server.php"><literal>$_SERVER['HTTP_HOST']</literal></link>) + it’s needed to add them to + <link linkend="opt-services.nextcloud.config.extraTrustedDomains"><literal>services.nextcloud.config.extraTrustedDomains</literal></link>. </para> - <warning> - <para>Don't delete <filename>config.php</filename>! This file - tracks the application's state and a deletion can cause unwanted - side-effects!</para> - </warning> - - <warning> - <para>Don't rerun <literal>nextcloud-occ - maintenance:install</literal>! This command tries to install the application - and can cause unwanted side-effects!</para> - </warning> - </listitem> - <listitem> - <formalpara> - <title>Multiple version upgrades</title> - <para> - Nextcloud doesn't allow to move more than one major-version forward. E.g., if you're on - <literal>v16</literal>, you cannot upgrade to <literal>v18</literal>, you need to upgrade to - <literal>v17</literal> first. This is ensured automatically as long as the - <link linkend="opt-system.stateVersion">stateVersion</link> is declared properly. In that case - the oldest version available (one major behind the one from the previous NixOS - release) will be selected by default and the module will generate a warning that reminds - the user to upgrade to latest Nextcloud <emphasis>after</emphasis> that deploy. - </para> - </formalpara> - </listitem> - <listitem> - <formalpara> - <title><literal>Error: Command "upgrade" is not defined.</literal></title> - <para> - This error usually occurs if the initial installation - (<command>nextcloud-occ maintenance:install</command>) has failed. After that, the application - is not installed, but the upgrade is attempted to be executed. Further context can - be found in <link xlink:href="https://github.com/NixOS/nixpkgs/issues/111175">NixOS/nixpkgs#111175</link>. - </para> - </formalpara> <para> - First of all, it makes sense to find out what went wrong by looking at the logs - of the installation via <command>journalctl -u nextcloud-setup</command> and try to fix - the underlying issue. + Auto updates for Nextcloud apps can be enabled using + <link linkend="opt-services.nextcloud.autoUpdateApps.enable"><literal>services.nextcloud.autoUpdateApps</literal></link>. </para> + </section> + <section xml:id="module-services-nextcloud-pitfalls-during-upgrade"> + <title>Common problems</title> <itemizedlist> - <listitem> - <para> - If this occurs on an <emphasis>existing</emphasis> setup, this is most likely because - the maintenance mode is active. It can be deactivated by running - <command>nextcloud-occ maintenance:mode --off</command>. It's advisable though to - check the logs first on why the maintenance mode was activated. - </para> - </listitem> - <listitem> - <warning><para>Only perform the following measures on - <emphasis>freshly installed instances!</emphasis></para></warning> - <para> - A re-run of the installer can be forced by <emphasis>deleting</emphasis> - <filename>/var/lib/nextcloud/config/config.php</filename>. This is the only time - advisable because the fresh install doesn't have any state that can be lost. - In case that doesn't help, an entire re-creation can be forced via - <command>rm -rf ~nextcloud/</command>. - </para> - </listitem> + <listitem> + <para> + <emphasis role="strong">General notes.</emphasis> + Unfortunately Nextcloud appears to be very stateful when it + comes to managing its own configuration. The config file lives + in the home directory of the <literal>nextcloud</literal> user + (by default + <literal>/var/lib/nextcloud/config/config.php</literal>) and + is also used to track several states of the application (e.g., + whether installed or not). + </para> + <para> + All configuration parameters are also stored in + <filename>/var/lib/nextcloud/config/override.config.php</filename> + which is generated by the module and linked from the store to + ensure that all values from <filename>config.php</filename> + can be modified by the module. However + <filename>config.php</filename> manages the application’s + state and shouldn’t be touched manually because of that. + </para> + <warning> + <para> + Don’t delete <filename>config.php</filename>! This file + tracks the application’s state and a deletion can cause + unwanted side-effects! + </para> + </warning> + <warning> + <para> + Don’t rerun + <literal>nextcloud-occ maintenance:install</literal>! This + command tries to install the application and can cause + unwanted side-effects! + </para> + </warning> + </listitem> + <listitem> + <para> + <emphasis role="strong">Multiple version upgrades.</emphasis> + Nextcloud doesn’t allow to move more than one major-version + forward. E.g., if you’re on <literal>v16</literal>, you cannot + upgrade to <literal>v18</literal>, you need to upgrade to + <literal>v17</literal> first. This is ensured automatically as + long as the + <link linkend="opt-system.stateVersion">stateVersion</link> is + declared properly. In that case the oldest version available + (one major behind the one from the previous NixOS release) + will be selected by default and the module will generate a + warning that reminds the user to upgrade to latest Nextcloud + <emphasis>after</emphasis> that deploy. + </para> + </listitem> + <listitem> + <para> + <emphasis role="strong"><literal>Error: Command "upgrade" is not defined.</literal></emphasis> + This error usually occurs if the initial installation + (<command>nextcloud-occ maintenance:install</command>) has + failed. After that, the application is not installed, but the + upgrade is attempted to be executed. Further context can be + found in + <link xlink:href="https://github.com/NixOS/nixpkgs/issues/111175">NixOS/nixpkgs#111175</link>. + </para> + <para> + First of all, it makes sense to find out what went wrong by + looking at the logs of the installation via + <command>journalctl -u nextcloud-setup</command> and try to + fix the underlying issue. + </para> + <itemizedlist> + <listitem> + <para> + If this occurs on an <emphasis>existing</emphasis> setup, + this is most likely because the maintenance mode is + active. It can be deactivated by running + <command>nextcloud-occ maintenance:mode --off</command>. + It’s advisable though to check the logs first on why the + maintenance mode was activated. + </para> + </listitem> + <listitem> + <warning> + <para> + Only perform the following measures on <emphasis>freshly + installed instances!</emphasis> + </para> + </warning> + <para> + A re-run of the installer can be forced by + <emphasis>deleting</emphasis> + <filename>/var/lib/nextcloud/config/config.php</filename>. + This is the only time advisable because the fresh install + doesn’t have any state that can be lost. In case that + doesn’t help, an entire re-creation can be forced via + <command>rm -rf ~nextcloud/</command>. + </para> + </listitem> + </itemizedlist> + </listitem> + <listitem> + <para> + <emphasis role="strong">Server-side encryption.</emphasis> + Nextcloud supports + <link xlink:href="https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html">server-side + encryption (SSE)</link>. This is not an end-to-end encryption, + but can be used to encrypt files that will be persisted to + external storage such as S3. Please note that this won’t work + anymore when using OpenSSL 3 for PHP’s openssl extension + because this is implemented using the legacy cipher RC4. If + <xref linkend="opt-system.stateVersion" /> is + <emphasis>above</emphasis> <literal>22.05</literal>, this is + disabled by default. To turn it on again and for further + information please refer to + <xref linkend="opt-services.nextcloud.enableBrokenCiphersForSSE" />. + </para> + </listitem> </itemizedlist> - </listitem> - <listitem> - <formalpara> - <title>Server-side encryption</title> - <para> - Nextcloud supports <link xlink:href="https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html">server-side encryption (SSE)</link>. - This is not an end-to-end encryption, but can be used to encrypt files that will be persisted - to external storage such as S3. Please note that this won't work anymore when using OpenSSL 3 - for PHP's openssl extension because this is implemented using the legacy cipher RC4. - If <xref linkend="opt-system.stateVersion" /> is <emphasis>above</emphasis> <literal>22.05</literal>, - this is disabled by default. To turn it on again and for further information please refer to - <xref linkend="opt-services.nextcloud.enableBrokenCiphersForSSE" />. - </para> - </formalpara> - </listitem> - </itemizedlist> - </section> - - <section xml:id="module-services-nextcloud-httpd"> - <title>Using an alternative webserver as reverse-proxy (e.g. <literal>httpd</literal>)</title> - <para> - By default, <package>nginx</package> is used as reverse-proxy for <package>nextcloud</package>. - However, it's possible to use e.g. <package>httpd</package> by explicitly disabling - <package>nginx</package> using <xref linkend="opt-services.nginx.enable" /> and fixing the - settings <literal>listen.owner</literal> & <literal>listen.group</literal> in the - <link linkend="opt-services.phpfpm.pools">corresponding <literal>phpfpm</literal> pool</link>. - </para> - <para> - An exemplary configuration may look like this: -<programlisting>{ config, lib, pkgs, ... }: { - <link linkend="opt-services.nginx.enable">services.nginx.enable</link> = false; + </section> + <section xml:id="module-services-nextcloud-httpd"> + <title>Using an alternative webserver as reverse-proxy (e.g. + <literal>httpd</literal>)</title> + <para> + By default, <literal>nginx</literal> is used as reverse-proxy for + <literal>nextcloud</literal>. However, it’s possible to use e.g. + <literal>httpd</literal> by explicitly disabling + <literal>nginx</literal> using + <xref linkend="opt-services.nginx.enable" /> and fixing the + settings <literal>listen.owner</literal> & + <literal>listen.group</literal> in the + <link linkend="opt-services.phpfpm.pools">corresponding + <literal>phpfpm</literal> pool</link>. + </para> + <para> + An exemplary configuration may look like this: + </para> + <programlisting> +{ config, lib, pkgs, ... }: { + services.nginx.enable = false; services.nextcloud = { - <link linkend="opt-services.nextcloud.enable">enable</link> = true; - <link linkend="opt-services.nextcloud.hostName">hostName</link> = "localhost"; + enable = true; + hostName = "localhost"; /* further, required options */ }; - <link linkend="opt-services.phpfpm.pools._name_.settings">services.phpfpm.pools.nextcloud.settings</link> = { - "listen.owner" = config.services.httpd.user; - "listen.group" = config.services.httpd.group; + services.phpfpm.pools.nextcloud.settings = { + "listen.owner" = config.services.httpd.user; + "listen.group" = config.services.httpd.group; }; services.httpd = { - <link linkend="opt-services.httpd.enable">enable</link> = true; - <link linkend="opt-services.httpd.adminAddr">adminAddr</link> = "webmaster@localhost"; - <link linkend="opt-services.httpd.extraModules">extraModules</link> = [ "proxy_fcgi" ]; - virtualHosts."localhost" = { - <link linkend="opt-services.httpd.virtualHosts._name_.documentRoot">documentRoot</link> = config.services.nextcloud.package; - <link linkend="opt-services.httpd.virtualHosts._name_.extraConfig">extraConfig</link> = '' - <Directory "${config.services.nextcloud.package}"> - <FilesMatch "\.php$"> - <If "-f %{REQUEST_FILENAME}"> - SetHandler "proxy:unix:${config.services.phpfpm.pools.nextcloud.socket}|fcgi://localhost/" + enable = true; + adminAddr = "webmaster@localhost"; + extraModules = [ "proxy_fcgi" ]; + virtualHosts."localhost" = { + documentRoot = config.services.nextcloud.package; + extraConfig = '' + <Directory "${config.services.nextcloud.package}"> + <FilesMatch "\.php$"> + <If "-f %{REQUEST_FILENAME}"> + SetHandler "proxy:unix:${config.services.phpfpm.pools.nextcloud.socket}|fcgi://localhost/" </If> </FilesMatch> <IfModule mod_rewrite.c> @@ -238,68 +261,73 @@ ''; }; }; -}</programlisting> - </para> - </section> - - <section xml:id="installing-apps-php-extensions-nextcloud"> - <title>Installing Apps and PHP extensions</title> - - <para> - Nextcloud apps are installed statefully through the web interface. - - Some apps may require extra PHP extensions to be installed. - This can be configured with the <xref linkend="opt-services.nextcloud.phpExtraExtensions" /> setting. - </para> - - <para> - Alternatively, extra apps can also be declared with the <xref linkend="opt-services.nextcloud.extraApps" /> setting. - When using this setting, apps can no longer be managed statefully because this can lead to Nextcloud updating apps - that are managed by Nix. If you want automatic updates it is recommended that you use web interface to install apps. - </para> - </section> - - <section xml:id="module-services-nextcloud-maintainer-info"> - <title>Maintainer information</title> - - <para> - As stated in the previous paragraph, we must provide a clean upgrade-path for Nextcloud - since it cannot move more than one major version forward on a single upgrade. This chapter - adds some notes how Nextcloud updates should be rolled out in the future. - </para> - - <para> - While minor and patch-level updates are no problem and can be done directly in the - package-expression (and should be backported to supported stable branches after that), - major-releases should be added in a new attribute (e.g. Nextcloud <literal>v19.0.0</literal> - should be available in <literal>nixpkgs</literal> as <literal>pkgs.nextcloud19</literal>). - To provide simple upgrade paths it's generally useful to backport those as well to stable - branches. As long as the package-default isn't altered, this won't break existing setups. - After that, the versioning-warning in the <literal>nextcloud</literal>-module should be - updated to make sure that the - <link linkend="opt-services.nextcloud.package">package</link>-option selects the latest version - on fresh setups. - </para> - - <para> - If major-releases will be abandoned by upstream, we should check first if those are needed - in NixOS for a safe upgrade-path before removing those. In that case we should keep those - packages, but mark them as insecure in an expression like this (in - <literal><nixpkgs/pkgs/servers/nextcloud/default.nix></literal>): -<programlisting>/* ... */ +} +</programlisting> + </section> + <section xml:id="installing-apps-php-extensions-nextcloud"> + <title>Installing Apps and PHP extensions</title> + <para> + Nextcloud apps are installed statefully through the web interface. + Some apps may require extra PHP extensions to be installed. This + can be configured with the + <xref linkend="opt-services.nextcloud.phpExtraExtensions" /> + setting. + </para> + <para> + Alternatively, extra apps can also be declared with the + <xref linkend="opt-services.nextcloud.extraApps" /> setting. When + using this setting, apps can no longer be managed statefully + because this can lead to Nextcloud updating apps that are managed + by Nix. If you want automatic updates it is recommended that you + use web interface to install apps. + </para> + </section> + <section xml:id="module-services-nextcloud-maintainer-info"> + <title>Maintainer information</title> + <para> + As stated in the previous paragraph, we must provide a clean + upgrade-path for Nextcloud since it cannot move more than one + major version forward on a single upgrade. This chapter adds some + notes how Nextcloud updates should be rolled out in the future. + </para> + <para> + While minor and patch-level updates are no problem and can be done + directly in the package-expression (and should be backported to + supported stable branches after that), major-releases should be + added in a new attribute (e.g. Nextcloud + <literal>v19.0.0</literal> should be available in + <literal>nixpkgs</literal> as + <literal>pkgs.nextcloud19</literal>). To provide simple upgrade + paths it’s generally useful to backport those as well to stable + branches. As long as the package-default isn’t altered, this won’t + break existing setups. After that, the versioning-warning in the + <literal>nextcloud</literal>-module should be updated to make sure + that the + <link linkend="opt-services.nextcloud.package">package</link>-option + selects the latest version on fresh setups. + </para> + <para> + If major-releases will be abandoned by upstream, we should check + first if those are needed in NixOS for a safe upgrade-path before + removing those. In that case we should keep those packages, but + mark them as insecure in an expression like this (in + <literal><nixpkgs/pkgs/servers/nextcloud/default.nix></literal>): + </para> + <programlisting> +/* ... */ { nextcloud17 = generic { - version = "17.0.x"; - sha256 = "0000000000000000000000000000000000000000000000000000"; + version = "17.0.x"; + sha256 = "0000000000000000000000000000000000000000000000000000"; eol = true; }; -}</programlisting> - </para> - - <para> - Ideally we should make sure that it's possible to jump two NixOS versions forward: - i.e. the warnings and the logic in the module should guard a user to upgrade from a - Nextcloud on e.g. 19.09 to a Nextcloud on 20.09. - </para> - </section> +} +</programlisting> + <para> + Ideally we should make sure that it’s possible to jump two NixOS + versions forward: i.e. the warnings and the logic in the module + should guard a user to upgrade from a Nextcloud on e.g. 19.09 to a + Nextcloud on 20.09. + </para> + </section> </chapter> diff --git a/nixos/modules/services/web-apps/pict-rs.md b/nixos/modules/services/web-apps/pict-rs.md index 4b622049909d2..2fa6bb3aebced 100644 --- a/nixos/modules/services/web-apps/pict-rs.md +++ b/nixos/modules/services/web-apps/pict-rs.md @@ -15,6 +15,7 @@ this will start the http server on port 8080 by default. ## Usage {#module-services-pict-rs-usage} pict-rs offers the following endpoints: + - `POST /image` for uploading an image. Uploaded content must be valid multipart/form-data with an image array located within the `images[]` key diff --git a/nixos/modules/services/web-apps/pict-rs.nix b/nixos/modules/services/web-apps/pict-rs.nix index ee9ff9b484f6f..ad07507ca37db 100644 --- a/nixos/modules/services/web-apps/pict-rs.nix +++ b/nixos/modules/services/web-apps/pict-rs.nix @@ -5,8 +5,6 @@ let in { meta.maintainers = with maintainers; [ happysalada ]; - # Don't edit the docbook xml directly, edit the md and generate it: - # `pandoc pict-rs.md -t docbook --top-level-division=chapter --extract-media=media -f markdown+smart > pict-rs.xml` meta.doc = ./pict-rs.xml; options.services.pict-rs = { diff --git a/nixos/modules/services/web-apps/pict-rs.xml b/nixos/modules/services/web-apps/pict-rs.xml index bf129f5cc2ac2..3f5900c55f151 100644 --- a/nixos/modules/services/web-apps/pict-rs.xml +++ b/nixos/modules/services/web-apps/pict-rs.xml @@ -1,3 +1,5 @@ +<!-- Do not edit this file directly, edit its companion .md instead + and regenerate this file using nixos/doc/manual/md-to-db.sh --> <chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-pict-rs"> <title>Pict-rs</title> <para> @@ -8,7 +10,7 @@ <para> the minimum to start pict-rs is </para> - <programlisting language="bash"> + <programlisting language="nix"> services.pict-rs.enable = true; </programlisting> <para> @@ -18,14 +20,20 @@ services.pict-rs.enable = true; <section xml:id="module-services-pict-rs-usage"> <title>Usage</title> <para> - pict-rs offers the following endpoints: - - <literal>POST /image</literal> for uploading an image. Uploaded - content must be valid multipart/form-data with an image array - located within the <literal>images[]</literal> key + pict-rs offers the following endpoints: </para> - <programlisting> -This endpoint returns the following JSON structure on success with a 201 Created status -```json + <itemizedlist> + <listitem> + <para> + <literal>POST /image</literal> for uploading an image. + Uploaded content must be valid multipart/form-data with an + image array located within the <literal>images[]</literal> key + </para> + <para> + This endpoint returns the following JSON structure on success + with a 201 Created status + </para> + <programlisting language="json"> { "files": [ { @@ -43,9 +51,8 @@ This endpoint returns the following JSON structure on success with a 201 Created ], "msg": "ok" } -``` </programlisting> - <itemizedlist> + </listitem> <listitem> <para> <literal>GET /image/download?url=...</literal> Download an @@ -66,8 +73,20 @@ This endpoint returns the following JSON structure on success with a 201 Created <literal>GET /image/details/original/{file}</literal> for getting the details of a full-resolution image. The returned JSON is structured like so: - <literal>json { "width": 800, "height": 537, "content_type": "image/webp", "created_at": [ 2020, 345, 67376, 394363487 ] }</literal> </para> + <programlisting language="json"> +{ + "width": 800, + "height": 537, + "content_type": "image/webp", + "created_at": [ + 2020, + 345, + 67376, + 394363487 + ] +} +</programlisting> </listitem> <listitem> <para> @@ -124,7 +143,11 @@ This endpoint returns the following JSON structure on success with a 201 Created </para> <para> An example of usage could be - <literal>GET /image/process.jpg?src=asdf.png&thumbnail=256&blur=3.0</literal> + </para> + <programlisting> +GET /image/process.jpg?src=asdf.png&thumbnail=256&blur=3.0 +</programlisting> + <para> which would create a 256x256px JPEG thumbnail and blur it </para> </listitem> diff --git a/nixos/modules/services/web-apps/plausible.md b/nixos/modules/services/web-apps/plausible.md new file mode 100644 index 0000000000000..1328ce69441a0 --- /dev/null +++ b/nixos/modules/services/web-apps/plausible.md @@ -0,0 +1,35 @@ +# Plausible {#module-services-plausible} + +[Plausible](https://plausible.io/) is a privacy-friendly alternative to +Google analytics. + +## Basic Usage {#module-services-plausible-basic-usage} + +At first, a secret key is needed to be generated. This can be done with e.g. +```ShellSession +$ openssl rand -base64 64 +``` + +After that, `plausible` can be deployed like this: +``` +{ + services.plausible = { + enable = true; + adminUser = { + # activate is used to skip the email verification of the admin-user that's + # automatically created by plausible. This is only supported if + # postgresql is configured by the module. This is done by default, but + # can be turned off with services.plausible.database.postgres.setup. + activate = true; + email = "admin@localhost"; + passwordFile = "/run/secrets/plausible-admin-pwd"; + }; + server = { + baseUrl = "http://analytics.example.org"; + # secretKeybaseFile is a path to the file which contains the secret generated + # with openssl as described above. + secretKeybaseFile = "/run/secrets/plausible-secret-key-base"; + }; + }; +} +``` diff --git a/nixos/modules/services/web-apps/plausible.xml b/nixos/modules/services/web-apps/plausible.xml index 92a571b9fbdb5..39ff004ffd95f 100644 --- a/nixos/modules/services/web-apps/plausible.xml +++ b/nixos/modules/services/web-apps/plausible.xml @@ -1,51 +1,45 @@ -<chapter xmlns="http://docbook.org/ns/docbook" - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:xi="http://www.w3.org/2001/XInclude" - version="5.0" - xml:id="module-services-plausible"> - <title>Plausible</title> - <para> - <link xlink:href="https://plausible.io/">Plausible</link> is a privacy-friendly alternative to - Google analytics. - </para> - <section xml:id="module-services-plausible-basic-usage"> - <title>Basic Usage</title> +<!-- Do not edit this file directly, edit its companion .md instead + and regenerate this file using nixos/doc/manual/md-to-db.sh --> +<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-plausible"> + <title>Plausible</title> <para> - At first, a secret key is needed to be generated. This can be done with e.g. - <screen><prompt>$ </prompt>openssl rand -base64 64</screen> + <link xlink:href="https://plausible.io/">Plausible</link> is a + privacy-friendly alternative to Google analytics. </para> - <para> - After that, <package>plausible</package> can be deployed like this: -<programlisting>{ + <section xml:id="module-services-plausible-basic-usage"> + <title>Basic Usage</title> + <para> + At first, a secret key is needed to be generated. This can be done + with e.g. + </para> + <programlisting> +$ openssl rand -base64 64 +</programlisting> + <para> + After that, <literal>plausible</literal> can be deployed like + this: + </para> + <programlisting> +{ services.plausible = { - <link linkend="opt-services.plausible.enable">enable</link> = true; + enable = true; adminUser = { - <link linkend="opt-services.plausible.adminUser.activate">activate</link> = true; <co xml:id='ex-plausible-cfg-activate' /> - <link linkend="opt-services.plausible.adminUser.email">email</link> = "admin@localhost"; - <link linkend="opt-services.plausible.adminUser.passwordFile">passwordFile</link> = "/run/secrets/plausible-admin-pwd"; + # activate is used to skip the email verification of the admin-user that's + # automatically created by plausible. This is only supported if + # postgresql is configured by the module. This is done by default, but + # can be turned off with services.plausible.database.postgres.setup. + activate = true; + email = "admin@localhost"; + passwordFile = "/run/secrets/plausible-admin-pwd"; }; server = { - <link linkend="opt-services.plausible.server.baseUrl">baseUrl</link> = "http://analytics.example.org"; - <link linkend="opt-services.plausible.server.secretKeybaseFile">secretKeybaseFile</link> = "/run/secrets/plausible-secret-key-base"; <co xml:id='ex-plausible-cfg-secretbase' /> + baseUrl = "http://analytics.example.org"; + # secretKeybaseFile is a path to the file which contains the secret generated + # with openssl as described above. + secretKeybaseFile = "/run/secrets/plausible-secret-key-base"; }; }; -}</programlisting> - <calloutlist> - <callout arearefs='ex-plausible-cfg-activate'> - <para> - <varname>activate</varname> is used to skip the email verification of the admin-user that's - automatically created by <package>plausible</package>. This is only supported if - <package>postgresql</package> is configured by the module. This is done by default, but - can be turned off with <xref linkend="opt-services.plausible.database.postgres.setup" />. - </para> - </callout> - <callout arearefs='ex-plausible-cfg-secretbase'> - <para> - <varname>secretKeybaseFile</varname> is a path to the file which contains the secret generated - with <package>openssl</package> as described above. - </para> - </callout> - </calloutlist> - </para> - </section> +} +</programlisting> + </section> </chapter> |