1{ config, lib, pkgs, ... }:
2
3with lib;
4let
5 cfg = config.services.livebook;
6in
7{
8 options.services.livebook = {
9 # Since livebook doesn't have a granular permission system (a user
10 # either has access to all the data or none at all), the decision
11 # was made to run this as a user service. If that changes in the
12 # future, this can be changed to a system service.
13 enableUserService = mkEnableOption "a user service for Livebook";
14
15 environmentFile = mkOption {
16 type = types.path;
17 description = lib.mdDoc ''
18 Environment file as defined in {manpage}`systemd.exec(5)` passed to the service.
19
20 This must contain at least `LIVEBOOK_PASSWORD` or
21 `LIVEBOOK_TOKEN_ENABLED=false`. See `livebook server --help`
22 for other options.'';
23 };
24
25 erlang_node_short_name = mkOption {
26 type = with types; nullOr str;
27 default = null;
28 example = "livebook";
29 description = "A short name for the distributed node.";
30 };
31
32 erlang_node_name = mkOption {
33 type = with types; nullOr str;
34 default = null;
35 example = "livebook@127.0.0.1";
36 description = "The name for the app distributed node.";
37 };
38
39 port = mkOption {
40 type = types.port;
41 default = 8080;
42 description = "The port to start the web application on.";
43 };
44
45 address = mkOption {
46 type = types.str;
47 default = "127.0.0.1";
48 description = lib.mdDoc ''
49 The address to start the web application on. Must be a valid IPv4 or
50 IPv6 address.
51 '';
52 };
53
54 options = mkOption {
55 type = with types; attrsOf str;
56 default = { };
57 description = lib.mdDoc ''
58 Additional options to pass as command-line arguments to the server.
59 '';
60 example = literalExpression ''
61 {
62 cookie = "a value shared by all nodes in this cluster";
63 }
64 '';
65 };
66 };
67
68 config = mkIf cfg.enableUserService {
69 systemd.user.services.livebook = {
70 serviceConfig = {
71 Restart = "always";
72 EnvironmentFile = cfg.environmentFile;
73 ExecStart =
74 let
75 args = lib.cli.toGNUCommandLineShell { } ({
76 inherit (cfg) port;
77 ip = cfg.address;
78 name = cfg.erlang_node_name;
79 sname = cfg.erlang_node_short_name;
80 } // cfg.options);
81 in
82 "${pkgs.livebook}/bin/livebook server ${args}";
83 };
84 path = [ pkgs.bash ];
85 wantedBy = [ "default.target" ];
86 };
87 };
88
89 meta.doc = ./livebook.md;
90}