Skip to content

Commit

Permalink
colima: init
Browse files Browse the repository at this point in the history
Allows the user to enable the Colima container runtime for macOS. Normally
Colima is run inside the current user's their context, but I wanted to use
Colima closer to how Docker works on Linux. Where the Docker daemon on Linux is
run as the root user, and users have to either run the docker command with sudo,
or add themselves to the docker group. Effectively enabling multi-user
interaction on macOS.

Just enabling the following config doesn't do a whole lot, as the user would
have to log in as the colima user to interact with the colima VM.

    services.colima.enable = true;

Instead, this module is meant to be used as follows, so that the user can use
Colima as a Docker Desktop for macOS alternative.

    services.colima = {
      enable = true;
      enableDockerCompatability = true;
    };

This will set up everything for the Docker CLI to work with the Colima VM under
the hood.

Co-authored-by: Sam <[email protected]>
Refs: https://github.com/abiosoft/colima
  • Loading branch information
bryanhonof and Samasaur1 committed Jan 23, 2025
1 parent bd92122 commit 23ae8a6
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 0 deletions.
2 changes: 2 additions & 0 deletions modules/misc/ids.nix
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ in
ids.uids = {
nixbld = lib.mkDefault 350;
_prometheus-node-exporter = 534;
colima = 400;
};

ids.gids = {
nixbld = lib.mkDefault (if config.system.stateVersion < 5 then 30000 else 350);
_prometheus-node-exporter = 534;
_colima = 400;
};

};
Expand Down
1 change: 1 addition & 0 deletions modules/module-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
./services/buildkite-agents.nix
./services/chunkwm.nix
./services/cachix-agent.nix
./services/colima
./services/dnsmasq.nix
./services/emacs.nix
./services/eternal-terminal.nix
Expand Down
192 changes: 192 additions & 0 deletions modules/services/colima/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
{
config,
lib,
pkgs,
...
}:

with lib;
let
cfg = config.services.colima;
user = config.users.users."colima";
group = config.users.groups."_colima";
in
{
options.services.colima = {
enable = mkEnableOption "Colima, a macOS container runtime";

enableDockerCompatability = mkOption {
type = types.bool;
default = false;
description = ''
Create a symlink from Colima's socket to /var/run/docker.sock, and set
its permissions so that users part of the _colima group can use it.
'';
};

package = mkPackageOption pkgs "colima" { };

stateDir = lib.mkOption {
type = types.path;
default = "/var/lib/colima";
description = "State directory of the Colima process.";
};

logFile = mkOption {
type = types.path;
default = "/var/log/colima.log";
description = "Combined stdout and stderr of the colima process. Set to /dev/null to disable.";
};

groupMembers = mkOption {
type = types.listOf types.str;
default = [ ];
description = ''
List of users that should be added to the _colima group.
Only has effect with enableDockerCompatability enabled.
'';
};

runtime = mkOption {
type = types.enum [
"docker"
"containerd"
"incus"
];
default = "docker";
description = "The runtime to use with Colima.";
};

architectue = mkOption {
type = types.enum [
"x86_64"
"aarch64"
"host"
];
default = "host";
description = "The architecture to use for the Colima virtual machine.";
};

extraFlags = mkOption {
type = types.listOf types.str;
default = [ ];
example = [ "--vz-rosetta" ];
description = "Extra commandline options to pass to the colima start command.";
};

vmType = mkOption {
type = types.enum [
"qemu"
"vz"
];
default = "vz";
description = "Virtual machine type to use with Colima.";
};
};

config = mkMerge [
(mkIf cfg.enableDockerCompatability {
assertions = [
{
assertion = !cfg.enable;
message = "services.colima.enableDockerCompatability doesn't make sense without enabling services.colima.enable";
}
];

launchd.daemons.colima-create-docker-socket-and-set-permissions = {
script = ''
# Wait for the docker socket to be created. This is important when
# we enabled Colima and Docker compatability at the same time, for
# the first time. Colima takes a while creating the VM.
until [ -S ${cfg.stateDir}/.colima/default/docker.sock ]
do
sleep 5
done
chmod g+rw ${cfg.stateDir}/.colima/default/docker.sock
ln -sf ${cfg.stateDir}/.colima/default/docker.sock /var/run/docker.sock
'';

serviceConfig = {
RunAtLoad = true;
EnvironmentVariables.PATH = "/usr/bin:/bin:/usr/sbin:/sbin";
};
};

users.groups."_colima".members = cfg.groupMembers;

environment.systemPackages = [
pkgs.docker
];
})

(mkIf cfg.enable {
launchd.daemons.colima = {
script =
concatStringsSep " " [
"exec"
(getExe cfg.package)
"start"
"--foreground"
"--runtime ${cfg.runtime}"
"--arch ${cfg.architectue}"
"--vm-type ${cfg.vmType}"
]
+ escapeShellArgs cfg.extraFlags;

serviceConfig = {
KeepAlive = true;
RunAtLoad = true;
StandardErrorPath = cfg.logFile;
StandardOutPath = cfg.logFile;
GroupName = group.name;
UserName = user.name;
WorkingDirectory = cfg.stateDir;
EnvironmentVariables = {
PATH = "${pkgs.colima}/bin:${pkgs.docker}/bin:/usr/bin:/bin:/usr/sbin:/sbin";
COLIMA_HOME = "${cfg.stateDir}/.colima";
};
};
};

system.activationScripts.preActivation.text = ''
touch '${cfg.logFile}'
chown ${toString user.uid}:${toString user.gid} '${cfg.logFile}'
'';

users = {
knownGroups = [
"colima"
"_colima"
];
knownUsers = [
"colima"
"_colima"
];
};

users.users."colima" = {
uid = config.ids.uids.colima;
gid = config.ids.gids._colima;
home = cfg.stateDir;
# The username isn't allowed to have an underscore in the beginning of
# its name, otherwise the VM will fail to start with the following error
# > "[hostagent] identifier \"_colima\" must match ^[A-Za-z0-9]+(?:[._-](?:[A-Za-z0-9]+))*$: invalid argument" fields.level=fatal
name = "colima";
createHome = true;
shell = "/bin/bash";
description = "System user for Colima";
};

users.groups."_colima" = {
gid = config.ids.gids._colima;
name = "_colima";
description = "System group for Colima";
};
})
];

meta.maintainers = [
lib.maintainers.bryanhonof or "bryanhonof"
];
}

0 comments on commit 23ae8a6

Please sign in to comment.