mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-11 04:05:40 +03:00
237 lines
6.5 KiB
Nix
237 lines
6.5 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
options,
|
|
...
|
|
}:
|
|
let
|
|
|
|
cfg = config.services.jupyter;
|
|
|
|
package = pkgs.python3.withPackages (
|
|
ps:
|
|
[
|
|
cfg.package
|
|
]
|
|
++ cfg.extraPackages
|
|
);
|
|
|
|
kernels = (
|
|
pkgs.jupyter-kernel.create {
|
|
definitions = if cfg.kernels != null then cfg.kernels else pkgs.jupyter-kernel.default;
|
|
}
|
|
);
|
|
|
|
notebookConfig = pkgs.writeText "jupyter_server_config.py" ''
|
|
${cfg.notebookConfig}
|
|
c.ServerApp.password = "${cfg.password}"
|
|
'';
|
|
|
|
in
|
|
{
|
|
meta.maintainers = with lib.maintainers; [
|
|
aborsu
|
|
b-m-f
|
|
];
|
|
|
|
options.services.jupyter = {
|
|
enable = lib.mkEnableOption "Jupyter development server";
|
|
|
|
ip = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "localhost";
|
|
description = ''
|
|
IP address Jupyter will be listening on.
|
|
'';
|
|
};
|
|
|
|
package = lib.mkPackageOption pkgs [
|
|
"python3"
|
|
"pkgs"
|
|
"jupyter"
|
|
] { };
|
|
|
|
extraPackages = lib.mkOption {
|
|
type = lib.types.listOf lib.types.package;
|
|
default = [ ];
|
|
example = lib.literalExpression ''
|
|
[
|
|
pkgs.python3.pkgs.nbconvert
|
|
pkgs.python3.pkgs.playwright
|
|
]
|
|
'';
|
|
description = "Extra packages to be available in the jupyter runtime environment";
|
|
};
|
|
extraEnvironmentVariables = lib.mkOption {
|
|
description = "Extra environment variables to be set in the runtime context of jupyter notebook";
|
|
default = { };
|
|
example = lib.literalExpression ''
|
|
{
|
|
PLAYWRIGHT_BROWSERS_PATH = "''${pkgs.playwright-driver.browsers}";
|
|
PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS = "true";
|
|
}
|
|
'';
|
|
inherit (options.environment.variables) type apply;
|
|
};
|
|
|
|
command = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "jupyter notebook";
|
|
example = "jupyter lab";
|
|
description = ''
|
|
Which command the service runs. Note that not all jupyter packages
|
|
have all commands, e.g. `jupyter lab` isn't present in the `notebook` package.
|
|
'';
|
|
};
|
|
|
|
port = lib.mkOption {
|
|
type = lib.types.port;
|
|
default = 8888;
|
|
description = ''
|
|
Port number Jupyter will be listening on.
|
|
'';
|
|
};
|
|
|
|
notebookDir = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "~/";
|
|
description = ''
|
|
Root directory for notebooks.
|
|
'';
|
|
};
|
|
|
|
user = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "jupyter";
|
|
description = ''
|
|
Name of the user used to run the jupyter service.
|
|
For security reason, jupyter should really not be run as root.
|
|
If not set (jupyter), the service will create a jupyter user with appropriate settings.
|
|
'';
|
|
example = "aborsu";
|
|
};
|
|
|
|
group = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "jupyter";
|
|
description = ''
|
|
Name of the group used to run the jupyter service.
|
|
Use this if you want to create a group of users that are able to view the notebook directory's content.
|
|
'';
|
|
example = "users";
|
|
};
|
|
|
|
password = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = ''
|
|
Password to use with notebook.
|
|
Can be generated following: https://jupyter-server.readthedocs.io/en/stable/operators/public-server.html#preparing-a-hashed-password
|
|
'';
|
|
example = "argon2:$argon2id$v=19$m=10240,t=10,p=8$48hF+vTUuy1LB83/GzNhUg$J1nx4jPWD7PwOJHs5OtDW8pjYK2s0c1R3rYGbSIKB54";
|
|
};
|
|
|
|
notebookConfig = lib.mkOption {
|
|
type = lib.types.lines;
|
|
default = "";
|
|
description = ''
|
|
Raw jupyter config.
|
|
Please use the password configuration option to set a password instead of passing it in here.
|
|
'';
|
|
};
|
|
|
|
kernels = lib.mkOption {
|
|
type = lib.types.nullOr (
|
|
lib.types.attrsOf (
|
|
lib.types.submodule (
|
|
import ./kernel-options.nix {
|
|
inherit lib pkgs;
|
|
}
|
|
)
|
|
)
|
|
);
|
|
|
|
default = null;
|
|
example = lib.literalExpression ''
|
|
{
|
|
python3 = let
|
|
env = (pkgs.python3.withPackages (pythonPackages: with pythonPackages; [
|
|
ipykernel
|
|
pandas
|
|
scikit-learn
|
|
]));
|
|
in {
|
|
displayName = "Python 3 for machine learning";
|
|
argv = [
|
|
"''${env.interpreter}"
|
|
"-m"
|
|
"ipykernel_launcher"
|
|
"-f"
|
|
"{connection_file}"
|
|
];
|
|
language = "python";
|
|
logo32 = "''${env.sitePackages}/ipykernel/resources/logo-32x32.png";
|
|
logo64 = "''${env.sitePackages}/ipykernel/resources/logo-64x64.png";
|
|
extraPaths = {
|
|
"cool.txt" = pkgs.writeText "cool" "cool content";
|
|
};
|
|
};
|
|
}
|
|
'';
|
|
description = ''
|
|
Declarative kernel config.
|
|
|
|
Kernels can be declared in any language that supports and has the required
|
|
dependencies to communicate with a jupyter server.
|
|
In python's case, it means that ipykernel package must always be included in
|
|
the list of packages of the targeted environment.
|
|
'';
|
|
};
|
|
};
|
|
|
|
config = lib.mkMerge [
|
|
(lib.mkIf cfg.enable {
|
|
systemd.services.jupyter = {
|
|
description = "Jupyter development server";
|
|
|
|
after = [ "network.target" ];
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
# TODO: Patch notebook so we can explicitly pass in a shell
|
|
path = [ pkgs.bash ]; # needed for sh in cell magic to work
|
|
|
|
environment = {
|
|
JUPYTER_PATH = toString kernels;
|
|
} // cfg.extraEnvironmentVariables;
|
|
|
|
serviceConfig = {
|
|
Restart = "always";
|
|
ExecStart = ''
|
|
${package}/bin/${cfg.command} \
|
|
--no-browser \
|
|
--ip=${cfg.ip} \
|
|
--port=${toString cfg.port} --port-retries 0 \
|
|
--notebook-dir=${cfg.notebookDir} \
|
|
--JupyterApp.config_file=${notebookConfig}
|
|
|
|
'';
|
|
User = cfg.user;
|
|
Group = cfg.group;
|
|
WorkingDirectory = "~";
|
|
};
|
|
};
|
|
})
|
|
(lib.mkIf (cfg.enable && (cfg.group == "jupyter")) {
|
|
users.groups.jupyter = { };
|
|
})
|
|
(lib.mkIf (cfg.enable && (cfg.user == "jupyter")) {
|
|
users.extraUsers.jupyter = {
|
|
inherit (cfg) group;
|
|
home = "/var/lib/jupyter";
|
|
createHome = true;
|
|
isSystemUser = true;
|
|
useDefaultShell = true; # needed so that the user can start a terminal.
|
|
};
|
|
})
|
|
];
|
|
}
|