parent
721fde93ff
commit
ab64310a5e
@ -0,0 +1,98 @@ |
||||
{ config, lib, pkgs, ... }: |
||||
|
||||
with lib; |
||||
|
||||
let |
||||
|
||||
cfg = config.virtualisation.docker.rootless; |
||||
proxy_env = config.networking.proxy.envVars; |
||||
settingsFormat = pkgs.formats.json {}; |
||||
daemonSettingsFile = settingsFormat.generate "daemon.json" cfg.daemon.settings; |
||||
|
||||
in |
||||
|
||||
{ |
||||
###### interface |
||||
|
||||
options.virtualisation.docker.rootless = { |
||||
enable = mkOption { |
||||
type = types.bool; |
||||
default = false; |
||||
description = '' |
||||
This option enables docker in a rootless mode, a daemon that manages |
||||
linux containers. To interact with the daemon, one needs to set |
||||
<command>DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock</command>. |
||||
''; |
||||
}; |
||||
|
||||
setSocketVariable = mkOption { |
||||
type = types.bool; |
||||
default = false; |
||||
description = '' |
||||
Point <command>DOCKER_HOST</command> to rootless Docker instance for |
||||
normal users by default. |
||||
''; |
||||
}; |
||||
|
||||
daemon.settings = mkOption { |
||||
type = settingsFormat.type; |
||||
default = { }; |
||||
example = { |
||||
ipv6 = true; |
||||
"fixed-cidr-v6" = "fd00::/80"; |
||||
}; |
||||
description = '' |
||||
Configuration for docker daemon. The attributes are serialized to JSON used as daemon.conf. |
||||
See https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file |
||||
''; |
||||
}; |
||||
|
||||
package = mkOption { |
||||
default = pkgs.docker; |
||||
defaultText = literalExpression "pkgs.docker"; |
||||
type = types.package; |
||||
example = literalExpression "pkgs.docker-edge"; |
||||
description = '' |
||||
Docker package to be used in the module. |
||||
''; |
||||
}; |
||||
}; |
||||
|
||||
###### implementation |
||||
|
||||
config = mkIf cfg.enable { |
||||
environment.systemPackages = [ cfg.package ]; |
||||
|
||||
environment.extraInit = optionalString cfg.setSocketVariable '' |
||||
if [ -z "$DOCKER_HOST" -a -n "$XDG_RUNTIME_DIR" ]; then |
||||
export DOCKER_HOST="unix://$XDG_RUNTIME_DIR/docker.sock" |
||||
fi |
||||
''; |
||||
|
||||
# Taken from https://github.com/moby/moby/blob/master/contrib/dockerd-rootless-setuptool.sh |
||||
systemd.user.services.docker = { |
||||
wantedBy = [ "default.target" ]; |
||||
description = "Docker Application Container Engine (Rootless)"; |
||||
# needs newuidmap from pkgs.shadow |
||||
path = [ "/run/wrappers" ]; |
||||
environment = proxy_env; |
||||
unitConfig.StartLimitInterval = "60s"; |
||||
serviceConfig = { |
||||
Type = "notify"; |
||||
ExecStart = "${cfg.package}/bin/dockerd-rootless --config-file=${daemonSettingsFile}"; |
||||
ExecReload = "${pkgs.procps}/bin/kill -s HUP $MAINPID"; |
||||
TimeoutSec = 0; |
||||
RestartSec = 2; |
||||
Restart = "always"; |
||||
StartLimitBurst = 3; |
||||
LimitNOFILE = "infinity"; |
||||
LimitNPROC = "infinity"; |
||||
LimitCORE = "infinity"; |
||||
Delegate = true; |
||||
NotifyAccess = "all"; |
||||
KillMode = "mixed"; |
||||
}; |
||||
}; |
||||
}; |
||||
|
||||
} |
@ -0,0 +1,41 @@ |
||||
# This test runs docker and checks if simple container starts |
||||
|
||||
import ./make-test-python.nix ({ lib, pkgs, ...} : { |
||||
name = "docker-rootless"; |
||||
meta = with pkgs.lib.maintainers; { |
||||
maintainers = [ abbradar ]; |
||||
}; |
||||
|
||||
nodes = { |
||||
machine = { pkgs, ... }: { |
||||
virtualisation.docker.rootless.enable = true; |
||||
|
||||
users.users.alice = { |
||||
uid = 1000; |
||||
isNormalUser = true; |
||||
}; |
||||
}; |
||||
}; |
||||
|
||||
testScript = { nodes, ... }: |
||||
let |
||||
user = nodes.machine.config.users.users.alice; |
||||
sudo = lib.concatStringsSep " " [ |
||||
"XDG_RUNTIME_DIR=/run/user/${toString user.uid}" |
||||
"DOCKER_HOST=unix:///run/user/${toString user.uid}/docker.sock" |
||||
"sudo" "--preserve-env=XDG_RUNTIME_DIR,DOCKER_HOST" "-u" "alice" |
||||
]; |
||||
in '' |
||||
machine.wait_for_unit("multi-user.target") |
||||
|
||||
machine.succeed("loginctl enable-linger alice") |
||||
machine.wait_until_succeeds("${sudo} systemctl --user is-active docker.service") |
||||
|
||||
machine.succeed("tar cv --files-from /dev/null | ${sudo} docker import - scratchimg") |
||||
machine.succeed( |
||||
"${sudo} docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10" |
||||
) |
||||
machine.succeed("${sudo} docker ps | grep sleeping") |
||||
machine.succeed("${sudo} docker stop sleeping") |
||||
''; |
||||
}) |
Loading…
Reference in new issue