docs: add how to expose a service recipe

This commit is contained in:
ibizaman 2025-08-26 22:20:54 +02:00 committed by Pierre Penninckx
parent e0a222f583
commit fad46e420a
7 changed files with 182 additions and 41 deletions

View file

@ -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

View file

@ -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

View file

@ -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
```

View file

@ -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 :)

8
docs/recipes.md Normal file
View file

@ -0,0 +1,8 @@
<!-- Read these docs at https://shb.skarabox.com -->
# 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
```

View file

@ -0,0 +1,129 @@
<!-- Read these docs at https://shb.skarabox.com -->
# 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;
};
```

View file

@ -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"
],