feat: started container implementation
This commit is contained in:
parent
4944ddd61a
commit
04ee323aa6
|
@ -11,6 +11,7 @@
|
|||
../../modules/hardware/zfs.nix
|
||||
|
||||
../../modules/services/samba.nix
|
||||
../../modules/services/nextcloud.nix
|
||||
|
||||
./net.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: [
|
||||
(import ./disko.nix inputs)
|
||||
(import ./containers.nix inputs)
|
||||
]
|
||||
|
|
|
@ -61,6 +61,7 @@ _inputs: _self: super: {
|
|||
"local/nix" = filesystem "/nix";
|
||||
"local/state" = filesystem "/state";
|
||||
"safe" = unmountable;
|
||||
"safe/containers" = unmountable;
|
||||
"safe/persist" = filesystem "/persist";
|
||||
};
|
||||
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;
|
||||
zfs = {
|
||||
enable = true;
|
||||
pool = "panzer";
|
||||
};
|
||||
macvlans = [
|
||||
"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!
|
||||
};
|
||||
|
||||
system.stateVersion = "23.05";
|
||||
system.stateVersion = stateVersion;
|
||||
|
||||
networking = {
|
||||
firewall = {
|
||||
|
@ -28,10 +37,19 @@
|
|||
};
|
||||
|
||||
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