Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(custom-service): Document the use of a custom service definition #243

Merged
merged 4 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 166 additions & 0 deletions doc/custom-service.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
# Custom service

When using `services-flake` you are not just limited to the [[services|builtin services]]. You can also define your own service.

By default, `services-flake` supports multiple instances for each service, allowing you to run several instances of the same service simultaneously. However, you also have the option to create custom single-instance services. In the following sections, we’ll explore how to define custom services of both types.

{#single-instance}
## Single instance service

We will create a `hello` service that will return a greeting message:

```nix
{ config, lib, pkgs, ... }:
{
options = {
services.hello = {
enable = lib.mkEnableOption "Enable hello service";
package = lib.mkPackageOption pkgs "hello" { };
message = lib.mkOption {
type = lib.types.str;
default = "Hello, world!";
description = "The message to be displayed";
};
};
};
config =
let
cfg = config.services.hello;
in
lib.mkIf cfg.enable {
settings.processes.hello = {
command = "${lib.getExe cfg.package} --greeting='${cfg.message}'";
};
};
}
```

Let's call this file `hello.nix`.

Now, we can import this service in our flake. In this example, we will configure an existing service, [[ollama]], and our custom service from above:

```nix
{
description = "A demo of importing a single instance custom service";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
systems.url = "github:nix-systems/default";
process-compose-flake.url = "github:Platonic-Systems/process-compose-flake";
services-flake.url = "github:juspay/services-flake";
};
outputs = inputs:
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
systems = import inputs.systems;
imports = [
inputs.process-compose-flake.flakeModule
];
perSystem = { self', pkgs, lib, ... }: {
process-compose."default" = { config, ... }: {
imports = [
inputs.services-flake.processComposeModules.default
./hello.nix
];

services.ollama."ollama1".enable = true;
services.hello.enable = true;
};
};
};
}
```

Finally, `nix run`:
![[single-instance-hello.png]]

{#multi-instance}
## Multi-instance service

For this purpose, `services-flake` exports a [multiService](https://github.com/juspay/services-flake/blob/647bff2c44b42529461f60a7fe07851ff93fb600/nix/lib.nix#L1-L34) library function. It aims to provide an interface wherein the user just writes the configuration like they would for a single instance service, and the library takes care of creating multiple instances of the service.

Let's write the same `hello` service as above, in `hello.nix`, but this time as a multi-instance service:

```nix
{ config, lib, name, pkgs, ... }:
{
options = {
enable = lib.mkEnableOption "Enable ${name} service";
package = lib.mkPackageOption pkgs "hello" { };
message = lib.mkOption {
type = lib.types.str;
default = "Hello, world!";
description = "The message to be displayed";
};
outputs.settings = lib.mkOption {
type = lib.types.deferredModule;
internal = true;
readOnly = true;
default = {
processes.${name} = {
command = "${lib.getExe config.package} --greeting='${config.message}'";
};
};
};
};
}
```

The primary differences from the single instance service are:

- The module now takes an additional argument `name`, which is the name of the instance of the service.
- We no longer have to write the `config` block, as it is now handled by the library by importing the `outputs.settings` option.
- And we don't have to write `options.services."${name}"`, as that is abstracted away by the library.

Now that we have defined the multi-instance service, we can import it in our flake:

```nix
{
description = "A demo of importing a multi-instance custom service";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
systems.url = "github:nix-systems/default";
process-compose-flake.url = "github:Platonic-Systems/process-compose-flake";
services-flake.url = "github:juspay/services-flake";
};
outputs = inputs:
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
systems = import inputs.systems;
imports = [
inputs.process-compose-flake.flakeModule
];
perSystem = { self', pkgs, lib, ... }: {
process-compose."default" =
let
inherit (inputs.services-flake.lib) multiService;
in
{
imports = [
inputs.services-flake.processComposeModules.default
(multiService ./hello.nix)
];

services.ollama."ollama1".enable = true;
services.hello = {
hello1 = {
enable = true;
message = "Hello, world!";
};
hello2 = {
enable = true;
message = "Hello, Nix!";
};
};
};
};
};
}
```

And finally, `nix run`:
![[multi-instance-hello.png]]

## See also

- [Postgres with replica](https://github.com/nammayatri/nammayatri/blob/main/Backend/nix/services/postgres-with-replica.nix)
- [Passetto (A custom encryption service)](https://github.com/nammayatri/passetto/blob/nixify/process-compose.nix), is [imported](https://github.com/nammayatri/nammayatri/blob/e8032f1fac3581b9062e2469dfc778d2913d3665/Backend/nix/services/nammayatri.nix#L32) and [configured in the Nammayatri flake](https://github.com/nammayatri/nammayatri/blob/e8032f1fac3581b9062e2469dfc778d2913d3665/Backend/nix/services/nammayatri.nix#L285-L297).
1 change: 1 addition & 0 deletions doc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ See:
- [[services]]#
- [[contributing]]#
- [[guide]]#
- [[custom-service]]#

## Demo

Expand Down
Binary file added doc/multi-instance-hello.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/single-instance-hello.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading