feat: acme/ddclient/nextcloud container
This commit is contained in:
parent
2ac6562a17
commit
4fda94b984
|
@ -122,11 +122,10 @@
|
||||||
inherit
|
inherit
|
||||||
(import ./nix/hosts.nix inputs)
|
(import ./nix/hosts.nix inputs)
|
||||||
hosts
|
hosts
|
||||||
microvmConfigurations
|
|
||||||
nixosConfigurations
|
nixosConfigurations
|
||||||
minimalConfigurations
|
minimalConfigurations
|
||||||
;
|
;
|
||||||
nodes = self.nixosConfigurations // self.microvmConfigurations;
|
nodes = self.nixosConfigurations;
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
(lib.foldl' lib.recursiveUpdate {}
|
(lib.foldl' lib.recursiveUpdate {}
|
||||||
|
|
|
@ -115,6 +115,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/state".neededForBoot = true;
|
fileSystems."/state".neededForBoot = true;
|
||||||
|
fileSystems."/persist".neededForBoot = true;
|
||||||
fileSystems."/panzer/state".neededForBoot = true;
|
fileSystems."/panzer/state".neededForBoot = true;
|
||||||
fileSystems."/panzer/persist".neededForBoot = true;
|
fileSystems."/panzer/persist".neededForBoot = true;
|
||||||
boot.initrd.luks.devices.enc-rpool.allowDiscards = true;
|
boot.initrd.luks.devices.enc-rpool.allowDiscards = true;
|
||||||
|
|
BIN
hosts/testienix/secrets/generated/dhparams.pem.age
Normal file
BIN
hosts/testienix/secrets/generated/dhparams.pem.age
Normal file
Binary file not shown.
|
@ -1,18 +1,30 @@
|
||||||
_inputs: _self: super: {
|
inputs: _self: super: {
|
||||||
lib =
|
lib =
|
||||||
super.lib
|
super.lib
|
||||||
// {
|
// {
|
||||||
containers.mkConfig = name: config:
|
containers.mkConfig = name: config:
|
||||||
super.lib.mkMerge [
|
super.lib.mkMerge [
|
||||||
{
|
{
|
||||||
|
config = {
|
||||||
|
imports = [
|
||||||
|
../modules/config/impermanence
|
||||||
|
../modules/config/net.nix
|
||||||
|
../modules/interface-naming.nix
|
||||||
|
|
||||||
|
inputs.impermanence.nixosModules.impermanence
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
bindMounts = {
|
bindMounts = {
|
||||||
"state" = {
|
"state" = {
|
||||||
mountPoint = "/state";
|
mountPoint = "/state";
|
||||||
hostPath = "/state/containers/${name}";
|
hostPath = "/state/containers/${name}";
|
||||||
|
isReadOnly = false;
|
||||||
};
|
};
|
||||||
"persist" = {
|
"persist" = {
|
||||||
mountPoint = "/persist";
|
mountPoint = "/persist";
|
||||||
hostPath = "/containers/${name}";
|
hostPath = "/containers/${name}";
|
||||||
|
isReadOnly = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
zfs.mountpoint = super.lib.mkDefault "/containers/${name}";
|
zfs.mountpoint = super.lib.mkDefault "/containers/${name}";
|
||||||
|
|
9
lib/test.nix
Normal file
9
lib/test.nix
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
networking.hostName = "lololo";
|
||||||
|
programs.fuse.userAllowOther = true;
|
||||||
|
environment.systemPackages = [pkgs.hello];
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
|
imports = [./impermanence/users.nix];
|
||||||
home-manager = {
|
home-manager = {
|
||||||
useGlobalPkgs = true;
|
useGlobalPkgs = true;
|
||||||
useUserPackages = true;
|
useUserPackages = true;
|
||||||
|
|
|
@ -3,14 +3,16 @@
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}: {
|
}: let
|
||||||
imports = [./users.nix];
|
onlyHost =
|
||||||
|
lib.mkIf (!config.boot.isContainer);
|
||||||
|
in {
|
||||||
# to allow all users to access hm managed persistent folders
|
# to allow all users to access hm managed persistent folders
|
||||||
programs.fuse.userAllowOther = true;
|
programs.fuse.userAllowOther = true;
|
||||||
environment.persistence."/state" = {
|
environment.persistence."/state" = {
|
||||||
hideMounts = true;
|
hideMounts = true;
|
||||||
|
|
||||||
files = [
|
files = onlyHost [
|
||||||
"/etc/machine-id"
|
"/etc/machine-id"
|
||||||
"/etc/ssh/ssh_host_ed25519_key"
|
"/etc/ssh/ssh_host_ed25519_key"
|
||||||
"/etc/ssh/ssh_host_ed25519_key.pub"
|
"/etc/ssh/ssh_host_ed25519_key.pub"
|
||||||
|
@ -25,13 +27,27 @@
|
||||||
mode = "0777";
|
mode = "0777";
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
++ lib.lists.optionals config.security.acme.acceptTerms [
|
||||||
|
{
|
||||||
|
directory = "/var/lib/acme";
|
||||||
|
user = "acme";
|
||||||
|
group = "acme";
|
||||||
|
mode = "0755";
|
||||||
|
}
|
||||||
|
]
|
||||||
++ lib.lists.optionals config.hardware.bluetooth.enable [
|
++ lib.lists.optionals config.hardware.bluetooth.enable [
|
||||||
"/var/lib/bluetooth"
|
"/var/lib/bluetooth"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
environment.persistence."/persist" = {
|
||||||
|
hideMounts = true;
|
||||||
|
directories = [];
|
||||||
|
};
|
||||||
|
|
||||||
# After importing the rpool, rollback the root system to be empty.
|
# After importing the rpool, rollback the root system to be empty.
|
||||||
boot.initrd.systemd.services.impermanence-root = {
|
boot.initrd.systemd.services.impermanence-root =
|
||||||
|
onlyHost
|
||||||
|
{
|
||||||
wantedBy = ["initrd.target"];
|
wantedBy = ["initrd.target"];
|
||||||
after = ["zfs-import-rpool.service"];
|
after = ["zfs-import-rpool.service"];
|
||||||
before = ["sysroot.mount"];
|
before = ["sysroot.mount"];
|
||||||
|
|
|
@ -10,8 +10,10 @@
|
||||||
attrNames
|
attrNames
|
||||||
mkOption
|
mkOption
|
||||||
types
|
types
|
||||||
|
hasAttr
|
||||||
mkMerge
|
mkMerge
|
||||||
isAttrs
|
isAttrs
|
||||||
|
mkIf
|
||||||
;
|
;
|
||||||
in {
|
in {
|
||||||
# Expose a home manager module for each user that allows extending
|
# Expose a home manager module for each user that allows extending
|
||||||
|
|
|
@ -6,11 +6,13 @@
|
||||||
networking = {
|
networking = {
|
||||||
useNetworkd = true;
|
useNetworkd = true;
|
||||||
dhcpcd.enable = false;
|
dhcpcd.enable = false;
|
||||||
|
firewall.enable = true;
|
||||||
# allow mdns port
|
# allow mdns port
|
||||||
firewall.allowedUDPPorts = [5353];
|
firewall.allowedUDPPorts = [5353];
|
||||||
renameInterfacesByMac =
|
renameInterfacesByMac = lib.mkIf (!config.boot.isContainer) (
|
||||||
lib.mapAttrs (_: v: v.mac)
|
lib.mapAttrs (_: v: v.mac)
|
||||||
(config.secrets.secrets.local.networking.interfaces or {});
|
(config.secrets.secrets.local.networking.interfaces or {})
|
||||||
|
);
|
||||||
};
|
};
|
||||||
systemd.network = {
|
systemd.network = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
avahi = uidGid 209;
|
avahi = uidGid 209;
|
||||||
fwupd-refresh = uidGid 210;
|
fwupd-refresh = uidGid 210;
|
||||||
podman = uidGid 211;
|
podman = uidGid 211;
|
||||||
|
acme = uidGid 212;
|
||||||
systemd-oom = uidGid 300;
|
systemd-oom = uidGid 300;
|
||||||
systemd-coredump = uidGid 301;
|
systemd-coredump = uidGid 301;
|
||||||
};
|
};
|
||||||
|
|
29
modules/services/acme.nix
Normal file
29
modules/services/acme.nix
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
age.secrets.cloudflare_token_acme = {
|
||||||
|
rekeyFile = ../../secrets/cloudflare/api_token.age;
|
||||||
|
mode = "440";
|
||||||
|
group = "acme";
|
||||||
|
};
|
||||||
|
security.acme = {
|
||||||
|
acceptTerms = true;
|
||||||
|
defaults = {
|
||||||
|
email = config.secrets.secrets.global.devEmail;
|
||||||
|
dnsProvider = "cloudflare";
|
||||||
|
dnsPropagationCheck = true;
|
||||||
|
reloadServices = ["nginx"];
|
||||||
|
credentialFiles = {
|
||||||
|
"CF_DNS_API_TOKEN_FILE" = config.age.secrets.cloudflare_token_acme.path;
|
||||||
|
"CF_ZONE_API_TOKEN_FILE" = config.age.secrets.cloudflare_token_acme.path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
security.acme.certs = lib.flip lib.mapAttrs config.secrets.secrets.global.domains (_: value: {
|
||||||
|
domain = value;
|
||||||
|
extraDomainNames = ["*.${value}"];
|
||||||
|
});
|
||||||
|
users.groups.acme.members = ["nginx"];
|
||||||
|
}
|
14
modules/services/ddclient.nix
Normal file
14
modules/services/ddclient.nix
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{config, ...}: {
|
||||||
|
age.secrets.cloudflare_token_dns = {
|
||||||
|
rekeyFile = ../../secrets/cloudflare/api_token.age;
|
||||||
|
mode = "440";
|
||||||
|
};
|
||||||
|
services.ddclient = {
|
||||||
|
enable = true;
|
||||||
|
zone = config.secrets.secrets.global.domains.mail;
|
||||||
|
protocol = "Cloudflare";
|
||||||
|
username = "token";
|
||||||
|
passwordFile = config.age.secrets.cloudflare_token_dns.path;
|
||||||
|
domains = [config.secrets.secrets.global.domains.mail];
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,9 +1,27 @@
|
||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
stateVersion,
|
stateVersion,
|
||||||
|
config,
|
||||||
...
|
...
|
||||||
}: {
|
}: let
|
||||||
imports = [./containers.nix];
|
hostName = "nc.${config.secrets.secrets.global.domains.mail}";
|
||||||
|
in {
|
||||||
|
imports = [./containers.nix ./nginx.nix ./ddclient.nix ./acme.nix];
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
upstreams.nextcloud = {
|
||||||
|
servers."192.168.178.33:80" = {};
|
||||||
|
extraConfig = ''
|
||||||
|
zone nextcloud 64k ;
|
||||||
|
keepalive 5 ;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
virtualHosts.${hostName} = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "mail";
|
||||||
|
locations."/".proxyPass = "http://nextcloud";
|
||||||
|
};
|
||||||
|
};
|
||||||
containers.nextcloud = lib.containers.mkConfig "nextcloud" {
|
containers.nextcloud = lib.containers.mkConfig "nextcloud" {
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
zfs = {
|
zfs = {
|
||||||
|
@ -18,11 +36,41 @@
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
|
systemd.network.networks = {
|
||||||
|
"lan01" = {
|
||||||
|
address = ["192.168.178.33/24"];
|
||||||
|
gateway = ["192.168.178.1"];
|
||||||
|
matchConfig.Name = "mv-lan01*";
|
||||||
|
dns = ["192.168.178.2"];
|
||||||
|
networkConfig = {
|
||||||
|
IPv6PrivacyExtensions = "yes";
|
||||||
|
MulticastDNS = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
services.nextcloud = {
|
services.nextcloud = {
|
||||||
|
inherit hostName;
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.nextcloud27;
|
package = pkgs.nextcloud27;
|
||||||
hostName = "localhost";
|
configureRedis = true;
|
||||||
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!
|
||||||
|
extraApps = with config.services.nextcloud.package.packages.apps; {
|
||||||
|
inherit contacts calendar tasks;
|
||||||
|
};
|
||||||
|
extraAppsEnable = true;
|
||||||
|
extraOptions.enabledPreviewProviders = [
|
||||||
|
"OC\\Preview\\BMP"
|
||||||
|
"OC\\Preview\\GIF"
|
||||||
|
"OC\\Preview\\JPEG"
|
||||||
|
"OC\\Preview\\Krita"
|
||||||
|
"OC\\Preview\\MarkDown"
|
||||||
|
"OC\\Preview\\MP3"
|
||||||
|
"OC\\Preview\\OpenDocument"
|
||||||
|
"OC\\Preview\\PNG"
|
||||||
|
"OC\\Preview\\TXT"
|
||||||
|
"OC\\Preview\\XBitmap"
|
||||||
|
"OC\\Preview\\HEIC"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
system.stateVersion = stateVersion;
|
system.stateVersion = stateVersion;
|
||||||
|
|
|
@ -52,6 +52,8 @@ in {
|
||||||
mode = "440";
|
mode = "440";
|
||||||
group = "nginx";
|
group = "nginx";
|
||||||
};
|
};
|
||||||
|
security.acme.acceptTerms = true;
|
||||||
|
security.acme.defaults.email = config.secrets.secrets.global.devEmail;
|
||||||
|
|
||||||
# Sensible defaults for nginx
|
# Sensible defaults for nginx
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
|
|
|
@ -58,7 +58,6 @@ inputs: let
|
||||||
in {
|
in {
|
||||||
inherit
|
inherit
|
||||||
hosts
|
hosts
|
||||||
microvmConfigurations
|
|
||||||
nixosConfigurations
|
nixosConfigurations
|
||||||
minimalConfigurations
|
minimalConfigurations
|
||||||
;
|
;
|
||||||
|
|
13
secrets/cloudflare/api_token.age
Normal file
13
secrets/cloudflare/api_token.age
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> X25519 j1vdwUZ+o5coMFAaOCyiS42rLq7FPX6xwuWmoHcN61U
|
||||||
|
m1QEYj4NW5IdNsFh26Uhwe2Sg1ggkvTYB92S4B2lC8M
|
||||||
|
-> piv-p256 XTQkUA AhjsxoVBz3h/1Sj+cwnT7gpcE6SDMhNOBMU9nP+gfC5G
|
||||||
|
a7E3dolF4QaxTVpJBOKA314INK32eTdDykDyRT+/8XQ
|
||||||
|
-> piv-p256 ZFgiIw Ah49xwjTzvroi4R90URbbE0yY15w+OvUsWZ2cQdYHs/w
|
||||||
|
4i6XZ8lwOeWinlU1IiCgUBTSWMzxuPyvYKRbz6GqNUk
|
||||||
|
-> piv-p256 ZFgiIw A49Cv751h0WJYL6qPceFVwjbGVpF668SGKVjHq/lQ4Rs
|
||||||
|
AAGD0jOCHIOAIBk872SJwe2mCx69xn/1ZjiswebgU0w
|
||||||
|
-> K("0$@8-grease z`/W }"_xiVH <~Bj._
|
||||||
|
|
||||||
|
--- /NUrs98fD72LqCIYVOzrUhFNhxGivAEOZ9pob65I2fI
|
||||||
|
8î:(#–¥aô[8@BÊ4èÝ|ÍC7!³>Ù?¬Œ›`5á‰o‡Þr
õB´ˆ°y`óAIJ;)÷Å&“)@ÝÎB²¹Ï¡ñ´¾Q
|
Binary file not shown.
Loading…
Reference in a new issue