1{ pkgs, lib, config, ... }:
2let
3 cfg = config.virtualisation.containerd;
4
5 configFile = if cfg.configFile == null then
6 settingsFormat.generate "containerd.toml" cfg.settings
7 else
8 cfg.configFile;
9
10 containerdConfigChecked = pkgs.runCommand "containerd-config-checked.toml" {
11 nativeBuildInputs = [ pkgs.containerd ];
12 } ''
13 containerd -c ${configFile} config dump >/dev/null
14 ln -s ${configFile} $out
15 '';
16
17 settingsFormat = pkgs.formats.toml {};
18in
19{
20
21 options.virtualisation.containerd = with lib.types; {
22 enable = lib.mkEnableOption "containerd container runtime";
23
24 configFile = lib.mkOption {
25 default = null;
26 description = ''
27 Path to containerd config file.
28 Setting this option will override any configuration applied by the settings option.
29 '';
30 type = nullOr path;
31 };
32
33 settings = lib.mkOption {
34 type = settingsFormat.type;
35 default = {};
36 description = ''
37 Verbatim lines to add to containerd.toml
38 '';
39 };
40
41 args = lib.mkOption {
42 default = {};
43 description = "extra args to append to the containerd cmdline";
44 type = attrsOf str;
45 };
46 };
47
48 config = lib.mkIf cfg.enable {
49 warnings = lib.optional (cfg.configFile != null) ''
50 `virtualisation.containerd.configFile` is deprecated. use `virtualisation.containerd.settings` instead.
51 '';
52
53 virtualisation.containerd = {
54 args.config = toString containerdConfigChecked;
55 settings = {
56 version = 2;
57 plugins."io.containerd.grpc.v1.cri" = {
58 containerd.snapshotter =
59 lib.mkIf config.boot.zfs.enabled (lib.mkOptionDefault "zfs");
60 cni.bin_dir = lib.mkOptionDefault "${pkgs.cni-plugins}/bin";
61 };
62 };
63 };
64
65 environment.systemPackages = [ pkgs.containerd ];
66
67 systemd.services.containerd = {
68 description = "containerd - container runtime";
69 wantedBy = [ "multi-user.target" ];
70 after = [ "network.target" ];
71 path = with pkgs; [
72 containerd
73 runc
74 iptables
75 ] ++ lib.optional config.boot.zfs.enabled config.boot.zfs.package;
76 serviceConfig = {
77 ExecStart = ''${pkgs.containerd}/bin/containerd ${lib.concatStringsSep " " (lib.cli.toGNUCommandLine {} cfg.args)}'';
78 Delegate = "yes";
79 KillMode = "process";
80 Type = "notify";
81 Restart = "always";
82 RestartSec = "10";
83
84 # "limits" defined below are adopted from upstream: https://github.com/containerd/containerd/blob/master/containerd.service
85 LimitNPROC = "infinity";
86 LimitCORE = "infinity";
87 LimitNOFILE = "infinity";
88 TasksMax = "infinity";
89 OOMScoreAdjust = "-999";
90
91 StateDirectory = "containerd";
92 RuntimeDirectory = "containerd";
93 RuntimeDirectoryPreserve = "yes";
94 };
95 unitConfig = {
96 StartLimitBurst = "16";
97 StartLimitIntervalSec = "120s";
98 };
99 };
100 };
101}