0
0
Fork 0
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-07-14 06:00:33 +03:00

treewide: Fix all Nix ASTs in all markdown files

This allows for correct highlighting and maybe future automatic
formatting. The AST was verified to work with nixfmt only.
This commit is contained in:
Janne Heß 2024-03-27 19:10:27 +01:00 committed by Valentin Gagarin
parent bc77c7a973
commit fcc95ff817
150 changed files with 2896 additions and 2087 deletions

View file

@ -23,10 +23,12 @@ friendly input method user interface.
The following snippet can be used to configure IBus:
```nix
i18n.inputMethod = {
enabled = "ibus";
ibus.engines = with pkgs.ibus-engines; [ anthy hangul mozc ];
};
{
i18n.inputMethod = {
enabled = "ibus";
ibus.engines = with pkgs.ibus-engines; [ anthy hangul mozc ];
};
}
```
`i18n.inputMethod.ibus.engines` is optional and can be used
@ -49,7 +51,9 @@ Available extra IBus engines are:
`table`. For example:
```nix
ibus.engines = with pkgs.ibus-engines; [ table table-others ];
{
ibus.engines = with pkgs.ibus-engines; [ table table-others ];
}
```
To use any input method, the package must be added in the configuration, as
@ -75,10 +79,12 @@ built-in Input Method Engine, Pinyin, QuWei and Table-based input methods.
The following snippet can be used to configure Fcitx:
```nix
i18n.inputMethod = {
enabled = "fcitx5";
fcitx5.addons = with pkgs; [ fcitx5-mozc fcitx5-hangul fcitx5-m17n ];
};
{
i18n.inputMethod = {
enabled = "fcitx5";
fcitx5.addons = with pkgs; [ fcitx5-mozc fcitx5-hangul fcitx5-m17n ];
};
}
```
`i18n.inputMethod.fcitx5.addons` is optional and can be
@ -111,9 +117,11 @@ phonetic Korean characters (hangul) and pictographic Korean characters
The following snippet can be used to configure Nabi:
```nix
i18n.inputMethod = {
enabled = "nabi";
};
{
i18n.inputMethod = {
enabled = "nabi";
};
}
```
## Uim {#module-services-input-methods-uim}
@ -124,9 +132,11 @@ framework. Applications can use it through so-called bridges.
The following snippet can be used to configure uim:
```nix
i18n.inputMethod = {
enabled = "uim";
};
{
i18n.inputMethod = {
enabled = "uim";
};
}
```
Note: The [](#opt-i18n.inputMethod.uim.toolbar) option can be
@ -142,9 +152,11 @@ etc...
The following snippet can be used to configure Hime:
```nix
i18n.inputMethod = {
enabled = "hime";
};
{
i18n.inputMethod = {
enabled = "hime";
};
}
```
## Kime {#module-services-input-methods-kime}
@ -154,7 +166,9 @@ Kime is Korean IME. it's built with Rust language and let you get simple, safe,
The following snippet can be used to configure Kime:
```nix
i18n.inputMethod = {
enabled = "kime";
};
{
i18n.inputMethod = {
enabled = "kime";
};
}
```

View file

@ -5,7 +5,9 @@ Digital Bitbox is a hardware wallet and second-factor authenticator.
The `digitalbitbox` programs module may be installed by setting
`programs.digitalbitbox` to `true` in a manner similar to
```nix
programs.digitalbitbox.enable = true;
{
programs.digitalbitbox.enable = true;
}
```
and bundles the `digitalbitbox` package (see [](#sec-digitalbitbox-package)),
which contains the `dbb-app` and `dbb-cli` binaries, along with the hardware
@ -22,9 +24,11 @@ For more information, see <https://digitalbitbox.com/start_linux>.
The binaries, `dbb-app` (a GUI tool) and `dbb-cli` (a CLI tool), are available
through the `digitalbitbox` package which could be installed as follows:
```nix
environment.systemPackages = [
pkgs.digitalbitbox
];
{
environment.systemPackages = [
pkgs.digitalbitbox
];
}
```
## Hardware {#sec-digitalbitbox-hardware-module}
@ -32,16 +36,20 @@ environment.systemPackages = [
The digitalbitbox hardware package enables the udev rules for Digital Bitbox
devices and may be installed as follows:
```nix
hardware.digitalbitbox.enable = true;
{
hardware.digitalbitbox.enable = true;
}
```
In order to alter the udev rules, one may provide different values for the
`udevRule51` and `udevRule52` attributes by means of overriding as follows:
```nix
programs.digitalbitbox = {
enable = true;
package = pkgs.digitalbitbox.override {
udevRule51 = "something else";
{
programs.digitalbitbox = {
enable = true;
package = pkgs.digitalbitbox.override {
udevRule51 = "something else";
};
};
};
}
```

View file

@ -13,5 +13,7 @@ palette provides a searchable list of of all menu items in the application.
To enable Plotinus, add the following to your
{file}`configuration.nix`:
```nix
programs.plotinus.enable = true;
{
programs.plotinus.enable = true;
}
```

View file

@ -46,33 +46,35 @@ certs are overwritten when the ACME certs arrive. For
`foo.example.com` the config would look like this:
```nix
security.acme.acceptTerms = true;
security.acme.defaults.email = "admin+acme@example.com";
services.nginx = {
enable = true;
virtualHosts = {
"foo.example.com" = {
forceSSL = true;
enableACME = true;
# All serverAliases will be added as extra domain names on the certificate.
serverAliases = [ "bar.example.com" ];
locations."/" = {
root = "/var/www";
{
security.acme.acceptTerms = true;
security.acme.defaults.email = "admin+acme@example.com";
services.nginx = {
enable = true;
virtualHosts = {
"foo.example.com" = {
forceSSL = true;
enableACME = true;
# All serverAliases will be added as extra domain names on the certificate.
serverAliases = [ "bar.example.com" ];
locations."/" = {
root = "/var/www";
};
};
};
# We can also add a different vhost and reuse the same certificate
# but we have to append extraDomainNames manually beforehand:
# security.acme.certs."foo.example.com".extraDomainNames = [ "baz.example.com" ];
"baz.example.com" = {
forceSSL = true;
useACMEHost = "foo.example.com";
locations."/" = {
root = "/var/www";
# We can also add a different vhost and reuse the same certificate
# but we have to append extraDomainNames manually beforehand:
# security.acme.certs."foo.example.com".extraDomainNames = [ "baz.example.com" ];
"baz.example.com" = {
forceSSL = true;
useACMEHost = "foo.example.com";
locations."/" = {
root = "/var/www";
};
};
};
};
};
}
```
## Using ACME certificates in Apache/httpd {#module-security-acme-httpd}
@ -89,65 +91,69 @@ the intent that you will generate certs for all your vhosts and redirect
everyone to HTTPS.
```nix
security.acme.acceptTerms = true;
security.acme.defaults.email = "admin+acme@example.com";
{
security.acme.acceptTerms = true;
security.acme.defaults.email = "admin+acme@example.com";
# /var/lib/acme/.challenges must be writable by the ACME user
# and readable by the Nginx user. The easiest way to achieve
# this is to add the Nginx user to the ACME group.
users.users.nginx.extraGroups = [ "acme" ];
# /var/lib/acme/.challenges must be writable by the ACME user
# and readable by the Nginx user. The easiest way to achieve
# this is to add the Nginx user to the ACME group.
users.users.nginx.extraGroups = [ "acme" ];
services.nginx = {
enable = true;
virtualHosts = {
"acmechallenge.example.com" = {
# Catchall vhost, will redirect users to HTTPS for all vhosts
serverAliases = [ "*.example.com" ];
locations."/.well-known/acme-challenge" = {
root = "/var/lib/acme/.challenges";
};
locations."/" = {
return = "301 https://$host$request_uri";
services.nginx = {
enable = true;
virtualHosts = {
"acmechallenge.example.com" = {
# Catchall vhost, will redirect users to HTTPS for all vhosts
serverAliases = [ "*.example.com" ];
locations."/.well-known/acme-challenge" = {
root = "/var/lib/acme/.challenges";
};
locations."/" = {
return = "301 https://$host$request_uri";
};
};
};
};
};
# Alternative config for Apache
users.users.wwwrun.extraGroups = [ "acme" ];
services.httpd = {
enable = true;
virtualHosts = {
"acmechallenge.example.com" = {
# Catchall vhost, will redirect users to HTTPS for all vhosts
serverAliases = [ "*.example.com" ];
# /var/lib/acme/.challenges must be writable by the ACME user and readable by the Apache user.
# By default, this is the case.
documentRoot = "/var/lib/acme/.challenges";
extraConfig = ''
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301]
'';
# Alternative config for Apache
users.users.wwwrun.extraGroups = [ "acme" ];
services.httpd = {
enable = true;
virtualHosts = {
"acmechallenge.example.com" = {
# Catchall vhost, will redirect users to HTTPS for all vhosts
serverAliases = [ "*.example.com" ];
# /var/lib/acme/.challenges must be writable by the ACME user and readable by the Apache user.
# By default, this is the case.
documentRoot = "/var/lib/acme/.challenges";
extraConfig = ''
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301]
'';
};
};
};
};
}
```
Now you need to configure ACME to generate a certificate.
```nix
security.acme.certs."foo.example.com" = {
webroot = "/var/lib/acme/.challenges";
email = "foo@example.com";
# Ensure that the web server you use can read the generated certs
# Take a look at the group option for the web server you choose.
group = "nginx";
# Since we have a wildcard vhost to handle port 80,
# we can generate certs for anything!
# Just make sure your DNS resolves them.
extraDomainNames = [ "mail.example.com" ];
};
{
security.acme.certs."foo.example.com" = {
webroot = "/var/lib/acme/.challenges";
email = "foo@example.com";
# Ensure that the web server you use can read the generated certs
# Take a look at the group option for the web server you choose.
group = "nginx";
# Since we have a wildcard vhost to handle port 80,
# we can generate certs for anything!
# Just make sure your DNS resolves them.
extraDomainNames = [ "mail.example.com" ];
};
}
```
The private key {file}`key.pem` and certificate
@ -168,31 +174,33 @@ for provider/server specific configuration values. For the sake of these
docs, we will provide a fully self-hosted example using bind.
```nix
services.bind = {
enable = true;
extraConfig = ''
include "/var/lib/secrets/dnskeys.conf";
'';
zones = [
rec {
name = "example.com";
file = "/var/db/bind/${name}";
master = true;
extraConfig = "allow-update { key rfc2136key.example.com.; };";
}
];
};
{
services.bind = {
enable = true;
extraConfig = ''
include "/var/lib/secrets/dnskeys.conf";
'';
zones = [
rec {
name = "example.com";
file = "/var/db/bind/${name}";
master = true;
extraConfig = "allow-update { key rfc2136key.example.com.; };";
}
];
};
# Now we can configure ACME
security.acme.acceptTerms = true;
security.acme.defaults.email = "admin+acme@example.com";
security.acme.certs."example.com" = {
domain = "*.example.com";
dnsProvider = "rfc2136";
environmentFile = "/var/lib/secrets/certs.secret";
# We don't need to wait for propagation since this is a local DNS server
dnsPropagationCheck = false;
};
# Now we can configure ACME
security.acme.acceptTerms = true;
security.acme.defaults.email = "admin+acme@example.com";
security.acme.certs."example.com" = {
domain = "*.example.com";
dnsProvider = "rfc2136";
environmentFile = "/var/lib/secrets/certs.secret";
# We don't need to wait for propagation since this is a local DNS server
dnsPropagationCheck = false;
};
}
```
The {file}`dnskeys.conf` and {file}`certs.secret`
@ -200,36 +208,38 @@ must be kept secure and thus you should not keep their contents in your
Nix config. Instead, generate them one time with a systemd service:
```nix
systemd.services.dns-rfc2136-conf = {
requiredBy = ["acme-example.com.service" "bind.service"];
before = ["acme-example.com.service" "bind.service"];
unitConfig = {
ConditionPathExists = "!/var/lib/secrets/dnskeys.conf";
};
serviceConfig = {
Type = "oneshot";
UMask = 0077;
};
path = [ pkgs.bind ];
script = ''
mkdir -p /var/lib/secrets
chmod 755 /var/lib/secrets
tsig-keygen rfc2136key.example.com > /var/lib/secrets/dnskeys.conf
chown named:root /var/lib/secrets/dnskeys.conf
chmod 400 /var/lib/secrets/dnskeys.conf
{
systemd.services.dns-rfc2136-conf = {
requiredBy = ["acme-example.com.service" "bind.service"];
before = ["acme-example.com.service" "bind.service"];
unitConfig = {
ConditionPathExists = "!/var/lib/secrets/dnskeys.conf";
};
serviceConfig = {
Type = "oneshot";
UMask = 0077;
};
path = [ pkgs.bind ];
script = ''
mkdir -p /var/lib/secrets
chmod 755 /var/lib/secrets
tsig-keygen rfc2136key.example.com > /var/lib/secrets/dnskeys.conf
chown named:root /var/lib/secrets/dnskeys.conf
chmod 400 /var/lib/secrets/dnskeys.conf
# extract secret value from the dnskeys.conf
while read x y; do if [ "$x" = "secret" ]; then secret="''${y:1:''${#y}-3}"; fi; done < /var/lib/secrets/dnskeys.conf
# extract secret value from the dnskeys.conf
while read x y; do if [ "$x" = "secret" ]; then secret="''${y:1:''${#y}-3}"; fi; done < /var/lib/secrets/dnskeys.conf
cat > /var/lib/secrets/certs.secret << EOF
RFC2136_NAMESERVER='127.0.0.1:53'
RFC2136_TSIG_ALGORITHM='hmac-sha256.'
RFC2136_TSIG_KEY='rfc2136key.example.com'
RFC2136_TSIG_SECRET='$secret'
EOF
chmod 400 /var/lib/secrets/certs.secret
'';
};
cat > /var/lib/secrets/certs.secret << EOF
RFC2136_NAMESERVER='127.0.0.1:53'
RFC2136_TSIG_ALGORITHM='hmac-sha256.'
RFC2136_TSIG_KEY='rfc2136key.example.com'
RFC2136_TSIG_SECRET='$secret'
EOF
chmod 400 /var/lib/secrets/certs.secret
'';
};
}
```
Now you're all set to generate certs! You should monitor the first invocation
@ -251,27 +261,29 @@ you will set them as defaults
(e.g. [](#opt-security.acme.defaults.dnsProvider)).
```nix
# Configure ACME appropriately
security.acme.acceptTerms = true;
security.acme.defaults.email = "admin+acme@example.com";
security.acme.defaults = {
dnsProvider = "rfc2136";
environmentFile = "/var/lib/secrets/certs.secret";
# We don't need to wait for propagation since this is a local DNS server
dnsPropagationCheck = false;
};
{
# Configure ACME appropriately
security.acme.acceptTerms = true;
security.acme.defaults.email = "admin+acme@example.com";
security.acme.defaults = {
dnsProvider = "rfc2136";
environmentFile = "/var/lib/secrets/certs.secret";
# We don't need to wait for propagation since this is a local DNS server
dnsPropagationCheck = false;
};
# For each virtual host you would like to use DNS-01 validation with,
# set acmeRoot = null
services.nginx = {
enable = true;
virtualHosts = {
"foo.example.com" = {
enableACME = true;
acmeRoot = null;
# For each virtual host you would like to use DNS-01 validation with,
# set acmeRoot = null
services.nginx = {
enable = true;
virtualHosts = {
"foo.example.com" = {
enableACME = true;
acmeRoot = null;
};
};
};
};
}
```
And that's it! Next time your configuration is rebuilt, or when
@ -288,39 +300,41 @@ Below is an example configuration for OpenSMTPD, but this pattern
can be applied to any service.
```nix
# Configure ACME however you like (DNS or HTTP validation), adding
# the following configuration for the relevant certificate.
# Note: You cannot use `systemctl reload` here as that would mean
# the LoadCredential configuration below would be skipped and
# the service would continue to use old certificates.
security.acme.certs."mail.example.com".postRun = ''
systemctl restart opensmtpd
'';
# Now you must augment OpenSMTPD's systemd service to load
# the certificate files.
systemd.services.opensmtpd.requires = ["acme-finished-mail.example.com.target"];
systemd.services.opensmtpd.serviceConfig.LoadCredential = let
certDir = config.security.acme.certs."mail.example.com".directory;
in [
"cert.pem:${certDir}/cert.pem"
"key.pem:${certDir}/key.pem"
];
# Finally, configure OpenSMTPD to use these certs.
services.opensmtpd = let
credsDir = "/run/credentials/opensmtpd.service";
in {
enable = true;
setSendmail = false;
serverConfiguration = ''
pki mail.example.com cert "${credsDir}/cert.pem"
pki mail.example.com key "${credsDir}/key.pem"
listen on localhost tls pki mail.example.com
action act1 relay host smtp://127.0.0.1:10027
match for local action act1
{
# Configure ACME however you like (DNS or HTTP validation), adding
# the following configuration for the relevant certificate.
# Note: You cannot use `systemctl reload` here as that would mean
# the LoadCredential configuration below would be skipped and
# the service would continue to use old certificates.
security.acme.certs."mail.example.com".postRun = ''
systemctl restart opensmtpd
'';
};
# Now you must augment OpenSMTPD's systemd service to load
# the certificate files.
systemd.services.opensmtpd.requires = ["acme-finished-mail.example.com.target"];
systemd.services.opensmtpd.serviceConfig.LoadCredential = let
certDir = config.security.acme.certs."mail.example.com".directory;
in [
"cert.pem:${certDir}/cert.pem"
"key.pem:${certDir}/key.pem"
];
# Finally, configure OpenSMTPD to use these certs.
services.opensmtpd = let
credsDir = "/run/credentials/opensmtpd.service";
in {
enable = true;
setSendmail = false;
serverConfiguration = ''
pki mail.example.com cert "${credsDir}/cert.pem"
pki mail.example.com key "${credsDir}/key.pem"
listen on localhost tls pki mail.example.com
action act1 relay host smtp://127.0.0.1:10027
match for local action act1
'';
};
}
```
## Regenerating certificates {#module-security-acme-regenerate}

View file

@ -7,16 +7,18 @@ Castopod is an open-source hosting platform made for podcasters who want to enga
Use the following configuration to start a public instance of Castopod on `castopod.example.com` domain:
```nix
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.castopod = {
enable = true;
database.createLocally = true;
nginx.virtualHost = {
serverName = "castopod.example.com";
enableACME = true;
forceSSL = true;
{
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.castopod = {
enable = true;
database.createLocally = true;
nginx.virtualHost = {
serverName = "castopod.example.com";
enableACME = true;
forceSSL = true;
};
};
};
}
```
Go to `https://castopod.example.com/cp-install` to create superadmin account after applying the above configuration.

View file

@ -24,19 +24,18 @@ A very basic configuration for backing up to a locally accessible directory is:
```nix
{
opt.services.borgbackup.jobs = {
{ rootBackup = {
paths = "/";
exclude = [ "/nix" "/path/to/local/repo" ];
repo = "/path/to/local/repo";
doInit = true;
encryption = {
mode = "repokey";
passphrase = "secret";
};
compression = "auto,lzma";
startAt = "weekly";
rootBackup = {
paths = "/";
exclude = [ "/nix" "/path/to/local/repo" ];
repo = "/path/to/local/repo";
doInit = true;
encryption = {
mode = "repokey";
passphrase = "secret";
};
}
compression = "auto,lzma";
startAt = "weekly";
};
};
}
```
@ -96,7 +95,7 @@ accessible by root
startAt = "hourly";
};
};
};
}
```
The following few commands (run as root) let you test your backup.

View file

@ -16,8 +16,10 @@ key-value store.
To enable FoundationDB, add the following to your
{file}`configuration.nix`:
```nix
services.foundationdb.enable = true;
services.foundationdb.package = pkgs.foundationdb71; # FoundationDB 7.1.x
{
services.foundationdb.enable = true;
services.foundationdb.package = pkgs.foundationdb71; # FoundationDB 7.1.x
}
```
The {option}`services.foundationdb.package` option is required, and
@ -110,7 +112,9 @@ FoundationDB stores all data for all server processes under
{file}`/var/lib/foundationdb`. You can override this using
{option}`services.foundationdb.dataDir`, e.g.
```nix
services.foundationdb.dataDir = "/data/fdb";
{
services.foundationdb.dataDir = "/data/fdb";
}
```
Similarly, logs are stored under {file}`/var/log/foundationdb`
@ -266,7 +270,9 @@ For example, to create backups in {command}`/opt/fdb-backups`, first
set up the paths in the module options:
```nix
services.foundationdb.extraReadWritePaths = [ "/opt/fdb-backups" ];
{
services.foundationdb.extraReadWritePaths = [ "/opt/fdb-backups" ];
}
```
Restart the FoundationDB service, and it will now be able to write to this

View file

@ -16,8 +16,10 @@ PostgreSQL is an advanced, free relational database.
To enable PostgreSQL, add the following to your {file}`configuration.nix`:
```nix
services.postgresql.enable = true;
services.postgresql.package = pkgs.postgresql_15;
{
services.postgresql.enable = true;
services.postgresql.package = pkgs.postgresql_15;
}
```
Note that you are required to specify the desired version of PostgreSQL (e.g. `pkgs.postgresql_15`). Since upgrading your PostgreSQL version requires a database dump and reload (see below), NixOS cannot provide a default value for [](#opt-services.postgresql.package) such as the most recent release of PostgreSQL.
@ -36,7 +38,9 @@ alice=>
By default, PostgreSQL stores its databases in {file}`/var/lib/postgresql/$psqlSchema`. You can override this using [](#opt-services.postgresql.dataDir), e.g.
```nix
services.postgresql.dataDir = "/data/postgresql";
{
services.postgresql.dataDir = "/data/postgresql";
}
```
## Initializing {#module-services-postgres-initializing}
@ -95,16 +99,19 @@ databases from `ensureDatabases` and `extraUser1` from `ensureUsers`
are already created.
```nix
{
systemd.services.postgresql.postStart = lib.mkAfter ''
$PSQL service1 -c 'GRANT SELECT ON ALL TABLES IN SCHEMA public TO "extraUser1"'
$PSQL service1 -c 'GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO "extraUser1"'
# ....
'';
}
```
##### in intermediate oneshot service {#module-services-postgres-initializing-extra-permissions-superuser-oneshot}
```nix
{
systemd.services."migrate-service1-db1" = {
serviceConfig.Type = "oneshot";
requiredBy = "service1.service";
@ -119,6 +126,7 @@ are already created.
# ....
'';
};
}
```
#### as service user {#module-services-postgres-initializing-extra-permissions-service-user}
@ -130,6 +138,7 @@ are already created.
##### in service `preStart` {#module-services-postgres-initializing-extra-permissions-service-user-pre-start}
```nix
{
environment.PSQL = "psql --port=${toString services.postgresql.port}";
path = [ postgresql ];
systemd.services."service1".preStart = ''
@ -137,11 +146,13 @@ are already created.
$PSQL -c 'GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO "extraUser1"'
# ....
'';
}
```
##### in intermediate oneshot service {#module-services-postgres-initializing-extra-permissions-service-user-oneshot}
```nix
{
systemd.services."migrate-service1-db1" = {
serviceConfig.Type = "oneshot";
requiredBy = "service1.service";
@ -156,6 +167,7 @@ are already created.
# ....
'';
};
}
```
## Upgrading {#module-services-postgres-upgrading}
@ -257,11 +269,13 @@ postgresql_15.pkgs.pg_partman postgresql_15.pkgs.pgroonga
To add plugins via NixOS configuration, set `services.postgresql.extraPlugins`:
```nix
services.postgresql.package = pkgs.postgresql_12;
services.postgresql.extraPlugins = ps: with ps; [
pg_repack
postgis
];
{
services.postgresql.package = pkgs.postgresql_12;
services.postgresql.extraPlugins = ps: with ps; [
pg_repack
postgis
];
}
```
You can build custom PostgreSQL-with-plugins (to be used outside of NixOS) using function `.withPackages`. For example, creating a custom PostgreSQL package in an overlay can look like:

View file

@ -8,7 +8,9 @@ TigerBeetle is a distributed financial accounting database designed for mission
To enable TigerBeetle, add the following to your {file}`configuration.nix`:
```nix
{
services.tigerbeetle.enable = true;
}
```
When first started, the TigerBeetle service will create its data file at {file}`/var/lib/tigerbeetle` unless the file already exists, in which case it will just use the existing file.
@ -21,12 +23,14 @@ To configure it to listen on a different interface (and to configure it to conne
Note that the TigerBeetle module won't open any firewall ports automatically, so if you configure it to listen on an external interface, you'll need to ensure that connections can reach it:
```nix
{
services.tigerbeetle = {
enable = true;
addresses = [ "0.0.0.0:3001" ];
};
networking.firewall.allowedTCPPorts = [ 3001 ];
}
```
A complete list of options for TigerBeetle can be found [here](#opt-services.tigerbeetle.enable).

View file

@ -9,7 +9,9 @@ applications on Linux.
To enable Flatpak, add the following to your {file}`configuration.nix`:
```nix
{
services.flatpak.enable = true;
}
```
For the sandboxed apps to work correctly, desktop integration portals need to
@ -17,8 +19,10 @@ be installed. If you run GNOME, this will be handled automatically for you;
in other cases, you will need to add something like the following to your
{file}`configuration.nix`:
```nix
{
xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
xdg.portal.config.common.default = "gtk";
}
```
Then, you will need to add a repository, for example,

View file

@ -42,7 +42,7 @@ To use the local proxy in Go builds, you can set the proxy as environment variab
```nix
{
environment.variables = {
GOPROXY = "http://localhost:3000"
GOPROXY = "http://localhost:3000";
};
}
```

View file

@ -52,5 +52,7 @@ learning Kinos require `gcc` and `gnumake`. To add these, use
`extraPackages`:
```nix
services.livebook.extraPackages = with pkgs; [ gcc gnumake ];
{
services.livebook.extraPackages = with pkgs; [ gcc gnumake ];
}
```

View file

@ -242,7 +242,7 @@ let
rm $out/share/applications/emacs.desktop
'';
});
in [...]
in [ /* ... */ ]
```
:::
@ -263,7 +263,9 @@ with the user's login session.
To install and enable the {command}`systemd` user service for Emacs
daemon, add the following to your {file}`configuration.nix`:
```nix
services.emacs.enable = true;
{
services.emacs.enable = true;
}
```
The {var}`services.emacs.package` option allows a custom
@ -324,8 +326,10 @@ by symlinks in {file}`/etc/systemd/user`. In the case where
Emacs daemon is not wanted for all users, it is possible to install the
service but not globally enable it:
```nix
services.emacs.enable = false;
services.emacs.install = true;
{
services.emacs.enable = false;
services.emacs.install = true;
}
```
To enable the {command}`systemd` user service for just the

View file

@ -10,7 +10,9 @@ framework for Matrix.
2. If you want to use PostgreSQL instead of SQLite, do this:
```nix
services.maubot.settings.database = "postgresql://maubot@localhost/maubot";
{
services.maubot.settings.database = "postgresql://maubot@localhost/maubot";
}
```
If the PostgreSQL connection requires a password, you will have to
@ -18,54 +20,58 @@ framework for Matrix.
3. If you plan to expose your Maubot interface to the web, do something
like this:
```nix
services.nginx.virtualHosts."matrix.example.org".locations = {
"/_matrix/maubot/" = {
proxyPass = "http://127.0.0.1:${toString config.services.maubot.settings.server.port}";
proxyWebsockets = true;
{
services.nginx.virtualHosts."matrix.example.org".locations = {
"/_matrix/maubot/" = {
proxyPass = "http://127.0.0.1:${toString config.services.maubot.settings.server.port}";
proxyWebsockets = true;
};
};
};
services.maubot.settings.server.public_url = "matrix.example.org";
# do the following only if you want to use something other than /_matrix/maubot...
services.maubot.settings.server.ui_base_path = "/another/base/path";
services.maubot.settings.server.public_url = "matrix.example.org";
# do the following only if you want to use something other than /_matrix/maubot...
services.maubot.settings.server.ui_base_path = "/another/base/path";
}
```
4. Optionally, set `services.maubot.pythonPackages` to a list of python3
packages to make available for Maubot plugins.
5. Optionally, set `services.maubot.plugins` to a list of Maubot
plugins (full list available at https://plugins.maubot.xyz/):
```nix
services.maubot.plugins = with config.services.maubot.package.plugins; [
reactbot
# This will only change the default config! After you create a
# plugin instance, the default config will be copied into that
# instance's config in Maubot's database, and further base config
# changes won't affect the running plugin.
(rss.override {
base_config = {
update_interval = 60;
max_backoff = 7200;
spam_sleep = 2;
command_prefix = "rss";
admins = [ "@chayleaf:pavluk.org" ];
};
})
];
# ...or...
services.maubot.plugins = config.services.maubot.package.plugins.allOfficialPlugins;
# ...or...
services.maubot.plugins = config.services.maubot.package.plugins.allPlugins;
# ...or...
services.maubot.plugins = with config.services.maubot.package.plugins; [
(weather.override {
# you can pass base_config as a string
base_config = ''
default_location: New York
default_units: M
default_language:
show_link: true
show_image: false
'';
})
];
{
services.maubot.plugins = with config.services.maubot.package.plugins; [
reactbot
# This will only change the default config! After you create a
# plugin instance, the default config will be copied into that
# instance's config in Maubot's database, and further base config
# changes won't affect the running plugin.
(rss.override {
base_config = {
update_interval = 60;
max_backoff = 7200;
spam_sleep = 2;
command_prefix = "rss";
admins = [ "@chayleaf:pavluk.org" ];
};
})
];
# ...or...
services.maubot.plugins = config.services.maubot.package.plugins.allOfficialPlugins;
# ...or...
services.maubot.plugins = config.services.maubot.package.plugins.allPlugins;
# ...or...
services.maubot.plugins = with config.services.maubot.package.plugins; [
(weather.override {
# you can pass base_config as a string
base_config = ''
default_location: New York
default_units: M
default_language:
show_link: true
show_image: false
'';
})
];
}
```
6. Start Maubot at least once before doing the following steps (it's
necessary to generate the initial config).

View file

@ -57,23 +57,25 @@ locations and database, instead of having to copy or rename them.
Make sure to disable `services.gitea`, when doing this.
```nix
services.gitea.enable = false;
{
services.gitea.enable = false;
services.forgejo = {
enable = true;
user = "gitea";
group = "gitea";
stateDir = "/var/lib/gitea";
database.name = "gitea";
database.user = "gitea";
};
services.forgejo = {
enable = true;
user = "gitea";
group = "gitea";
stateDir = "/var/lib/gitea";
database.name = "gitea";
database.user = "gitea";
};
users.users.gitea = {
home = "/var/lib/gitea";
useDefaultShell = true;
group = "gitea";
isSystemUser = true;
};
users.users.gitea = {
home = "/var/lib/gitea";
useDefaultShell = true;
group = "gitea";
isSystemUser = true;
};
users.groups.gitea = {};
users.groups.gitea = {};
}
```

View file

@ -11,18 +11,20 @@ configure a webserver to proxy HTTP requests to the socket.
For instance, the following configuration could be used to use nginx as
frontend proxy:
```nix
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
virtualHosts."git.example.com" = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://unix:/run/gitlab/gitlab-workhorse.socket";
{
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
virtualHosts."git.example.com" = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://unix:/run/gitlab/gitlab-workhorse.socket";
};
};
};
}
```
## Configuring {#module-services-gitlab-configuring}
@ -36,35 +38,37 @@ all data like the repositories and uploads will be stored.
A basic configuration with some custom settings could look like this:
```nix
services.gitlab = {
enable = true;
databasePasswordFile = "/var/keys/gitlab/db_password";
initialRootPasswordFile = "/var/keys/gitlab/root_password";
https = true;
host = "git.example.com";
port = 443;
user = "git";
group = "git";
smtp = {
{
services.gitlab = {
enable = true;
address = "localhost";
port = 25;
};
secrets = {
dbFile = "/var/keys/gitlab/db";
secretFile = "/var/keys/gitlab/secret";
otpFile = "/var/keys/gitlab/otp";
jwsFile = "/var/keys/gitlab/jws";
};
extraConfig = {
gitlab = {
email_from = "gitlab-no-reply@example.com";
email_display_name = "Example GitLab";
email_reply_to = "gitlab-no-reply@example.com";
default_projects_features = { builds = false; };
databasePasswordFile = "/var/keys/gitlab/db_password";
initialRootPasswordFile = "/var/keys/gitlab/root_password";
https = true;
host = "git.example.com";
port = 443;
user = "git";
group = "git";
smtp = {
enable = true;
address = "localhost";
port = 25;
};
secrets = {
dbFile = "/var/keys/gitlab/db";
secretFile = "/var/keys/gitlab/secret";
otpFile = "/var/keys/gitlab/otp";
jwsFile = "/var/keys/gitlab/jws";
};
extraConfig = {
gitlab = {
email_from = "gitlab-no-reply@example.com";
email_display_name = "Example GitLab";
email_reply_to = "gitlab-no-reply@example.com";
default_projects_features = { builds = false; };
};
};
};
};
}
```
If you're setting up a new GitLab instance, generate new

View file

@ -66,9 +66,9 @@ in {
# Settings to setup what certificates are used for which endpoint.
virtualHosts = {
"${fqdn}".enableACME = true;
"meta.${fqdn}".useACMEHost = fqdn:
"man.${fqdn}".useACMEHost = fqdn:
"git.${fqdn}".useACMEHost = fqdn:
"meta.${fqdn}".useACMEHost = fqdn;
"man.${fqdn}".useACMEHost = fqdn;
"git.${fqdn}".useACMEHost = fqdn;
};
};
}

View file

@ -9,17 +9,19 @@ A basic config that notifies you of all certificate changes for your
domain would look as follows:
```nix
services.certspotter = {
enable = true;
# replace example.org with your domain name
watchlist = [ ".example.org" ];
emailRecipients = [ "webmaster@example.org" ];
};
{
services.certspotter = {
enable = true;
# replace example.org with your domain name
watchlist = [ ".example.org" ];
emailRecipients = [ "webmaster@example.org" ];
};
# Configure an SMTP client
programs.msmtp.enable = true;
# Or you can use any other module that provides sendmail, like
# services.nullmailer, services.opensmtpd, services.postfix
# Configure an SMTP client
programs.msmtp.enable = true;
# Or you can use any other module that provides sendmail, like
# services.nullmailer, services.opensmtpd, services.postfix
}
```
In this case, the leading dot in `".example.org"` means that Cert
@ -59,16 +61,18 @@ For example, you can remove `emailRecipients` and send email
notifications manually using the following hook:
```nix
services.certspotter.hooks = [
(pkgs.writeShellScript "certspotter-hook" ''
function print_email() {
echo "Subject: [certspotter] $SUMMARY"
echo "Mime-Version: 1.0"
echo "Content-Type: text/plain; charset=US-ASCII"
echo
cat "$TEXT_FILENAME"
}
print_email | ${config.services.certspotter.sendmailPath} -i webmaster@example.org
'')
];
{
services.certspotter.hooks = [
(pkgs.writeShellScript "certspotter-hook" ''
function print_email() {
echo "Subject: [certspotter] $SUMMARY"
echo "Mime-Version: 1.0"
echo "Content-Type: text/plain; charset=US-ASCII"
echo
cat "$TEXT_FILENAME"
}
print_email | ${config.services.certspotter.sendmailPath} -i webmaster@example.org
'')
];
}
```

View file

@ -11,15 +11,17 @@ email address and saves them to a local Elasticsearch instance looks
like this:
```nix
services.parsedmarc = {
enable = true;
settings.imap = {
host = "imap.example.com";
user = "alice@example.com";
password = "/path/to/imap_password_file";
{
services.parsedmarc = {
enable = true;
settings.imap = {
host = "imap.example.com";
user = "alice@example.com";
password = "/path/to/imap_password_file";
};
provision.geoIp = false; # Not recommended!
};
provision.geoIp = false; # Not recommended!
};
}
```
Note that GeoIP provisioning is disabled in the example for
@ -37,16 +39,18 @@ configured in the domain's dmarc policy is
`dmarc@monitoring.example.com`.
```nix
services.parsedmarc = {
enable = true;
provision = {
localMail = {
enable = true;
hostname = monitoring.example.com;
{
services.parsedmarc = {
enable = true;
provision = {
localMail = {
enable = true;
hostname = monitoring.example.com;
};
geoIp = false; # Not recommended!
};
geoIp = false; # Not recommended!
};
};
}
```
## Grafana and GeoIP {#module-services-parsedmarc-grafana-geoip}
@ -58,55 +62,57 @@ is automatically added as a Grafana datasource, and the dashboard is
added to Grafana as well.
```nix
services.parsedmarc = {
enable = true;
provision = {
localMail = {
enable = true;
hostname = url;
};
grafana = {
datasource = true;
dashboard = true;
{
services.parsedmarc = {
enable = true;
provision = {
localMail = {
enable = true;
hostname = url;
};
grafana = {
datasource = true;
dashboard = true;
};
};
};
};
# Not required, but recommended for full functionality
services.geoipupdate = {
settings = {
AccountID = 000000;
LicenseKey = "/path/to/license_key_file";
# Not required, but recommended for full functionality
services.geoipupdate = {
settings = {
AccountID = 000000;
LicenseKey = "/path/to/license_key_file";
};
};
};
services.grafana = {
enable = true;
addr = "0.0.0.0";
domain = url;
rootUrl = "https://" + url;
protocol = "socket";
security = {
adminUser = "admin";
adminPasswordFile = "/path/to/admin_password_file";
secretKeyFile = "/path/to/secret_key_file";
services.grafana = {
enable = true;
addr = "0.0.0.0";
domain = url;
rootUrl = "https://" + url;
protocol = "socket";
security = {
adminUser = "admin";
adminPasswordFile = "/path/to/admin_password_file";
secretKeyFile = "/path/to/secret_key_file";
};
};
};
services.nginx = {
enable = true;
recommendedTlsSettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedProxySettings = true;
upstreams.grafana.servers."unix:/${config.services.grafana.socket}" = {};
virtualHosts.${url} = {
root = config.services.grafana.staticRootPath;
enableACME = true;
forceSSL = true;
locations."/".tryFiles = "$uri @grafana";
locations."@grafana".proxyPass = "http://grafana";
services.nginx = {
enable = true;
recommendedTlsSettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedProxySettings = true;
upstreams.grafana.servers."unix:/${config.services.grafana.socket}" = {};
virtualHosts.${url} = {
root = config.services.grafana.staticRootPath;
enableACME = true;
forceSSL = true;
locations."/".tryFiles = "$uri @grafana";
locations."@grafana".proxyPass = "http://grafana";
};
};
};
users.users.nginx.extraGroups = [ "grafana" ];
users.users.nginx.extraGroups = [ "grafana" ];
}
```

View file

@ -10,6 +10,7 @@ One of the most common exporters is the
it provides hardware and OS metrics from the host it's
running on. The exporter could be configured as follows:
```nix
{
services.prometheus.exporters.node = {
enable = true;
port = 9100;
@ -23,6 +24,7 @@ running on. The exporter could be configured as follows:
openFirewall = true;
firewallFilter = "-i br0 -p tcp -m tcp --dport 9100";
};
}
```
It should now serve all metrics from the collectors that are explicitly
enabled and the ones that are
@ -36,6 +38,7 @@ the [available options](https://nixos.org/nixos/options.html#prometheus.exporter
Prometheus can now be configured to consume the metrics produced by the exporter:
```nix
{
services.prometheus = {
# ...
@ -49,7 +52,8 @@ Prometheus can now be configured to consume the metrics produced by the exporter
];
# ...
}
};
}
```
## Adding a new exporter {#module-services-prometheus-exporters-new-exporter}

View file

@ -7,19 +7,21 @@ A storage server for Firefox Sync that you can easily host yourself.
The absolute minimal configuration for the sync server looks like this:
```nix
services.mysql.package = pkgs.mariadb;
{
services.mysql.package = pkgs.mariadb;
services.firefox-syncserver = {
enable = true;
secrets = builtins.toFile "sync-secrets" ''
SYNC_MASTER_SECRET=this-secret-is-actually-leaked-to-/nix/store
'';
singleNode = {
services.firefox-syncserver = {
enable = true;
hostname = "localhost";
url = "http://localhost:5000";
secrets = builtins.toFile "sync-secrets" ''
SYNC_MASTER_SECRET=this-secret-is-actually-leaked-to-/nix/store
'';
singleNode = {
enable = true;
hostname = "localhost";
url = "http://localhost:5000";
};
};
};
}
```
This will start a sync server that is only accessible locally. Once the services is

View file

@ -7,14 +7,16 @@ Mosquitto is a MQTT broker often used for IoT or home automation data transport.
A minimal configuration for Mosquitto is
```nix
services.mosquitto = {
enable = true;
listeners = [ {
acl = [ "pattern readwrite #" ];
omitPasswordAuth = true;
settings.allow_anonymous = true;
} ];
};
{
services.mosquitto = {
enable = true;
listeners = [ {
acl = [ "pattern readwrite #" ];
omitPasswordAuth = true;
settings.allow_anonymous = true;
} ];
};
}
```
This will start a broker on port 1883, listening on all interfaces of the machine, allowing
@ -25,37 +27,42 @@ full read access to a user `monitor` and restricted write access to a user `serv
like
```nix
services.mosquitto = {
enable = true;
listeners = [ {
users = {
monitor = {
acl = [ "read #" ];
password = "monitor";
{
services.mosquitto = {
enable = true;
listeners = [ {
users = {
monitor = {
acl = [ "read #" ];
password = "monitor";
};
service = {
acl = [ "write service/#" ];
password = "service";
};
};
service = {
acl = [ "write service/#" ];
password = "service";
};
};
} ];
};
} ];
};
}
```
TLS authentication is configured by setting TLS-related options of the listener:
```nix
services.mosquitto = {
enable = true;
listeners = [ {
port = 8883; # port change is not required, but helpful to avoid mistakes
# ...
settings = {
cafile = "/path/to/mqtt.ca.pem";
certfile = "/path/to/mqtt.pem";
keyfile = "/path/to/mqtt.key";
};
} ];
{
services.mosquitto = {
enable = true;
listeners = [ {
port = 8883; # port change is not required, but helpful to avoid mistakes
# ...
settings = {
cafile = "/path/to/mqtt.ca.pem";
certfile = "/path/to/mqtt.pem";
keyfile = "/path/to/mqtt.key";
};
} ];
};
}
```
## Configuration {#module-services-mosquitto-config}

View file

@ -5,7 +5,9 @@
The absolute minimal configuration for the netbird daemon looks like this:
```nix
services.netbird.enable = true;
{
services.netbird.enable = true;
}
```
This will set up a netbird service listening on the port `51820` associated to the
@ -14,7 +16,9 @@ This will set up a netbird service listening on the port `51820` associated to t
It is strictly equivalent to setting:
```nix
services.netbird.tunnels.wt0.stateDir = "netbird";
{
services.netbird.tunnels.wt0.stateDir = "netbird";
}
```
The `enable` option is mainly kept for backward compatibility, as defining netbird
@ -29,11 +33,13 @@ The following configuration will start a netbird daemon using the interface `wt1
the port 51830. Its configuration file will then be located at `/var/lib/netbird-wt1/config.json`.
```nix
services.netbird.tunnels = {
wt1 = {
port = 51830;
{
services.netbird.tunnels = {
wt1 = {
port = 51830;
};
};
};
}
```
To interact with it, you will need to specify the correct daemon address:
@ -48,9 +54,11 @@ It is also possible to overwrite default options passed to the service, for
example:
```nix
services.netbird.tunnels.wt1.environment = {
NB_DAEMON_ADDR = "unix:///var/run/toto.sock"
};
{
services.netbird.tunnels.wt1.environment = {
NB_DAEMON_ADDR = "unix:///var/run/toto.sock";
};
}
```
This will set the socket to interact with the netbird service to `/var/run/toto.sock`.

View file

@ -18,10 +18,12 @@ The `config.exs` file can be further customized following the instructions on th
First, the Postgresql service must be enabled in the NixOS configuration
```nix
services.postgresql = {
enable = true;
package = pkgs.postgresql_13;
};
{
services.postgresql = {
enable = true;
package = pkgs.postgresql_13;
};
}
```
and activated with the usual
```ShellSession
@ -39,42 +41,44 @@ In this section we will enable the Pleroma service only locally, so its configur
This is an example of configuration, where [](#opt-services.pleroma.configs) option contains the content of the file `config.exs`, generated [in the first section](#module-services-pleroma-generate-config), but with the secrets (database password, endpoint secret key, salts, etc.) removed. Removing secrets is important, because otherwise they will be stored publicly in the Nix store.
```nix
services.pleroma = {
enable = true;
secretConfigFile = "/var/lib/pleroma/secrets.exs";
configs = [
''
import Config
{
services.pleroma = {
enable = true;
secretConfigFile = "/var/lib/pleroma/secrets.exs";
configs = [
''
import Config
config :pleroma, Pleroma.Web.Endpoint,
url: [host: "pleroma.example.net", scheme: "https", port: 443],
http: [ip: {127, 0, 0, 1}, port: 4000]
config :pleroma, Pleroma.Web.Endpoint,
url: [host: "pleroma.example.net", scheme: "https", port: 443],
http: [ip: {127, 0, 0, 1}, port: 4000]
config :pleroma, :instance,
name: "Test",
email: "admin@example.net",
notify_email: "admin@example.net",
limit: 5000,
registrations_open: true
config :pleroma, :instance,
name: "Test",
email: "admin@example.net",
notify_email: "admin@example.net",
limit: 5000,
registrations_open: true
config :pleroma, :media_proxy,
enabled: false,
redirect_on_failure: true
config :pleroma, :media_proxy,
enabled: false,
redirect_on_failure: true
config :pleroma, Pleroma.Repo,
adapter: Ecto.Adapters.Postgres,
username: "pleroma",
database: "pleroma",
hostname: "localhost"
config :pleroma, Pleroma.Repo,
adapter: Ecto.Adapters.Postgres,
username: "pleroma",
database: "pleroma",
hostname: "localhost"
# Configure web push notifications
config :web_push_encryption, :vapid_details,
subject: "mailto:admin@example.net"
# Configure web push notifications
config :web_push_encryption, :vapid_details,
subject: "mailto:admin@example.net"
# ... TO CONTINUE ...
''
];
};
# ... TO CONTINUE ...
''
];
};
}
```
Secrets must be moved into a file pointed by [](#opt-services.pleroma.secretConfigFile), in our case `/var/lib/pleroma/secrets.exs`. This file can be created copying the previously generated `config.exs` file and then removing all the settings, except the secrets. This is an example
@ -122,59 +126,61 @@ $ pleroma_ctl user new <nickname> <email> --admin --moderator --password <passw
In this configuration, Pleroma is listening only on the local port 4000. Nginx can be configured as a Reverse Proxy, for forwarding requests from public ports to the Pleroma service. This is an example of configuration, using
[Let's Encrypt](https://letsencrypt.org/) for the TLS certificates
```nix
security.acme = {
email = "root@example.net";
acceptTerms = true;
};
{
security.acme = {
email = "root@example.net";
acceptTerms = true;
};
services.nginx = {
enable = true;
addSSL = true;
services.nginx = {
enable = true;
addSSL = true;
recommendedTlsSettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedTlsSettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedProxySettings = false;
# NOTE: if enabled, the NixOS proxy optimizations will override the Pleroma
# specific settings, and they will enter in conflict.
recommendedProxySettings = false;
# NOTE: if enabled, the NixOS proxy optimizations will override the Pleroma
# specific settings, and they will enter in conflict.
virtualHosts = {
"pleroma.example.net" = {
http2 = true;
enableACME = true;
forceSSL = true;
virtualHosts = {
"pleroma.example.net" = {
http2 = true;
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:4000";
locations."/" = {
proxyPass = "http://127.0.0.1:4000";
extraConfig = ''
etag on;
gzip on;
extraConfig = ''
etag on;
gzip on;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'POST, PUT, DELETE, GET, PATCH, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Idempotency-Key' always;
add_header 'Access-Control-Expose-Headers' 'Link, X-RateLimit-Reset, X-RateLimit-Limit, X-RateLimit-Remaining, X-Request-Id' always;
if ($request_method = OPTIONS) {
return 204;
}
add_header X-XSS-Protection "1; mode=block";
add_header X-Permitted-Cross-Domain-Policies none;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy same-origin;
add_header X-Download-Options noopen;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'POST, PUT, DELETE, GET, PATCH, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Idempotency-Key' always;
add_header 'Access-Control-Expose-Headers' 'Link, X-RateLimit-Reset, X-RateLimit-Limit, X-RateLimit-Remaining, X-Request-Id' always;
if ($request_method = OPTIONS) {
return 204;
}
add_header X-XSS-Protection "1; mode=block";
add_header X-Permitted-Cross-Domain-Policies none;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy same-origin;
add_header X-Download-Options noopen;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
client_max_body_size 16m;
# NOTE: increase if users need to upload very big files
'';
client_max_body_size 16m;
# NOTE: increase if users need to upload very big files
'';
};
};
};
};
};
}
```

View file

@ -26,24 +26,26 @@ A good configuration to start with, including a
endpoint as well as a [HTTP File Upload](https://xmpp.org/extensions/xep-0363.html)
endpoint will look like this:
```nix
services.prosody = {
enable = true;
admins = [ "root@example.org" ];
ssl.cert = "/var/lib/acme/example.org/fullchain.pem";
ssl.key = "/var/lib/acme/example.org/key.pem";
virtualHosts."example.org" = {
enabled = true;
domain = "example.org";
ssl.cert = "/var/lib/acme/example.org/fullchain.pem";
ssl.key = "/var/lib/acme/example.org/key.pem";
{
services.prosody = {
enable = true;
admins = [ "root@example.org" ];
ssl.cert = "/var/lib/acme/example.org/fullchain.pem";
ssl.key = "/var/lib/acme/example.org/key.pem";
virtualHosts."example.org" = {
enabled = true;
domain = "example.org";
ssl.cert = "/var/lib/acme/example.org/fullchain.pem";
ssl.key = "/var/lib/acme/example.org/key.pem";
};
muc = [ {
domain = "conference.example.org";
} ];
uploadHttp = {
domain = "upload.example.org";
};
};
muc = [ {
domain = "conference.example.org";
} ];
uploadHttp = {
domain = "upload.example.org";
};
};
}
```
## Let's Encrypt Configuration {#module-services-prosody-letsencrypt}
@ -58,15 +60,17 @@ certificate by leveraging the ACME
Provided the setup detailed in the previous section, you'll need the following acme configuration to generate
a TLS certificate for the three endponits:
```nix
security.acme = {
email = "root@example.org";
acceptTerms = true;
certs = {
"example.org" = {
webroot = "/var/www/example.org";
email = "root@example.org";
extraDomainNames = [ "conference.example.org" "upload.example.org" ];
{
security.acme = {
email = "root@example.org";
acceptTerms = true;
certs = {
"example.org" = {
webroot = "/var/www/example.org";
email = "root@example.org";
extraDomainNames = [ "conference.example.org" "upload.example.org" ];
};
};
};
};
}
```

View file

@ -7,7 +7,9 @@ Meilisearch is a lightweight, fast and powerful search engine. Think elastic sea
the minimum to start meilisearch is
```nix
services.meilisearch.enable = true;
{
services.meilisearch.enable = true;
}
```
this will start the http server included with meilisearch on port 7700.

View file

@ -19,21 +19,23 @@ be run behind a HTTP proxy on `fediverse.example.com`.
```nix
services.akkoma.enable = true;
services.akkoma.config = {
":pleroma" = {
":instance" = {
name = "My Akkoma instance";
description = "More detailed description";
email = "admin@example.com";
registration_open = false;
};
{
services.akkoma.enable = true;
services.akkoma.config = {
":pleroma" = {
":instance" = {
name = "My Akkoma instance";
description = "More detailed description";
email = "admin@example.com";
registration_open = false;
};
"Pleroma.Web.Endpoint" = {
url.host = "fediverse.example.com";
"Pleroma.Web.Endpoint" = {
url.host = "fediverse.example.com";
};
};
};
};
}
```
Please refer to the [configuration cheat sheet](https://docs.akkoma.dev/stable/configuration/cheatsheet/)
@ -55,19 +57,21 @@ Although it is possible to expose Akkoma directly, it is common practice to oper
HTTP reverse proxy such as nginx.
```nix
services.akkoma.nginx = {
enableACME = true;
forceSSL = true;
};
{
services.akkoma.nginx = {
enableACME = true;
forceSSL = true;
};
services.nginx = {
enable = true;
services.nginx = {
enable = true;
clientMaxBodySize = "16m";
recommendedTlsSettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
};
clientMaxBodySize = "16m";
recommendedTlsSettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
};
}
```
Please refer to [](#module-security-acme) for details on how to provision an SSL/TLS certificate.
@ -78,51 +82,53 @@ Without the media proxy function, Akkoma does not store any remote media like pi
locally, and clients have to fetch them directly from the source server.
```nix
# Enable nginx slice module distributed with Tengine
services.nginx.package = pkgs.tengine;
{
# Enable nginx slice module distributed with Tengine
services.nginx.package = pkgs.tengine;
# Enable media proxy
services.akkoma.config.":pleroma".":media_proxy" = {
enabled = true;
proxy_opts.redirect_on_failure = true;
};
# Adjust the persistent cache size as needed:
# Assuming an average object size of 128 KiB, around 1 MiB
# of memory is required for the key zone per GiB of cache.
# Ensure that the cache directory exists and is writable by nginx.
services.nginx.commonHttpConfig = ''
proxy_cache_path /var/cache/nginx/cache/akkoma-media-cache
levels= keys_zone=akkoma_media_cache:16m max_size=16g
inactive=1y use_temp_path=off;
'';
services.akkoma.nginx = {
locations."/proxy" = {
proxyPass = "http://unix:/run/akkoma/socket";
extraConfig = ''
proxy_cache akkoma_media_cache;
# Cache objects in slices of 1 MiB
slice 1m;
proxy_cache_key $host$uri$is_args$args$slice_range;
proxy_set_header Range $slice_range;
# Decouple proxy and upstream responses
proxy_buffering on;
proxy_cache_lock on;
proxy_ignore_client_abort on;
# Default cache times for various responses
proxy_cache_valid 200 1y;
proxy_cache_valid 206 301 304 1h;
# Allow serving of stale items
proxy_cache_use_stale error timeout invalid_header updating;
'';
# Enable media proxy
services.akkoma.config.":pleroma".":media_proxy" = {
enabled = true;
proxy_opts.redirect_on_failure = true;
};
};
# Adjust the persistent cache size as needed:
# Assuming an average object size of 128 KiB, around 1 MiB
# of memory is required for the key zone per GiB of cache.
# Ensure that the cache directory exists and is writable by nginx.
services.nginx.commonHttpConfig = ''
proxy_cache_path /var/cache/nginx/cache/akkoma-media-cache
levels= keys_zone=akkoma_media_cache:16m max_size=16g
inactive=1y use_temp_path=off;
'';
services.akkoma.nginx = {
locations."/proxy" = {
proxyPass = "http://unix:/run/akkoma/socket";
extraConfig = ''
proxy_cache akkoma_media_cache;
# Cache objects in slices of 1 MiB
slice 1m;
proxy_cache_key $host$uri$is_args$args$slice_range;
proxy_set_header Range $slice_range;
# Decouple proxy and upstream responses
proxy_buffering on;
proxy_cache_lock on;
proxy_ignore_client_abort on;
# Default cache times for various responses
proxy_cache_valid 200 1y;
proxy_cache_valid 206 301 304 1h;
# Allow serving of stale items
proxy_cache_use_stale error timeout invalid_header updating;
'';
};
};
}
```
#### Prefetch remote media {#modules-services-akkoma-prefetch-remote-media}
@ -132,10 +138,12 @@ fetches all media associated with a post through the media proxy, as soon as the
received by the instance.
```nix
services.akkoma.config.":pleroma".":mrf".policies =
map (pkgs.formats.elixirConf { }).lib.mkRaw [
"Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy"
];
{
services.akkoma.config.":pleroma".":mrf".policies =
map (pkgs.formats.elixirConf { }).lib.mkRaw [
"Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy"
];
}
```
#### Media previews {#modules-services-akkoma-media-previews}
@ -143,11 +151,13 @@ services.akkoma.config.":pleroma".":mrf".policies =
Akkoma can generate previews for media.
```nix
services.akkoma.config.":pleroma".":media_preview_proxy" = {
enabled = true;
thumbnail_max_width = 1920;
thumbnail_max_height = 1080;
};
{
services.akkoma.config.":pleroma".":media_preview_proxy" = {
enabled = true;
thumbnail_max_width = 1920;
thumbnail_max_height = 1080;
};
}
```
## Frontend management {#modules-services-akkoma-frontend-management}
@ -160,29 +170,31 @@ The following example overrides the primary frontends default configuration u
derivation.
```nix
services.akkoma.frontends.primary.package = pkgs.runCommand "akkoma-fe" {
config = builtins.toJSON {
expertLevel = 1;
collapseMessageWithSubject = false;
stopGifs = false;
replyVisibility = "following";
webPushHideIfCW = true;
hideScopeNotice = true;
renderMisskeyMarkdown = false;
hideSiteFavicon = true;
postContentType = "text/markdown";
showNavShortcuts = false;
};
nativeBuildInputs = with pkgs; [ jq xorg.lndir ];
passAsFile = [ "config" ];
} ''
mkdir $out
lndir ${pkgs.akkoma-frontends.akkoma-fe} $out
{
services.akkoma.frontends.primary.package = pkgs.runCommand "akkoma-fe" {
config = builtins.toJSON {
expertLevel = 1;
collapseMessageWithSubject = false;
stopGifs = false;
replyVisibility = "following";
webPushHideIfCW = true;
hideScopeNotice = true;
renderMisskeyMarkdown = false;
hideSiteFavicon = true;
postContentType = "text/markdown";
showNavShortcuts = false;
};
nativeBuildInputs = with pkgs; [ jq xorg.lndir ];
passAsFile = [ "config" ];
} ''
mkdir $out
lndir ${pkgs.akkoma-frontends.akkoma-fe} $out
rm $out/static/config.json
jq -s add ${pkgs.akkoma-frontends.akkoma-fe}/static/config.json ${config} \
>$out/static/config.json
'';
rm $out/static/config.json
jq -s add ${pkgs.akkoma-frontends.akkoma-fe}/static/config.json ${config} \
>$out/static/config.json
'';
}
```
## Federation policies {#modules-services-akkoma-federation-policies}
@ -198,28 +210,30 @@ of the fediverse and providing a pleasant experience to the users of an instance
```nix
services.akkoma.config.":pleroma" = with (pkgs.formats.elixirConf { }).lib; {
":mrf".policies = map mkRaw [
"Pleroma.Web.ActivityPub.MRF.SimplePolicy"
];
{
services.akkoma.config.":pleroma" = with (pkgs.formats.elixirConf { }).lib; {
":mrf".policies = map mkRaw [
"Pleroma.Web.ActivityPub.MRF.SimplePolicy"
];
":mrf_simple" = {
# Tag all media as sensitive
media_nsfw = mkMap {
"nsfw.weird.kinky" = "Untagged NSFW content";
};
":mrf_simple" = {
# Tag all media as sensitive
media_nsfw = mkMap {
"nsfw.weird.kinky" = "Untagged NSFW content";
};
# Reject all activities except deletes
reject = mkMap {
"kiwifarms.cc" = "Persistent harassment of users, no moderation";
};
# Reject all activities except deletes
reject = mkMap {
"kiwifarms.cc" = "Persistent harassment of users, no moderation";
};
# Force posts to be visible by followers only
followers_only = mkMap {
"beta.birdsite.live" = "Avoid polluting timelines with Twitter posts";
# Force posts to be visible by followers only
followers_only = mkMap {
"beta.birdsite.live" = "Avoid polluting timelines with Twitter posts";
};
};
};
};
}
```
## Upload filters {#modules-services-akkoma-upload-filters}
@ -228,12 +242,14 @@ This example strips GPS and location metadata from uploads, deduplicates them an
the file name.
```nix
services.akkoma.config.":pleroma"."Pleroma.Upload".filters =
map (pkgs.formats.elixirConf { }).lib.mkRaw [
"Pleroma.Upload.Filter.Exiftool"
"Pleroma.Upload.Filter.Dedupe"
"Pleroma.Upload.Filter.AnonymizeFilename"
];
{
services.akkoma.config.":pleroma"."Pleroma.Upload".filters =
map (pkgs.formats.elixirConf { }).lib.mkRaw [
"Pleroma.Upload.Filter.Exiftool"
"Pleroma.Upload.Filter.Dedupe"
"Pleroma.Upload.Filter.AnonymizeFilename"
];
}
```
## Migration from Pleroma {#modules-services-akkoma-migration-pleroma}
@ -286,9 +302,11 @@ To reuse the Pleroma data in place, disable Pleroma and enable Akkoma, pointi
Pleroma database and upload directory.
```nix
# Adjust these settings according to the database name and upload directory path used by Pleroma
services.akkoma.config.":pleroma"."Pleroma.Repo".database = "pleroma";
services.akkoma.config.":pleroma".":instance".upload_dir = "/var/lib/pleroma/uploads";
{
# Adjust these settings according to the database name and upload directory path used by Pleroma
services.akkoma.config.":pleroma"."Pleroma.Repo".database = "pleroma";
services.akkoma.config.":pleroma".":instance".upload_dir = "/var/lib/pleroma/uploads";
}
```
Please keep in mind that after the Akkoma service has been started, any migrations applied by
@ -304,7 +322,9 @@ details.
The Akkoma systemd service may be confined to a chroot with
```nix
services.systemd.akkoma.confinement.enable = true;
{
services.systemd.akkoma.confinement.enable = true;
}
```
Confinement of services is not generally supported in NixOS and therefore disabled by default.

View file

@ -7,19 +7,21 @@ modern and open source discussion platform.
A minimal configuration using Let's Encrypt for TLS certificates looks like this:
```nix
services.discourse = {
enable = true;
hostname = "discourse.example.com";
admin = {
email = "admin@example.com";
username = "admin";
fullName = "Administrator";
passwordFile = "/path/to/password_file";
{
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";
};
secretKeyBaseFile = "/path/to/secret_key_base_file";
};
security.acme.email = "me@example.com";
security.acme.acceptTerms = true;
security.acme.email = "me@example.com";
security.acme.acceptTerms = true;
}
```
Provided a proper DNS setup, you'll be able to connect to the
@ -35,19 +37,21 @@ and [](#opt-services.discourse.sslCertificateKey)
options:
```nix
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";
{
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";
};
secretKeyBaseFile = "/path/to/secret_key_base_file";
};
}
```
## Database access {#module-services-discourse-database}
@ -81,26 +85,28 @@ A basic setup which assumes you want to use your configured
email domain can be done like this:
```nix
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";
{
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";
};
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
@ -163,43 +169,45 @@ Discourse instance and enables
GitHub login in the site settings,
and changes a few request limits in the backend settings:
```nix
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)";
{
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";
};
login = {
enable_github_logins = true;
github_client_id = "a2f6dfe838cb3206ce20";
github_client_secret._secret = /run/keys/discourse_github_client_secret;
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";
};
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
@ -254,33 +262,35 @@ plugins, and disable `discourse-spoiler-alert`
by default:
```nix
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;
{
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";
};
secretKeyBaseFile = "/path/to/secret_key_base_file";
};
}
```

View file

@ -8,17 +8,19 @@ The following configuration sets up the PostgreSQL as database backend and binds
GoToSocial to `127.0.0.1:8080`, expecting to be run behind a HTTP proxy on `gotosocial.example.com`.
```nix
services.gotosocial = {
enable = true;
setupPostgresqlDB = true;
settings = {
application-name = "My GoToSocial";
host = "gotosocial.example.com";
protocol = "https";
bind-address = "127.0.0.1";
port = 8080;
{
services.gotosocial = {
enable = true;
setupPostgresqlDB = true;
settings = {
application-name = "My GoToSocial";
host = "gotosocial.example.com";
protocol = "https";
bind-address = "127.0.0.1";
port = 8080;
};
};
};
}
```
Please refer to the [GoToSocial Documentation](https://docs.gotosocial.org/en/latest/configuration/general/)
@ -30,24 +32,26 @@ Although it is possible to expose GoToSocial directly, it is common practice to
HTTP reverse proxy such as nginx.
```nix
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.nginx = {
enable = true;
clientMaxBodySize = "40M";
virtualHosts = with config.services.gotosocial.settings; {
"${host}" = {
enableACME = true;
forceSSL = true;
locations = {
"/" = {
recommendedProxySettings = true;
proxyWebsockets = true;
proxyPass = "http://${bind-address}:${toString port}";
{
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.nginx = {
enable = true;
clientMaxBodySize = "40M";
virtualHosts = with config.services.gotosocial.settings; {
"${host}" = {
enableACME = true;
forceSSL = true;
locations = {
"/" = {
recommendedProxySettings = true;
proxyWebsockets = true;
proxyPass = "http://${bind-address}:${toString port}";
};
};
};
};
};
};
}
```
Please refer to [](#module-security-acme) for details on how to provision an SSL/TLS certificate.

View file

@ -127,15 +127,17 @@ should be set to. See the description of
A basic configuration with some custom settings could look like this:
```nix
services.keycloak = {
enable = true;
settings = {
hostname = "keycloak.example.com";
hostname-strict-backchannel = true;
{
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";
};
initialAdminPassword = "e6Wcm0RrtegMEHl"; # change on first login
sslCertificate = "/run/keys/ssl_cert";
sslCertificateKey = "/run/keys/ssl_key";
database.passwordFile = "/run/keys/db_password";
};
}
```

View file

@ -7,13 +7,15 @@ Lemmy is a federated alternative to reddit in rust.
the minimum to start lemmy is
```nix
services.lemmy = {
enable = true;
settings = {
hostname = "lemmy.union.rocks";
database.createLocally = true;
{
services.lemmy = {
enable = true;
settings = {
hostname = "lemmy.union.rocks";
database.createLocally = true;
};
caddy.enable = true;
};
caddy.enable = true;
}
```

View file

@ -7,7 +7,9 @@ pict-rs is a a simple image hosting service.
the minimum to start pict-rs is
```nix
services.pict-rs.enable = true;
{
services.pict-rs.enable = true;
}
```
this will start the http server on port 8080 by default.

View file

@ -100,7 +100,7 @@ Not all the configuration options are available directly in this module, but you
server = {
port = 4567;
autoDownloadNewChapters = false;
maxSourcesInParallel" = 6;
maxSourcesInParallel = 6;
extensionRepos = [
"https://raw.githubusercontent.com/MY_ACCOUNT/MY_REPO/repo/index.min.json"
];

View file

@ -9,8 +9,10 @@ All of the core apps, optional apps, games, and core developer tools from GNOME
To enable the GNOME desktop use:
```nix
services.xserver.desktopManager.gnome.enable = true;
services.xserver.displayManager.gdm.enable = true;
{
services.xserver.desktopManager.gnome.enable = true;
services.xserver.displayManager.gdm.enable = true;
}
```
::: {.note}
@ -24,7 +26,9 @@ The default applications used in NixOS are very minimal, inspired by the default
If youd like to only use the GNOME desktop and not the apps, you can disable them with:
```nix
services.gnome.core-utilities.enable = false;
{
services.gnome.core-utilities.enable = false;
}
```
and none of them will be installed.
@ -38,8 +42,10 @@ Note that this mechanism can only exclude core utilities, games and core develop
It is also possible to disable many of the [core services](https://github.com/NixOS/nixpkgs/blob/b8ec4fd2a4edc4e30d02ba7b1a2cc1358f3db1d5/nixos/modules/services/x11/desktop-managers/gnome.nix#L329-L348). For example, if you do not need indexing files, you can disable Tracker with:
```nix
services.gnome.tracker-miners.enable = false;
services.gnome.tracker.enable = false;
{
services.gnome.tracker-miners.enable = false;
services.gnome.tracker.enable = false;
}
```
Note, however, that doing so is not supported and might break some applications. Notably, GNOME Music cannot work without Tracker.
@ -49,7 +55,9 @@ Note, however, that doing so is not supported and might break some applications.
You can install all of the GNOME games with:
```nix
services.gnome.games.enable = true;
{
services.gnome.games.enable = true;
}
```
### GNOME core developer tools {#sec-gnome-core-developer-tools}
@ -57,7 +65,9 @@ services.gnome.games.enable = true;
You can install GNOME core developer tools with:
```nix
services.gnome.core-developer-tools.enable = true;
{
services.gnome.core-developer-tools.enable = true;
}
```
## Enabling GNOME Flashback {#sec-gnome-enable-flashback}
@ -65,7 +75,9 @@ services.gnome.core-developer-tools.enable = true;
GNOME Flashback provides a desktop environment based on the classic GNOME 2 architecture. You can enable the default GNOME Flashback session, which uses the Metacity window manager, with:
```nix
services.xserver.desktopManager.gnome.flashback.enableMetacity = true;
{
services.xserver.desktopManager.gnome.flashback.enableMetacity = true;
}
```
It is also possible to create custom sessions that replace Metacity with a different window manager using [](#opt-services.xserver.desktopManager.gnome.flashback.customSessions).
@ -73,14 +85,16 @@ It is also possible to create custom sessions that replace Metacity with a diffe
The following example uses `xmonad` window manager:
```nix
services.xserver.desktopManager.gnome.flashback.customSessions = [
{
wmName = "xmonad";
wmLabel = "XMonad";
wmCommand = "${pkgs.haskellPackages.xmonad}/bin/xmonad";
enableGnomePanel = false;
}
];
{
services.xserver.desktopManager.gnome.flashback.customSessions = [
{
wmName = "xmonad";
wmLabel = "XMonad";
wmCommand = "${pkgs.haskellPackages.xmonad}/bin/xmonad";
enableGnomePanel = false;
}
];
}
```
## Icons and GTK Themes {#sec-gnome-icons-and-gtk-themes}
@ -105,11 +119,13 @@ Some packages that include Shell extensions, like `gnome.gpaste`, dont have t
You can install them like any other package:
```nix
environment.systemPackages = [
gnomeExtensions.dash-to-dock
gnomeExtensions.gsconnect
gnomeExtensions.mpris-indicator-button
];
{
environment.systemPackages = [
gnomeExtensions.dash-to-dock
gnomeExtensions.gsconnect
gnomeExtensions.mpris-indicator-button
];
}
```
Unfortunately, we lack a way for these to be managed in a completely declarative way.
@ -137,22 +153,24 @@ You can use `dconf-editor` tool to explore which GSettings you can set.
### Example {#sec-gnome-gsettings-overrides-example}
```nix
services.xserver.desktopManager.gnome = {
extraGSettingsOverrides = ''
# Change default background
[org.gnome.desktop.background]
picture-uri='file://${pkgs.nixos-artwork.wallpapers.mosaic-blue.gnomeFilePath}'
{
services.xserver.desktopManager.gnome = {
extraGSettingsOverrides = ''
# Change default background
[org.gnome.desktop.background]
picture-uri='file://${pkgs.nixos-artwork.wallpapers.mosaic-blue.gnomeFilePath}'
# Favorite apps in gnome-shell
[org.gnome.shell]
favorite-apps=['org.gnome.Console.desktop', 'org.gnome.Nautilus.desktop']
'';
# Favorite apps in gnome-shell
[org.gnome.shell]
favorite-apps=['org.gnome.Console.desktop', 'org.gnome.Nautilus.desktop']
'';
extraGSettingsOverridePackages = [
pkgs.gsettings-desktop-schemas # for org.gnome.desktop
pkgs.gnome.gnome-shell # for org.gnome.shell
];
};
extraGSettingsOverridePackages = [
pkgs.gsettings-desktop-schemas # for org.gnome.desktop
pkgs.gnome.gnome-shell # for org.gnome.shell
];
};
}
```
## Frequently Asked Questions {#sec-gnome-faq}

View file

@ -6,16 +6,22 @@ Pantheon is the desktop environment created for the elementary OS distribution.
All of Pantheon is working in NixOS and the applications should be available, aside from a few [exceptions](https://github.com/NixOS/nixpkgs/issues/58161). To enable Pantheon, set
```nix
services.xserver.desktopManager.pantheon.enable = true;
{
services.xserver.desktopManager.pantheon.enable = true;
}
```
This automatically enables LightDM and Pantheon's LightDM greeter. If you'd like to disable this, set
```nix
services.xserver.displayManager.lightdm.greeters.pantheon.enable = false;
services.xserver.displayManager.lightdm.enable = false;
{
services.xserver.displayManager.lightdm.greeters.pantheon.enable = false;
services.xserver.displayManager.lightdm.enable = false;
}
```
but please be aware using Pantheon without LightDM as a display manager will break screenlocking from the UI. The NixOS module for Pantheon installs all of Pantheon's default applications. If you'd like to not install Pantheon's apps, set
```nix
services.pantheon.apps.enable = false;
{
services.pantheon.apps.enable = false;
}
```
You can also use [](#opt-environment.pantheon.excludePackages) to remove any other app (like `elementary-mail`).
@ -34,25 +40,28 @@ wingpanel-with-indicators.override {
indicators = [
pkgs.some-special-indicator
];
};
}
```
```nix
switchboard-with-plugs.override {
plugs = [
pkgs.some-special-plug
];
};
}
```
please note that, like how the NixOS options describe these as extra plugins, this would only add to the default plugins included with the programs. If for some reason you'd like to configure which plugins to use exactly, both packages have an argument for this:
```nix
wingpanel-with-indicators.override {
useDefaultIndicators = false;
indicators = specialListOfIndicators;
};
}
```
```nix
switchboard-with-plugs.override {
useDefaultPlugs = false;
plugs = specialListOfPlugs;
};
}
```
this could be most useful for testing a particular plug-in in isolation.

View file

@ -40,12 +40,16 @@ For more complete documentation on how to generate a secret with clevis, see the
In order to activate unattended decryption of a resource at boot, enable the `clevis` module:
```nix
boot.initrd.clevis.enable = true;
{
boot.initrd.clevis.enable = true;
}
```
Then, specify the device you want to decrypt using a given clevis secret. Clevis will automatically try to decrypt the device at boot and will fallback to interactive unlocking if the decryption policy is not fulfilled.
```nix
boot.initrd.clevis.devices."/dev/nvme0n1p1".secretFile = ./nvme0n1p1.jwe;
{
boot.initrd.clevis.devices."/dev/nvme0n1p1".secretFile = ./nvme0n1p1.jwe;
}
```
Only `bcachefs`, `zfs` and `luks` encrypted devices are supported at this time.