diff --git a/README.md b/README.md index 964303b..adfcaee 100644 --- a/README.md +++ b/README.md @@ -171,8 +171,6 @@ is to go to the [All Options][] section of the manual. The services above rely on the following [common blocks][]: -[common blocks]: https://shb.skarabox.com/blocks.html - - Authelia - BorgBackup - Davfs @@ -188,11 +186,11 @@ The services above rely on the following [common blocks][]: - ZFS Those blocks can be used with services -not provided by SelfHostBlocks. +not provided by SelfHostBlocks as shows [in the manual][common blocks]. -Some blocks do not have an entry yet in the manual. -To know options for those, the only way for now -is to go to the [All Options][] section of the manual. +[common blocks]: https://shb.skarabox.com/blocks.html + +The manual also provides documentation for each individual blocks. ### Unified Interfaces diff --git a/docs/blocks.md b/docs/blocks.md index 655d2d6..1bf6a8a 100644 --- a/docs/blocks.md +++ b/docs/blocks.md @@ -5,31 +5,8 @@ Blocks help you self-host apps or services. They implement a specific function l access through a subdomain. Each block is designed to be usable on its own and to fit nicely with others. -In practice, most blocks implement a [contract](contracts.html) that must be followed to implement a -specific self-hosting function. It also comes with a unit test and NixOS VM test suite to ensure any -implementation follows the contract. - -As an example, let's take the HTTPS access block which allows for a service to be accessible through -a specific subdomain. In Nix terms, this block defines at minimum the inputs: - -- subdomain, -- domain, -- and upstream address of the service. - -It defines no outputs but has one major side effect: - -- the service should be accessible through HTTPS at `https://subdomain.domain`. - -Anything that provides the inputs and expected outputs and side effects defined by the block can be -used to fulfill its contract. In this example, we could use any of Nginx, Caddy, Haproxy or others. - -Self Host Blocks provides at least one implementation for each contract and allows you to use your own -implementation if you want to, as long as it passes the tests. You can then use blocks to improve -services you already have deployed. - -::: {.note} -Not all blocks are yet documented. You can find all available blocks [in the repository](@REPO@/modules/blocks). -::: +Not all blocks are documented yet. +You can find all available blocks [in the repository](@REPO@/modules/blocks). ```{=include=} chapters html:into-file=//blocks-authelia.html modules/blocks/authelia/docs/default.md diff --git a/docs/manual.md b/docs/manual.md index a2bbfef..bb0a0cb 100644 --- a/docs/manual.md +++ b/docs/manual.md @@ -24,6 +24,10 @@ contracts.md blocks.md ``` +```{=include=} chapters html:into-file=//recipes.html +recipes.md +``` + ```{=include=} chapters html:into-file=//demos.html demos.md ``` diff --git a/docs/preface.md b/docs/preface.md index f41e587..bec84bb 100644 --- a/docs/preface.md +++ b/docs/preface.md @@ -92,13 +92,6 @@ To achieve this, Self Host Blocks provides building blocks which each provide part of what a self hosted app should do (SSO, HTTPS, etc.). It also provides some services that are already integrated with all those building blocks. -- You are new to self hosting and want pre-configured services to deploy easily. - Look at the [services section](services.html). -- You are a seasoned self-hoster but want to enhance some services you deploy already. - Go to the [blocks section](blocks.html). -- You are a user of Self Host Blocks but would like to use your own implementation for a block. - Go to the [contracts section](https://shb.skarabox.com/contracts.html). - Self Host Blocks uses the full power of NixOS modules to achieve these goals. Blocks and service are both NixOS modules. @@ -114,9 +107,14 @@ and also goes over secrets management with [SOPS][]. [deploy-rs]: https://shb.skarabox.com/usage.html#usage-example-deployrs [SOPS]: https://shb.skarabox.com/usage.html#usage-secrets -Then, to actually configure services, you can choose which one interests you in -[the services section](https://shb.skarabox.com/services.html) of the manual. -Not all services have a corresponding manual page yet. +Then, depending on what you want to do: + +- You are new to self hosting and want pre-configured services to deploy easily. + Look at the [services section](services.html). +- You are a seasoned self-hoster but want to enhance some services you deploy already. + Go to the [blocks section](blocks.html) and the [recipes section](recipes.html). +- You are a user of Self Host Blocks but would like to use your own implementation for a block. + Go to the [contracts section](https://shb.skarabox.com/contracts.html). Head over to the [matrix channel](https://matrix.to/#/#selfhostblocks:matrix.org) for any remaining question, or just to say hi :) diff --git a/docs/recipes.md b/docs/recipes.md new file mode 100644 index 0000000..c14f988 --- /dev/null +++ b/docs/recipes.md @@ -0,0 +1,8 @@ + +# Recipes {#recipes} + +This section of the manual gives you easy to follow recipes for common use cases. + +```{=include=} chapters html:into-file=//recipes-exposeService.html +recipes/exposeService.md +``` diff --git a/docs/recipes/exposeService.md b/docs/recipes/exposeService.md new file mode 100644 index 0000000..2c17d25 --- /dev/null +++ b/docs/recipes/exposeService.md @@ -0,0 +1,129 @@ + +# Expose a service {#recipes-exposeService} + +Let's see how one can use most of the blocks provided by SelfHostBlocks to make a service +accessible through a reverse proxy with LDAP and SSO integration as well as backing up +this service and creating a ZFS dataset to store the service's data. + +We'll use an hypothetical well made service found under `services.awesome` as our example. +We're purposely not using a real service to avoid needing to deal with uninteresting particularities. + +## Service setup {#recipes-exposeService-service} + +Let's say our domain name is `example.com`, +and we want to reach our service under the `awesome` subdomain: + +```nix +let + domain = "example.com"; + subdomain = "awesome"; + fqdn = "${subdomain}.${domain}"; + listenPort = 9000; + dataDir = "/var/lib/awesome"; +in +``` + +We then `enable` the service and explicitly set the `listenPort` and `dataDir`, +assuming those options exist: + +```nix +services.awesome = { + enable = true; + inherit dataDir listenPort; +}; +``` + +## SSL Certificate {#recipes-exposeService-ssl} + +Requesting an SSL certificate from Let's Encrypt is done by adding an entry to +the `extraDomains` option: + +```nix +shb.certs.certs.letsencrypt.${domain}.extraDomains = [ fqdn ]; +``` + +This assumes the `shb.certs` block has been configured: + +```nix +shb.certs.certs.letsencrypt.${domain} = { + inherit domain; + group = "nginx"; + reloadServices = [ "nginx.service" ]; + adminEmail = "admin@${domain}"; +}; +``` + +## LDAP group {#recipes-exposeService-ldap} + +We want only users of the group `calibre_user` to be able to access this subdomain. +The following snippet creates the LDAP group: + +```nix +shb.lldap.ensureGroups = { + calibre_user = {}; +}; +``` + +## Reverse Proxy with Forward Auth {#recipes-exposeService-nginx} + +If our service does not integrate with OIDC, we can still protect it with SSO +with forward authentication by letting the reverse proxy handle authentication. +This is done by adding an entry to `shb.nginx.vhosts`: + +```nix +shb.nginx.vhosts = [ + { + inherit subdomain domain; + ssl = config.shb.certs.certs.letsencrypt.${domain}; + upstream = "http://127.0.0.1:${toString config.services.calibre-web.listen.port}"; + authEndpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}"; + autheliaRules = [{ + policy = "one_factor"; + subject = [ "group:${config.shb.lldap.ensureGroups.calibre_user.name}" ]; + }]; + } +]; +``` + +## ZFS support {#recipes-exposeService-zfs} + +If you use ZFS, you can use SelfHostBlocks to create a dataset for you: + +```nix +shb.zfs.datasets."safe/awesome".path = config.services.awesome.dataDir; +``` + +## Debugging {#recipes-exposeService-debug} + +Usually, the log level of the service can be increased with some option they provide. + +With SelfHostBlocks, you can also introspect any HTTP service by adding an +`mitmdump` instance between the reverse proxy and the `awesome` service: + +```nix +shb.mitmdump.awesome = { + inherit listenPort; + upstreamPort = listenPort + 1; +}; +services.awesome.listenPort = lib.mkForce (listenPort + 1); +``` + +This creates a `mitmdump-awesome.service` systemd service which prints the requests' and responses' headers and bodies. + +## Backup {#recipes-exposeService-backup} + +The following snippet uses the `shb.restic` block to backup the `services.awesome.dataDir` directory: + +```nix +shb.restic.instances.awesome = { + request.user = "awesome"; + request.sourceDirectories = [ dataDir ]; + settings.enable = true; + settings.passphrase.result = config.shb.sops.secret.awesome.result; + settings.repository.path = "/srv/backup/awesome"; +}; + +shb.sops.secret."awesome" = { + request = config.shb.restic.instances.awesome.settings.passphrase.request; +}; +``` diff --git a/docs/redirects.json b/docs/redirects.json index c3402a9..b89d06a 100644 --- a/docs/redirects.json +++ b/docs/redirects.json @@ -1643,6 +1643,33 @@ "quick-reference": [ "service-implementation-guide.html#quick-reference" ], + "recipes": [ + "recipes.html#recipes" + ], + "recipes-exposeService": [ + "recipes-exposeService.html#recipes-exposeService" + ], + "recipes-exposeService-backup": [ + "recipes-exposeService.html#recipes-exposeService-backup" + ], + "recipes-exposeService-debug": [ + "recipes-exposeService.html#recipes-exposeService-debug" + ], + "recipes-exposeService-ldap": [ + "recipes-exposeService.html#recipes-exposeService-ldap" + ], + "recipes-exposeService-nginx": [ + "recipes-exposeService.html#recipes-exposeService-nginx" + ], + "recipes-exposeService-service": [ + "recipes-exposeService.html#recipes-exposeService-service" + ], + "recipes-exposeService-ssl": [ + "recipes-exposeService.html#recipes-exposeService-ssl" + ], + "recipes-exposeService-zfs": [ + "recipes-exposeService.html#recipes-exposeService-zfs" + ], "redirect-management": [ "service-implementation-guide.html#redirect-management" ],