WIP: Migrate from Docker to NixOS Containers. #67

Closed
voronind wants to merge 5 commits from migrate into main
12 changed files with 153 additions and 125 deletions
Showing only changes of commit 095e97e6b6 - Show all commits

View file

@ -1,30 +1,24 @@
{ storage { container, ... } @args: let
, domain cfg = container.config.change;
, mkContainer
, mkContainerConfig
, mkContainerDir
, ... } @args: let
address = "10.1.0.41";
path = "${storage}/change";
in { in {
systemd.tmpfiles.rules = map (dir: mkContainerDir "${path}/${dir}") [ systemd.tmpfiles.rules = container.mkContainerDir cfg [
"data" "data"
]; ];
containers.change = mkContainer address { containers.change = container.mkContainer cfg {
bindMounts = { bindMounts = {
"/var/lib/changedetection-io" = { "/var/lib/changedetection-io" = {
hostPath = "${path}/data"; hostPath = "${cfg.storage}/data";
isReadOnly = false; isReadOnly = false;
}; };
}; };
config = { ... }: mkContainerConfig { config = { ... }: container.mkContainerConfig cfg {
services.changedetection-io = { services.changedetection-io = {
enable = true; enable = true;
baseURL = "https://change.${domain}"; baseURL = cfg.domain;
behindProxy = true; behindProxy = true;
listenAddress = address; listenAddress = cfg.address;
}; };
}; };
}; };

View file

@ -1,26 +1,33 @@
{ storage { pkgs, container, ... } @args: let
, mkContainer cfg = container.config.cloud;
, mkContainerConfig
, mkContainerDir
, ... } @args: let
address = "10.1.0.13";
path = "${storage}/cloud";
in { in {
systemd.tmpfiles.rules = map (dir: mkContainerDir "${path}/${dir}") [ systemd.tmpfiles.rules = container.mkContainerDir cfg [
"data" "data"
]; ];
containers.postgres = mkContainer address { containers.cloud = container.mkContainer cfg {
bindMounts = { bindMounts = {
"/var/www/html" = { "/var/www/html" = {
hostPath = "${path}/data"; hostPath = "${cfg.storage}/data";
isReadOnly = false; isReadOnly = false;
}; };
}; };
config = { ... }: mkContainerConfig { config = { ... }: container.mkContainerConfig cfg {
services.nextcloud = { services.nextcloud = {
enable = true; enable = true;
hostName = cfg.domain;
config = {
adminuser = "root";
adminpassFile = "${pkgs.writeText "NextcloudPassword" "root"}";
dbtype = "pgsql";
dbhost = "10.1.0.3";
};
settings = {
trusted_domains = [ cfg.address ];
trusted_proxies = [ container.config.proxy.address ];
};
}; };
}; };
}; };

View file

@ -1,44 +1,34 @@
{ pkgs { pkgs, util, container, ... } @args: let
, storage cfg = container.config.paste;
, domain
, util
, mkContainer
, mkContainerConfig
, mkContainerDir
, mkServer
, ... } @args: let
address = "10.1.0.14";
fqdn = "paste.${domain}";
package = (pkgs.callPackage ./pastebin args); package = (pkgs.callPackage ./pastebin args);
path = "${storage}/paste";
in { in {
systemd.tmpfiles.rules = map (dir: mkContainerDir "${path}/${dir}") [ systemd.tmpfiles.rules = container.mkContainerDir cfg [
"data" "data"
"tmp" "tmp"
"nginxtmp" "nginxtmp"
]; ];
containers.paste = mkContainer address { containers.paste = container.mkContainer cfg {
bindMounts = { bindMounts = {
"/srv/data" = { "/srv/data" = {
hostPath = "${path}/data"; hostPath = "${cfg.storage}/data";
isReadOnly = false; isReadOnly = false;
}; };
"/tmp" = { "/tmp" = {
hostPath = "${path}/tmp"; hostPath = "${cfg.storage}/tmp";
isReadOnly = false; isReadOnly = false;
}; };
"/var/lib/nginx/tmp" = { "/var/lib/nginx/tmp" = {
hostPath = "${path}/nginxtmp"; hostPath = "${cfg.storage}/nginxtmp";
isReadOnly = false; isReadOnly = false;
}; };
"/srv/config" = { "/srv/config" = {
hostPath = "${path}/config"; hostPath = "${cfg.storage}/config";
isReadOnly = false; isReadOnly = false;
}; };
}; };
config = { config, ... }: mkContainerConfig { config = { config, ... }: container.mkContainerConfig cfg {
environment.systemPackages = [ package ]; environment.systemPackages = [ package ];
systemd.packages = [ package ]; systemd.packages = [ package ];
@ -73,7 +63,7 @@ in {
services.nginx = { services.nginx = {
enable = true; enable = true;
virtualHosts.${fqdn} = mkServer { virtualHosts.${cfg.domain} = container.mkServer {
default = true; default = true;
root = "${package}"; root = "${package}";

View file

@ -1,28 +1,23 @@
{ storage { container, ... } @args: let
, host cfg = container.config.postgres;
, mkContainer
, mkContainerConfig
, mkContainerDir
, ... } @args: let
address = "10.1.0.3";
path = "${storage}/postgres";
in { in {
systemd.tmpfiles.rules = map (dir: mkContainerDir "${path}/${dir}") [ systemd.tmpfiles.rules = container.mkContainerDir cfg [
"data" "data"
]; ];
containers.postgres = mkContainer address { containers.postgres = container.mkContainer cfg {
bindMounts = { bindMounts = {
"/var/lib/postgresql/data" = { "/var/lib/postgresql/data" = {
hostPath = "${path}/data"; hostPath = "${cfg.storage}/data";
isReadOnly = false; isReadOnly = false;
}; };
}; };
config = { pkgs, ... }: mkContainerConfig { config = { pkgs, ... }: container.mkContainerConfig cfg {
services.postgresql = let services.postgresql = let
databases = [ databases = [
"privatebin" "privatebin"
"nextcloud"
]; ];
in { in {
enable = true; enable = true;
@ -30,8 +25,9 @@ in {
dataDir = "/var/lib/postgresql/data/14"; dataDir = "/var/lib/postgresql/data/14";
enableTCPIP = true; enableTCPIP = true;
authentication = '' authentication = ''
host all all ${host}/32 trust host all all ${container.host}/32 trust
host privatebin privatebin 10.1.0.14/32 trust host privatebin privatebin ${container.config.paste.address}/32 trust
host nextcloud nextcloud ${container.config.cloud.address}/32 trust
''; '';
ensureDatabases = databases; ensureDatabases = databases;
ensureUsers = map (name: { ensureUsers = map (name: {

View file

@ -1,32 +1,25 @@
{ storage { domain, util, container, ... } @args: let
, util cfg = container.config.proxy;
, domain
, mkContainer
, mkContainerConfig
, mkContainerDir
, ... } @args: let
address = "10.1.0.2";
path = "${storage}/proxy";
virtualHosts = util.catSet (util.ls ./proxy/host) args; virtualHosts = util.catSet (util.ls ./proxy/host) args;
in { in {
systemd.tmpfiles.rules = map (dir: mkContainerDir "${path}/${dir}") [ systemd.tmpfiles.rules = container.mkContainerDir cfg [
"challenge" "challenge"
"letsencrypt" "letsencrypt"
]; ];
containers.proxy = mkContainer address { containers.proxy = container.mkContainer cfg {
bindMounts = { bindMounts = {
"/etc/letsencrypt" = { "/etc/letsencrypt" = {
hostPath = "${path}/letsencrypt"; hostPath = "${cfg.storage}/letsencrypt";
isReadOnly = true; isReadOnly = true;
}; };
"/var/www/.well-known" = { "/var/www/.well-known" = {
hostPath = "${path}/challenge"; hostPath = "${cfg.storage}/challenge";
isReadOnly = false; isReadOnly = false;
}; };
}; };
config = { pkgs, ... }: mkContainerConfig { config = { pkgs, ... }: container.mkContainerConfig cfg {
environment.systemPackages = with pkgs; [ certbot ]; environment.systemPackages = with pkgs; [ certbot ];
services.nginx = { services.nginx = {

59
container/default.nix Normal file
View file

@ -0,0 +1,59 @@
{ lib
, const
, host
, storage
, domain
, ... }: {
inherit host;
mkContainer = config: cfg: lib.recursiveUpdate cfg {
autoStart = true;
hostAddress = host;
localAddress = config.address;
privateNetwork = true;
};
mkContainerConfig = config: cfg: lib.recursiveUpdate cfg {
system.stateVersion = const.stateVersion;
users.users.root.password = "";
users.mutableUsers = false;
networking = {
useHostResolvConf = lib.mkForce false;
firewall.enable = false;
};
};
mkContainerDir = cfg: dirs: map (path: "d '${cfg.storage}/${path}' 1777 root root - -") dirs;
mkServer = cfg: lib.recursiveUpdate cfg {
forceSSL = false;
};
config = {
change = {
address = "10.1.0.41";
domain = "change.${domain}";
storage = "${storage}/change";
};
cloud = {
address = "10.1.0.13";
domain = "cloud.${domain}";
storage = "${storage}/cloud";
};
paste = {
address = "10.1.0.14";
domain = "paste.${domain}";
storage = "${storage}/paste";
};
proxy = {
address = "10.1.0.2";
storage = "${storage}/proxy";
};
postgres = {
address = "10.1.0.3";
storage = "${storage}/postgres";
};
};
}

View file

@ -1,8 +1,10 @@
{ domain, util, mkServer, ... }: { { domain, util, container, ... }: let
"change.${domain}" = mkServer { cfg = container.config.change;
in {
${cfg.domain} = container.mkServer {
extraConfig = util.trimTabs '' extraConfig = util.trimTabs ''
listen 443 ssl; listen 443 ssl;
set $change 10.1.0.41:5000; set $change ${cfg.address}:5000;
location / { location / {
allow 192.168.1.0/24; allow 192.168.1.0/24;

View file

@ -0,0 +1,26 @@
{ domain, util, container, ... }: let
cfg = container.config.cloud;
in {
${cfg.domain} = container.mkServer {
extraConfig = util.trimTabs ''
listen 443 ssl;
set $cloud ${cfg.address}:80;
location ~ ^/(settings/admin|settings/users|settings/apps|login|api) {
allow 192.168.1.0/24;
allow 10.1.0.1;
deny all;
proxy_pass http://$cloud$request_uri;
}
location / {
proxy_pass http://$cloud$request_uri;
}
ssl_certificate /etc/letsencrypt/live/${domain}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${domain}/privkey.pem;
include /etc/letsencrypt/conf/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/conf/ssl-dhparams.pem;
'';
};
}

View file

@ -1,8 +1,10 @@
{ domain, util, mkServer, ... }: { { domain, util, container, ... }: let
"paste.${domain}" = mkServer { cfg = container.config.paste;
in {
${cfg.domain} = container.mkServer {
extraConfig = util.trimTabs '' extraConfig = util.trimTabs ''
listen 443 ssl; listen 443 ssl;
set $paste 10.1.0.14:80; set $paste ${cfg.address}:80;
location = / { location = / {
return 403; return 403;

View file

@ -125,7 +125,7 @@
# Constant values. # Constant values.
const = { const = {
droidStateVersion = "22.11"; droidStateVersion = "22.11";
stateVersion = "23.11"; stateVersion = "24.05";
timeZone = "Europe/Moscow"; timeZone = "Europe/Moscow";
url = "https://git.voronind.com/voronind/nixos.git"; url = "https://git.voronind.com/voronind/nixos.git";
}; };

View file

@ -6,30 +6,7 @@
in { in {
inherit storage domain host pkgs const lib config util; inherit storage domain host pkgs const lib config util;
mkContainer = address: cfg: lib.recursiveUpdate cfg { container = import ../../container args;
autoStart = true;
hostAddress = host;
localAddress = address;
privateNetwork = true;
};
mkContainerConfig = cfg: lib.recursiveUpdate cfg {
system.stateVersion = const.stateVersion;
users.users.root.password = "";
users.mutableUsers = false;
networking = {
useHostResolvConf = lib.mkForce false;
firewall.enable = false;
};
};
mkContainerDir = path: "d '${path}' 1777 root root - -";
mkServer = cfg: lib.recursiveUpdate cfg {
forceSSL = false;
};
}; };
in { in {
networking.nat = { networking.nat = {
@ -40,13 +17,15 @@ in {
# TODO: Remove this. # TODO: Remove this.
networking.extraHosts = '' networking.extraHosts = ''
10.1.0.2 paste.local
10.1.0.2 change.local 10.1.0.2 change.local
10.1.0.2 cloud.local
10.1.0.2 paste.local
10.1.0.2 local 10.1.0.2 local
''; '';
imports = [ imports = [
(import ../../container/Change.nix args) (import ../../container/Change.nix args)
(import ../../container/Cloud.nix args)
(import ../../container/Paste.nix args) (import ../../container/Paste.nix args)
(import ../../container/Postgres.nix args) (import ../../container/Postgres.nix args)
(import ../../container/Proxy.nix args) (import ../../container/Proxy.nix args)

View file

@ -5,26 +5,6 @@
host = "192.168.0.174"; host = "192.168.0.174";
in { in {
inherit storage domain host pkgs const lib config util; inherit storage domain host pkgs const lib config util;
mkContainer = cfg: lib.recursiveUpdate cfg {
hostAddress = host;
};
mkContainerConfig = cfg: lib.recursiveUpdate cfg {
system.stateVersion = const.stateVersion;
users.users.root.password = "";
users.mutableUsers = false;
networking = {
useHostResolvConf = lib.mkForce false;
firewall.enable = false;
};
};
mkServer = cfg: lib.recursiveUpdate cfg {
forceSSL = false;
};
}; };
in { in {
networking.nat = { networking.nat = {