feat: started container implementation
This commit is contained in:
parent
4944ddd61a
commit
04ee323aa6
|
@ -11,6 +11,7 @@
|
||||||
../../modules/hardware/zfs.nix
|
../../modules/hardware/zfs.nix
|
||||||
|
|
||||||
../../modules/services/samba.nix
|
../../modules/services/samba.nix
|
||||||
|
../../modules/services/nextcloud.nix
|
||||||
|
|
||||||
./net.nix
|
./net.nix
|
||||||
./fs.nix
|
./fs.nix
|
||||||
|
|
24
lib/containers.nix
Normal file
24
lib/containers.nix
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
_inputs: _self: super: {
|
||||||
|
lib =
|
||||||
|
super.lib
|
||||||
|
// {
|
||||||
|
containers.mkConfig = name: config:
|
||||||
|
super.lib.mkMerge [
|
||||||
|
{
|
||||||
|
bindmounts = {
|
||||||
|
"state" = {
|
||||||
|
mountpoint = "/state";
|
||||||
|
hostPath = "/state/containers/${name}";
|
||||||
|
};
|
||||||
|
"persist" = {
|
||||||
|
mountpoint = "/persist";
|
||||||
|
hostPath = config.zfs.mountpoint;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
#config = {...}: {
|
||||||
|
#};
|
||||||
|
}
|
||||||
|
config
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
inputs: [
|
inputs: [
|
||||||
(import ./disko.nix inputs)
|
(import ./disko.nix inputs)
|
||||||
|
(import ./containers.nix inputs)
|
||||||
]
|
]
|
||||||
|
|
|
@ -61,6 +61,7 @@ _inputs: _self: super: {
|
||||||
"local/nix" = filesystem "/nix";
|
"local/nix" = filesystem "/nix";
|
||||||
"local/state" = filesystem "/state";
|
"local/state" = filesystem "/state";
|
||||||
"safe" = unmountable;
|
"safe" = unmountable;
|
||||||
|
"safe/containers" = unmountable;
|
||||||
"safe/persist" = filesystem "/persist";
|
"safe/persist" = filesystem "/persist";
|
||||||
};
|
};
|
||||||
unmountable = {type = "zfs_fs";};
|
unmountable = {type = "zfs_fs";};
|
||||||
|
|
107
modules/services/containers.nix
Normal file
107
modules/services/containers.nix
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
utils,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit
|
||||||
|
(lib)
|
||||||
|
mapAttrsToList
|
||||||
|
flip
|
||||||
|
types
|
||||||
|
mkOption
|
||||||
|
mkEnableOption
|
||||||
|
mdDoc
|
||||||
|
mkIf
|
||||||
|
disko
|
||||||
|
makeBinPath
|
||||||
|
escapeShellArg
|
||||||
|
mkMerge
|
||||||
|
;
|
||||||
|
in {
|
||||||
|
options.containers = mkOption {
|
||||||
|
type = types.attrsOf (types.submodule (
|
||||||
|
{name, ...}: {
|
||||||
|
options = {
|
||||||
|
zfs = {
|
||||||
|
enable = mkEnableOption (mdDoc "persistent data on separate zfs dataset");
|
||||||
|
|
||||||
|
pool = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = mdDoc "The host's zfs pool on which the dataset resides";
|
||||||
|
};
|
||||||
|
|
||||||
|
dataset = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "safe/containers/${name}";
|
||||||
|
description = mdDoc "The host's dataset that should be used for this containers persistent data (will automatically be created, parent dataset must exist)";
|
||||||
|
};
|
||||||
|
|
||||||
|
mountpoint = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "/containers/${name}";
|
||||||
|
description = mdDoc "The host's mountpoint for the containers dataset";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
));
|
||||||
|
};
|
||||||
|
config.disko = mkMerge (flip mapAttrsToList config.containers
|
||||||
|
(
|
||||||
|
_: cfg: {
|
||||||
|
devices.zpool = mkIf cfg.zfs.enable {
|
||||||
|
${cfg.zfs.pool}.datasets."${cfg.zfs.dataset}" =
|
||||||
|
disko.zfs.filesystem cfg.zfs.mountpoint;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Ensure that the zfs dataset exists before it is mounted.
|
||||||
|
}
|
||||||
|
));
|
||||||
|
config.systemd = mkMerge (flip mapAttrsToList config.containers
|
||||||
|
(
|
||||||
|
name: cfg: {
|
||||||
|
services = let
|
||||||
|
fsMountUnit = "${utils.escapeSystemdPath cfg.zfs.mountpoint}.mount";
|
||||||
|
in
|
||||||
|
mkIf cfg.zfs.enable {
|
||||||
|
# Ensure that the zfs dataset exists before it is mounted.
|
||||||
|
"zfs-ensure-${utils.escapeSystemdPath cfg.zfs.mountpoint}" = {
|
||||||
|
wantedBy = [fsMountUnit];
|
||||||
|
before = [fsMountUnit];
|
||||||
|
after = [
|
||||||
|
"zfs-import-${utils.escapeSystemdPath cfg.zfs.pool}.service"
|
||||||
|
"zfs-mount.target"
|
||||||
|
];
|
||||||
|
unitConfig.DefaultDependencies = "no";
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
script = let
|
||||||
|
poolDataset = "${cfg.zfs.pool}/${cfg.zfs.dataset}";
|
||||||
|
diskoDataset = config.disko.devices.zpool.${cfg.zfs.pool}.datasets.${cfg.zfs.dataset};
|
||||||
|
in ''
|
||||||
|
export PATH=${makeBinPath [pkgs.zfs]}":$PATH"
|
||||||
|
if ! zfs list -H -o type ${escapeShellArg poolDataset} &>/dev/null ; then
|
||||||
|
${diskoDataset._create}
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Ensure that the zfs dataset has the correct permissions when mounted
|
||||||
|
"zfs-chown-${utils.escapeSystemdPath cfg.zfs.mountpoint}" = {
|
||||||
|
after = [fsMountUnit];
|
||||||
|
unitConfig.DefaultDependencies = "no";
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
script = ''
|
||||||
|
chmod 700 ${escapeShellArg cfg.zfs.mountpoint}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"container@${name}" = {
|
||||||
|
requires = [fsMountUnit "zfs-chown-${utils.escapeSystemdPath cfg.zfs.mountpoint}.service"];
|
||||||
|
after = [fsMountUnit "zfs-chown-${utils.escapeSystemdPath cfg.zfs.mountpoint}.service"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
|
@ -1,6 +1,15 @@
|
||||||
{lib, ...}: {
|
{
|
||||||
containers.nextcloud = {
|
lib,
|
||||||
|
stateVersion,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
imports = [./containers.nix];
|
||||||
|
containers.nextcloud = lib.container.mkConfig "nextcloud" {
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
|
zfs = {
|
||||||
|
enable = true;
|
||||||
|
pool = "panzer";
|
||||||
|
};
|
||||||
macvlans = [
|
macvlans = [
|
||||||
"lan01"
|
"lan01"
|
||||||
];
|
];
|
||||||
|
@ -16,7 +25,7 @@
|
||||||
config.adminpassFile = "${pkgs.writeText "adminpass" "test123"}"; # DON'T DO THIS IN PRODUCTION - the password file will be world-readable in the Nix Store!
|
config.adminpassFile = "${pkgs.writeText "adminpass" "test123"}"; # DON'T DO THIS IN PRODUCTION - the password file will be world-readable in the Nix Store!
|
||||||
};
|
};
|
||||||
|
|
||||||
system.stateVersion = "23.05";
|
system.stateVersion = stateVersion;
|
||||||
|
|
||||||
networking = {
|
networking = {
|
||||||
firewall = {
|
firewall = {
|
||||||
|
@ -28,10 +37,19 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
services.resolved.enable = true;
|
services.resolved.enable = true;
|
||||||
bindMounts.data = {
|
|
||||||
mountPoint = "/persist";
|
|
||||||
hostPath = "/persist/containers/nextcloud";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
#wireguard
|
||||||
|
#samba/printer finding
|
||||||
|
#vaultwarden
|
||||||
|
#nextcloud
|
||||||
|
#acme
|
||||||
|
#nginx
|
||||||
|
#maddy
|
||||||
|
#kanidm
|
||||||
|
#xdg portals
|
||||||
|
#zfs snapshots
|
||||||
|
#remote backups
|
||||||
|
#immich
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue