{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.code-server;
defaultUser = "code-server";
defaultGroup = defaultUser;
in {
###### interface
options = {
services.code-server = {
enable = mkEnableOption "code-server";
package = mkOption {
default = pkgs.code-server;
defaultText = "pkgs.code-server";
description = "Which code-server derivation to use.";
type = types.package;
};
extraPackages = mkOption {
default = [ ];
description = "Packages that are available in the PATH of code-server.";
example = "[ pkgs.go ]";
type = types.listOf types.package;
};
extraEnvironment = mkOption {
type = types.attrsOf types.str;
description =
"Additional environment variables to passed to code-server.";
default = { };
example = { PKG_CONFIG_PATH = "/run/current-system/sw/lib/pkgconfig"; };
};
extraArguments = mkOption {
default = [ "--disable-telemetry" ];
description = "Additional arguments that passed to code-server";
example = ''[ "--verbose" ]'';
type = types.listOf types.str;
};
host = mkOption {
default = "127.0.0.1";
description = "The host-ip to bind to.";
type = types.str;
};
port = mkOption {
default = 4444;
description = "The port where code-server runs.";
type = types.port;
};
auth = mkOption {
default = "password";
description = "The type of authentication to use.";
type = types.enum [ "none" "password" ];
};
hashedPassword = mkOption {
default = "";
description =
"Create the password with: 'echo -n 'thisismypassword' | npx argon2-cli -e'.";
type = types.str;
};
user = mkOption {
default = defaultUser;
example = "yourUser";
description = ''
The user to run code-server as.
By default, a user named ${defaultUser} will be created.
'';
type = types.str;
};
group = mkOption {
default = defaultGroup;
example = "yourGroup";
description = ''
The group to run code-server under.
By default, a group named ${defaultGroup} will be created.
'';
type = types.str;
};
extraGroups = mkOption {
default = [ ];
description =
"An array of additional groups for the ${defaultUser} user.";
example = [ "docker" ];
type = types.listOf types.str;
};
};
};
###### implementation
config = mkIf cfg.enable {
systemd.services.code-server = {
description = "VSCode server";
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" ];
path = cfg.extraPackages;
environment = {
HASHED_PASSWORD = cfg.hashedPassword;
} // cfg.extraEnvironment;
serviceConfig = {
ExecStart = "${cfg.package}/bin/code-server --bind-addr ${cfg.host}:${toString cfg.port} --auth ${cfg.auth} " + builtins.concatStringsSep " " cfg.extraArguments;
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
RuntimeDirectory = cfg.user;
User = cfg.user;
Group = cfg.group;
Restart = "on-failure";
};
};
users.users."${cfg.user}" = mkMerge [
(mkIf (cfg.user == defaultUser) {
isNormalUser = true;
description = "code-server user";
inherit (cfg) group;
})
{
packages = cfg.extraPackages;
inherit (cfg) extraGroups;
}
];
users.groups."${defaultGroup}" = mkIf (cfg.group == defaultGroup) { };
};
meta.maintainers = with maintainers; [ stackshadow ];
}