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 1 commit
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

While using `services-flake` you are not just limited to the [[services|services supported here]]. You can define your own service, and use it in your flake.
shivaraj-bh marked this conversation as resolved.
Show resolved Hide resolved

By default, the services provided in `services-flake` support multiple instances, 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.
shivaraj-bh marked this conversation as resolved.
Show resolved Hide resolved

{#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. The aim is 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.
shivaraj-bh marked this conversation as resolved.
Show resolved Hide resolved

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