1
0
Fork 0

switch to nixos-render-docs (#34)

fixes #33
This commit is contained in:
Pierre Penninckx 2023-12-04 00:33:16 -08:00 committed by GitHub
parent 0242ae26c4
commit a63b0a6e2e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 343 additions and 259 deletions

View file

@ -1,118 +0,0 @@
# Monitoring Block
This block sets up the monitoring stack for Self Host Blocks. It is composed of:
- Grafana as the dashboard frontend.
- Prometheus as the database for metrics.
- Loki as the database for logs.
## Configuration
```nix
shb.monitoring = {
enable = true;
subdomain = "grafana";
inherit domain;
contactPoints = [ "me@example.com" ];
adminPasswordFile = config.sops.secrets."monitoring/admin_password".path;
secretKeyFile = config.sops.secrets."monitoring/secret_key".path;
};
sops.secrets."monitoring/admin_password" = {
sopsFile = ./secrets.yaml;
mode = "0400";
owner = "grafana";
group = "grafana";
restartUnits = [ "grafana.service" ];
};
sops.secrets."monitoring/secret_key" = {
sopsFile = ./secrets.yaml;
mode = "0400";
owner = "grafana";
group = "grafana";
restartUnits = [ "grafana.service" ];
};
```
With that, Grafana, Prometheus, Loki and Promtail are setup! You can access `Grafana` at
`grafana.example.com` with user `admin` and password ``.
I recommend adding a STMP server configuration so you receive alerts by email:
```nix
shb.monitoring.smtp = {
from_address = "grafana@$example.com";
from_name = "Grafana";
host = "smtp.mailgun.org";
port = 587;
username = "postmaster@mg.example.com";
passwordFile = config.sops.secrets."monitoring/smtp".path;
};
sops.secrets."monitoring/secret_key" = {
sopsFile = ./secrets.yaml;
mode = "0400";
owner = "grafana";
group = "grafana";
restartUnits = [ "grafana.service" ];
};
```
Since all logs are now stored in Loki, you can probably reduce the systemd journal retention
time with:
```nix
# See https://www.freedesktop.org/software/systemd/man/journald.conf.html#SystemMaxUse=
services.journald.extraConfig = ''
SystemMaxUse=2G
SystemKeepFree=4G
SystemMaxFileSize=100M
MaxFileSec=day
'';
```
## Provisioning
Self Host Blocks will create automatically the following resources:
- For Grafana:
- datasources
- dashboards
- contact points
- notification policies
- alerts
- For Prometheus, the following exporters and related scrapers:
- node
- smartctl
- nginx
- For Loki, the following exporters and related scrapers:
- systemd
Those resources are namespaced as appropriate under the Self Host Blocks namespace:
![](../assets/monitoring_grafana_folder.png)
## Errors Dashboard
This dashboard is meant to be the first stop to understand why a service is misbehaving.
![](../assets/monitoring_grafana_dashboards_Errors_1.png)
![](../assets/monitoring_grafana_dashboards_Errors_2.png)
The yellow and red dashed vertical bars correspond to the [Requests Error Budget
Alert](#requests-error-budget-alert) firing.
## Performance Dashboard
This dashboard is meant to be the first stop to understand why a service is performing poorly.
![](../assets/monitoring_grafana_dashboards_Performance_1.png)
![](../assets/monitoring_grafana_dashboards_Performance_2.png)
## Requests Error Budget Alert
This alert will fire when the ratio between number of requests getting a 5XX response from a service
and the total requests to that service exceeds 1%.
![](../assets/monitoring_grafana_alert_rules_5xx_1.png)
![](../assets/monitoring_grafana_alert_rules_5xx_2.png)

View file

@ -0,0 +1,7 @@
# Requests Error Budget Alert {#blocks-monitoring-budget-alerts}
This alert will fire when the ratio between number of requests getting a 5XX response from a service
and the total requests to that service exceeds 1%.
![](./assets/alert_rules_5xx_1.png)
![](./assets/alert_rules_5xx_2.png)

View file

Before

Width:  |  Height:  |  Size: 233 KiB

After

Width:  |  Height:  |  Size: 233 KiB

View file

Before

Width:  |  Height:  |  Size: 246 KiB

After

Width:  |  Height:  |  Size: 246 KiB

View file

Before

Width:  |  Height:  |  Size: 444 KiB

After

Width:  |  Height:  |  Size: 444 KiB

View file

Before

Width:  |  Height:  |  Size: 441 KiB

After

Width:  |  Height:  |  Size: 441 KiB

View file

Before

Width:  |  Height:  |  Size: 628 KiB

After

Width:  |  Height:  |  Size: 628 KiB

View file

Before

Width:  |  Height:  |  Size: 267 KiB

After

Width:  |  Height:  |  Size: 267 KiB

View file

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View file

@ -0,0 +1,64 @@
# Configuration {#blocks-monitoring-configuration}
```nix
shb.monitoring = {
enable = true;
subdomain = "grafana";
inherit domain;
contactPoints = [ "me@example.com" ];
adminPasswordFile = config.sops.secrets."monitoring/admin_password".path;
secretKeyFile = config.sops.secrets."monitoring/secret_key".path;
};
sops.secrets."monitoring/admin_password" = {
sopsFile = ./secrets.yaml;
mode = "0400";
owner = "grafana";
group = "grafana";
restartUnits = [ "grafana.service" ];
};
sops.secrets."monitoring/secret_key" = {
sopsFile = ./secrets.yaml;
mode = "0400";
owner = "grafana";
group = "grafana";
restartUnits = [ "grafana.service" ];
};
```
With that, Grafana, Prometheus, Loki and Promtail are setup! You can access `Grafana` at
`grafana.example.com` with user `admin` and password ``.
I recommend adding a STMP server configuration so you receive alerts by email:
```nix
shb.monitoring.smtp = {
from_address = "grafana@$example.com";
from_name = "Grafana";
host = "smtp.mailgun.org";
port = 587;
username = "postmaster@mg.example.com";
passwordFile = config.sops.secrets."monitoring/smtp".path;
};
sops.secrets."monitoring/secret_key" = {
sopsFile = ./secrets.yaml;
mode = "0400";
owner = "grafana";
group = "grafana";
restartUnits = [ "grafana.service" ];
};
```
Since all logs are now stored in Loki, you can probably reduce the systemd journal retention
time with:
```nix
# See https://www.freedesktop.org/software/systemd/man/journald.conf.html#SystemMaxUse=
services.journald.extraConfig = ''
SystemMaxUse=2G
SystemKeepFree=4G
SystemMaxFileSize=100M
MaxFileSec=day
'';
```

View file

@ -0,0 +1,9 @@
# Errors Dashboard {#blocks-monitoring-error-dashboard}
This dashboard is meant to be the first stop to understand why a service is misbehaving.
![](./assets/dashboards_Errors_1.png)
![](./assets/dashboards_Errors_2.png)
The yellow and red dashed vertical bars correspond to the [Requests Error Budget
Alert](#blocks-monitoring-budget-alerts) firing.

View file

@ -0,0 +1,6 @@
# Performance Dashboard {#blocks-monitoring-performance-dashboard}
This dashboard is meant to be the first stop to understand why a service is performing poorly.
![Performance Dashboard Top Part](./assets/dashboards_Performance_1.png)
![Performance Dashboard Bottom Part](./assets/dashboards_Performance_2.png)

View file

@ -0,0 +1,17 @@
# Monitoring Block {#blocks-monitoring}
Defined in [`/modules/blocks/monitoring.nix`](@REPO@/modules/blocks/monitoring.nix).
This block sets up the monitoring stack for Self Host Blocks. It is composed of:
- Grafana as the dashboard frontend.
- Prometheus as the database for metrics.
- Loki as the database for logs.
```{=include=} parts
configuration.md
provisioning.md
dashboard-errors.md
dashboard-performance.md
alerts-requests-error-budger.md
```

View file

@ -0,0 +1,20 @@
# Provisioning {#blocks-monitoring-provisioning}
Self Host Blocks will create automatically the following resources:
- For Grafana:
- datasources
- dashboards
- contact points
- notification policies
- alerts
- For Prometheus, the following exporters and related scrapers:
- node
- smartctl
- nginx
- For Loki, the following exporters and related scrapers:
- systemd
Those resources are namespaced as appropriate under the Self Host Blocks namespace:
[](./assets/folder.png)

120
docs/default.nix Normal file
View file

@ -0,0 +1,120 @@
# Taken nearly verbatim from https://github.com/nix-community/home-manager/pull/4673
{ pkgs
, buildPackages
, lib
, nmdsrc
, stdenv
, documentation-highlighter
, nixos-render-docs
, release
, allModules
}:
let
shbPath = toString ./..;
gitHubDeclaration = user: repo: subpath:
let urlRef = "main";
end = if subpath == "" then "" else "/" + subpath;
in {
url = "https://github.com/${user}/${repo}/blob/${urlRef}${end}";
name = "<${repo}${end}>";
};
ghRoot = (gitHubDeclaration "ibizaman" "selfhostblocks" "").url;
buildOptionsDocs = args@{ modules, includeModuleSystemOptions ? true, ... }:
let options = (lib.evalModules { inherit modules; }).options;
in buildPackages.nixosOptionsDoc ({
options = if includeModuleSystemOptions then
options
else
builtins.removeAttrs options [ "_module" ];
transformOptions = opt:
opt // {
# Clean up declaration sites to not refer to the Home Manager
# source tree.
declarations = map (decl:
gitHubDeclaration "ibizaman" "selfhostblocks"
(lib.removePrefix "/" (lib.removePrefix shbPath (toString decl)))) opt.declarations;
};
} // builtins.removeAttrs args [ "modules" "includeModuleSystemOptions" ]);
scrubbedModule = {
_module.args.pkgs = lib.mkForce (nmd.scrubDerivations "pkgs" pkgs);
_module.check = false;
};
optionsDocs = buildOptionsDocs {
modules = allModules ++ [ scrubbedModule ];
variablelistId = "selfhostblocks-options";
includeModuleSystemOptions = false;
};
nmd = import nmdsrc {
inherit lib;
# The DocBook output of `nixos-render-docs` doesn't have the change
# `nmd` uses to work around the broken stylesheets in
# `docbook-xsl-ns`, so we restore the patched version here.
pkgs = pkgs // {
docbook-xsl-ns =
pkgs.docbook-xsl-ns.override { withManOptDedupPatch = true; };
};
};
outputPath = "share/doc/selfhostblocks";
manpage-urls = pkgs.writeText "manpage-urls.json" ''{}'';
in stdenv.mkDerivation {
name = "self-host-blocks-manual";
nativeBuildInputs = [ nixos-render-docs ];
src = ./.;
buildPhase = ''
mkdir -p out/media
mkdir -p out/highlightjs
cp -t out/highlightjs \
${documentation-highlighter}/highlight.pack.js \
${documentation-highlighter}/LICENSE \
${documentation-highlighter}/mono-blue.css \
${documentation-highlighter}/loader.js
substituteInPlace ./options.md \
--replace \
'@OPTIONS_JSON@' \
${optionsDocs.optionsJSON}/share/doc/nixos/options.json
find . -name "*.md" -print0 | \
while IFS= read -r -d ''' f; do
substituteInPlace "''${f}" \
--replace \
'@REPO@' \
"${lib.debug.traceVal ghRoot}"
done
nixos-render-docs manual html \
--manpage-urls ${manpage-urls} \
--media-dir media \
--revision ${lib.trivial.revisionWithDefault release} \
--stylesheet ${nmdsrc}/static/style.css \
--stylesheet ${nmdsrc}/static/highlightjs/tomorrow-night.min.css \
--script ${nmdsrc}/static/highlightjs/highlight.min.js \
--script ${nmdsrc}/static/highlightjs/highlight.load.js \
--toc-depth 1 \
--section-toc-depth 1 \
manual.md \
out/index.html
'';
installPhase = ''
dest="$out/${outputPath}"
mkdir -p "$(dirname "$dest")"
mv out "$dest"
mkdir -p $out/nix-support/
echo "doc manual $dest index.html" >> $out/nix-support/hydra-build-products
'';
}

View file

@ -1,37 +0,0 @@
<!-- Copyright (c) 2019-2022, see AUTHORS. Licensed under MIT License, see LICENSE. -->
<reference xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude">
<title>Self Host Blocks Reference Pages</title>
<info>
<author><personname>Self Host Blocks contributors</personname>
</author>
<copyright><year>2022</year><holder>Self Host Blocks contributors</holder>
</copyright>
</info>
<refentry>
<refmeta>
<refentrytitle><filename>selfhostblocks-options</filename></refentrytitle>
<manvolnum>5</manvolnum>
<refmiscinfo class="source">Self Host Blocks</refmiscinfo>
</refmeta>
<refnamediv>
<refname><filename>selfhostblocks-options</filename>
</refname><refpurpose>Self Host Blocks configuration specification</refpurpose>
</refnamediv>
<refsection>
<title>Description</title>
<para>
This contains the module options available for Self Host Blocks.
</para>
</refsection>
<refsection>
<title>Options</title>
<para>
You can use the following options after importing Self Host Blocks as a flake input, then
importing the default module for your system.
</para>
<xi:include href="./nmd-result/selfhostblocks-options.xml" />
</refsection>
</refentry>
</reference>

24
docs/manual.md Normal file
View file

@ -0,0 +1,24 @@
# Self Host Blocks Manual {#self-host-blocks-manual}
## Version 0.0.1
```{=include=} preface
preface.md
```
```{=include=} parts html:into-file=//blocks-monitoring.html
blocks/monitoring/default.md
```
```{=include=} appendix html:into-file=//options.html
options.md
```
<!-- ```{=include=} appendix html:into-file=//nixos-options.html -->
<!-- nixos-options.md -->
<!-- ``` -->
<!-- ```{=include=} appendix html:into-file=//nix-darwin-options.html -->
<!-- nix-darwin-options.md -->
<!-- ``` -->

View file

@ -1,71 +0,0 @@
<!-- Copyright (c) 2019-2023, see AUTHORS. Licensed under MIT License, see LICENSE. -->
<book 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="book-manual">
<info>
<title>Self Host Blocks manual</title>
</info>
<preface>
<title>Preface</title>
<para>
Complete manual for Self Host Blocks, the building blocks for self-hosting with battery included.
</para>
<para>
If you encounter problems or bugs then please report them on the
<link xlink:href="https://github.com/ibizaman/selfhostblocks/issues">issue tracker</link>.
</para>
</preface>
<appendix xml:id="ch-options">
<title>Self Host Blocks configuration options</title>
<section xml:id="sec-usage">
<title>Usage</title>
<!--
Tags:
<title>
<section xml:id="sec-NAME">
<para>
<filename>
<replaceable>
<varname>
<programlisting language="nix">
-->
<para>
To use these options, import Self Host Blocks as a flake input, then import the default module for your system.
<programlisting language="nix">
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
sops-nix.url = "github:Mic92/sops-nix";
shb.url = "github:ibizaman/selfhostblocks";
shb.inputs.nixpkgs.follows = "nixpkgs";
shb.inputs.sops-nix.follows = "sops-nix";
};
outputs = { self, nixpkgs, shb }: {
nixosConfigurations.machine = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
shb.nixosModules.x86_64-linux.default
./machine.nix
];
};
};
}
</programlisting>
</para>
</section>
<section xml:id="sec-options">
<title>Options</title>
<xi:include href="./nmd-result/selfhostblocks-options.xml" />
</section>
</appendix>
</book>

7
docs/options.md Normal file
View file

@ -0,0 +1,7 @@
# Self Host Blocks Options {#ch-options}
```{=include=} options
id-prefix: opt-
list-id: selfhostblock-options
source: @OPTIONS_JSON@
```

10
docs/preface.md Normal file
View file

@ -0,0 +1,10 @@
# Preface {#preface}
This document is the complete manual for Self Host Blocks, the building blocks for self-hosting with battery included.
Self Host Blocks is hosted on [GitHub](https://github.com/ibizaman/selfhostblocks). If you encounter
problems or bugs then please report them on the [issue
tracker](https://github.com/ibizaman/selfhostblocks/issues).
Feel free to join the dedicated Matrix room
[matrix.org#selfhostblocks](https://matrix.to/#/#selfhostblocks:matrix.org).

View file

@ -14,11 +14,44 @@
outputs = { nixpkgs, nix-flake-tests, flake-utils, nmdsrc, ... }: flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
patches = [
''
From a4d67df38628eaa3e1823af7b7613af3d7ff7555 Mon Sep 17 00:00:00 2001
From: ibizaman <ibizapeanut@gmail.com>
Date: Sun, 3 Dec 2023 21:09:30 -0800
Subject: [PATCH] fix for nixos-render-docs media path
---
.../tools/nix/nixos-render-docs/src/nixos_render_docs/manual.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pkgs/tools/nix/nixos-render-docs/src/nixos_render_docs/manual.py b/pkgs/tools/nix/nixos-render-docs/src/nixos_render_docs/manual.py
index d605dd88b37d..3482cc02c4d1 100644
--- a/pkgs/tools/nix/nixos-render-docs/src/nixos_render_docs/manual.py
+++ b/pkgs/tools/nix/nixos-render-docs/src/nixos_render_docs/manual.py
@@ -506,7 +506,7 @@ class ManualHTMLRenderer(RendererMixin, HTMLRenderer):
in_dir = self._in_dir
for included, path in fragments:
try:
- self._in_dir = (in_dir / path).parent
+ self._in_dir = path.parent
inner.append(self.render(included))
except Exception as e:
raise RuntimeError(f"rendering {path}") from e
--
2.42.0
''
];
originPkgs = nixpkgs.legacyPackages.${system};
patchedNixpkgs = originPkgs.applyPatches {
name = "nixpkgs-patched";
src = nixpkgs;
patches = map (p: originPkgs.writeText "patch" p) patches;
};
nmd = import nmdsrc { inherit pkgs; };
pkgs = import patchedNixpkgs {
inherit system;
};
allModules = [
modules/blocks/authelia.nix
@ -46,36 +79,10 @@
imports = allModules;
};
# Inspiration from https://github.com/nix-community/nix-on-droid/blob/039379abeee67144d4094d80bbdaf183fb2eabe5/docs/default.nix#L22
packages.manualHtml = let
setupModule = {
_module.args.pkgs = pkgs.lib.mkForce (nmd.scrubDerivations "pkgs" pkgs);
_module.check = false;
};
modulesDocs = nmd.buildModulesDocs {
modules = allModules ++ [ setupModule ];
moduleRootPaths = [ ./. ];
mkModuleUrl = path: "https://github.com/ibizaman/selfhostblocks/blob/main/${path}";
channelName = "selfhostblocks";
docBook = { id = "selfhostblocks-options"; optionIdPrefix = "shb-opt"; };
};
manual = nmd.buildDocBookDocs {
pathName = "selfhostblocks";
modulesDocs = [ modulesDocs ];
documentsDirectory = ./docs;
chunkToc = ''
<toc>
<d:tocentry xmlns:d="http://docbook.org/ns/docbook" linkend="book-manual">
<?dbhtml filename="index.html"?>
<d:tocentry linkend="ch-options"><?dbhtml filename="selfhostblocks-options.html"?></d:tocentry>
</d:tocentry>
</toc>
'';
};
in
manual.html;
packages.manualHtml = pkgs.callPackage ./docs {
inherit allModules nmdsrc;
release = "0.0.1";
};
checks =
let

View file

@ -42,28 +42,36 @@ in
};
secrets = lib.mkOption {
description = "Secrets needed by Authelia";
type = lib.types.submodule {
options = {
jwtSecretFile = lib.mkOption {
type = lib.types.str;
description = "File containing the JWT secret.";
};
ldapAdminPasswordFile = lib.mkOption {
type = lib.types.str;
description = "File containing the LDAP admin user password.";
};
sessionSecretFile = lib.mkOption {
type = lib.types.str;
description = "File containing the session secret.";
};
notifierSMTPPasswordFile = lib.mkOption {
type = lib.types.str;
description = "File containing the STMP password for the notifier.";
};
storageEncryptionKeyFile = lib.mkOption {
type = lib.types.str;
description = "File containing the storage encryption key.";
};
identityProvidersOIDCHMACSecretFile = lib.mkOption {
type = lib.types.str;
description = "File containing the identity provider OIDC HMAC secret.";
};
identityProvidersOIDCIssuerPrivateKeyFile = lib.mkOption {
type = lib.types.str;
description = "File containing the identity provider OIDC issuer private key.";
};
};
};

View file

@ -18,6 +18,7 @@ in
{
options.shb.davfs = {
mounts = lib.mkOption {
description = "List of mounts.";
default = [];
type = lib.types.listOf (lib.types.submodule {
options = {

View file

@ -75,6 +75,7 @@ in
};
smtp = lib.mkOption {
description = "SMTP options.";
default = null;
type = lib.types.nullOr (lib.types.submodule {
options = {

View file

@ -21,6 +21,7 @@ in
};
ensures = lib.mkOption {
description = "List of username, database and/or passwords that should be created.";
type = lib.types.listOf (lib.types.submodule {
options = {
username = lib.mkOption {

View file

@ -9,15 +9,18 @@ let
settingsFormat = formatXML {};
moreOptions = {
settings = lib.mkOption {
description = "Specific options for radarr.";
default = {};
type = lib.types.submodule {
freeformType = apps.radarr.settingsFormat.type;
options = {
APIKeyFile = lib.mkOption {
type = lib.types.path;
description = "Path to api key secret file.";
};
LogLevel = lib.mkOption {
type = lib.types.enum ["debug" "info"];
description = "Log level.";
default = "info";
};
};
@ -58,6 +61,7 @@ let
};
OmdbApiKeyFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
description = "File containing the Open Movie Database API key.";
default = null;
};
ProxyType = lib.mkOption {
@ -72,10 +76,12 @@ let
};
ProxyUrl = lib.mkOption {
type = lib.types.nullOr lib.types.str;
description = "URL of the proxy. Ignored if ProxyType is set to -1";
default = null;
};
ProxyPort = lib.mkOption {
type = lib.types.nullOr lib.types.port;
description = "Port of the proxy. Ignored if ProxyType is set to -1";
default = null;
};
};

View file

@ -57,6 +57,7 @@ in
};
smtp = lib.mkOption {
description = "SMTP options.";
type = lib.types.submodule {
options = {
from_address = lib.mkOption {
@ -102,6 +103,7 @@ in
backupConfig = lib.mkOption {
type = lib.types.nullOr lib.types.anything;
description = "Backup configuration of Vaultwarden.";
default = null;
};