Up all the containers.

This commit is contained in:
Dmitry Voronin 2024-06-13 17:00:05 +03:00
parent 5456ec4824
commit 5516a2a8c2
Signed by: voronind
SSH key fingerprint: SHA256:3kBb4iV2ahufEBNq+vFbUe4QYfHt98DHQjN7QaptY9k
24 changed files with 275 additions and 280 deletions

View file

@ -7,7 +7,7 @@ in {
containers.cloud = container.mkContainer cfg {
bindMounts = {
"/var/www/html" = {
"/var/lib/nextcloud" = {
hostPath = "${cfg.storage}/data";
isReadOnly = false;
};

View file

@ -7,19 +7,11 @@ in {
containers.download = container.mkContainer cfg {
bindMounts = {
"/var/lib/deluge" = {
"/var/lib/deluge/.config/deluge" = {
hostPath = "${cfg.storage}/data";
isReadOnly = false;
};
} // builtins.listToAttrs (lib.imap0 (i: path:
{
name = "/download/${toString i}";
value = {
hostPath = path;
isReadOnly = false;
};
}
) cfg.download);
} // container.attachMedia "download" cfg.download false;
config = { ... }: container.mkContainerConfig cfg {
services.deluge = {

View file

@ -1,20 +1,20 @@
{ container, pkgs, util, ... } @args: let
cfg = container.config.home;
package = (pkgs.callpackage ./homer args);
package = (pkgs.callPackage ./homer args);
in {
containers.home = container.mkContainer cfg {
config = { ... }: container.mkContainerConfig cfg {
environment.systempackages = [ package ];
environment.systemPackages = [ package ];
systemd.packages = [ package ];
services.nginx = {
enable = true;
virtualhosts.${cfg.domain} = container.mkserver {
virtualHosts.${cfg.domain} = container.mkServer {
default = true;
root = "${package}";
locations = {
"/".extraconfig = ''
"/".extraConfig = ''
try_files $uri $uri/index.html;
'';
};

View file

@ -11,21 +11,27 @@ in {
hostPath = "${cfg.storage}/data";
isReadOnly = false;
};
# "/photo" = {
# hostPath = "${cfg.photos}";
# isReadOnly = true;
# };
# "/dev/ttyACM0" = {
# hostPath = "/dev/ttyACM0";
# isReadOnly = false;
# };
# "/dev/serial/by-id" = {
# hostPath = "/dev/serial/by-id";
# isReadOnly = false;
# };
};
"/dev/ttyACM0" = {
hostPath = "/dev/ttyACM0";
isReadOnly = false;
};
"/dev/serial/by-id" = {
hostPath = "/dev/serial/by-id";
isReadOnly = false;
};
} // container.attachMedia "photo" cfg.photo true;
allowedDevices = [
{
modifier = "rwm";
node = "/dev/ttyACM0";
}
];
config = { ... }: container.mkContainerConfig cfg {
# Allow Hass to talk to Zigbee dongle.
users.users.hass.extraGroups = [ "dialout" "tty" ];
config = { pkgs, ... }: container.mkContainerConfig cfg {
services.home-assistant = {
# NOTE: Missing: hacs. Inside hacs: `card-mod`, `Clock Weather Card`, `WallPanel` and `Yandex.Station`.
enable = true;
@ -39,6 +45,7 @@ in {
extraPackages = python3Packages: with python3Packages; [
aiodhcpwatcher
aiodiscover
aiogithubapi
async-upnp-client
ha-av
ha-ffmpeg
@ -48,6 +55,7 @@ in {
numpy
pynacl
pyturbojpeg
python-telegram-bot
zeroconf
];
configDir = "/var/lib/hass";

View file

@ -1,13 +1,12 @@
# Guide: https://nixos-mailserver.readthedocs.io/en/latest/setup-guide.html
{ container, domain, pkgs, util, const, ... } @args: let
cfg = container.config.mail;
{ container, domain, pkgs, util, const, ... } @args: let cfg = container.config.mail;
in {
systemd.tmpfiles.rules = container.mkContainerDir cfg [
"data"
"data/indices"
"data/vmail"
"data/sieve"
"data/dkim"
# "data/indices"
# "data/vmail"
# "data/sieve"
# "data/dkim"
];
containers.mail = container.mkContainer cfg {
@ -158,9 +157,14 @@ in {
extraConfig = ''
# starttls needed for authentication, so the fqdn required to match
# the certificate
$config['smtp_server'] = "tls://${config.mailserver.fqdn}";
$config['smtp_user'] = "%u";
$config['smtp_pass'] = "%p";
# $config['smtp_server'] = "tls://${config.mailserver.fqdn}";
# $config['smtp_server'] = "tls://localhost";
$config['smtp_server'] = "localhost:25";
$config['smtp_auth_type'] = null;
$config['smtp_user'] = "";
$config['smtp_pass'] = "";
# $config['smtp_user'] = "%u";
# $config['smtp_pass'] = "%p";
'';
};

View file

@ -1,4 +1,4 @@
{ container, pkgs, util, ... } @args: let
{ container, pkgs, util, lib, ... } @args: let
cfg = container.config.paper;
in {
systemd.tmpfiles.rules = container.mkContainerDir cfg [
@ -11,9 +11,15 @@ in {
hostPath = "${cfg.storage}/data";
isReadOnly = false;
};
"/var/lib/paperless/media" = {
hostPath = "${lib.elemAt cfg.paper 0}";
isReadOnly = false;
};
};
config = { lib, ... }: container.mkContainerConfig cfg {
config = { lib, pkgs, ... }: container.mkContainerConfig cfg {
environment.systemPackages = with pkgs; [ postgresql inetutils ];
services.paperless = {
enable = true;
dataDir = "/var/lib/paperless";
@ -22,6 +28,7 @@ in {
port = cfg.port;
passwordFile = pkgs.writeText "PaperlessPassword" "root";
settings = {
PAPERLESS_URL = "https://${cfg.domain}";
PAPERLESS_ADMIN_USER = "root";
PAPERLESS_DBHOST = container.config.postgres.address;
PAPERLESS_DBENGINE = "postgresql";

View file

@ -16,10 +16,10 @@ in {
config = { ... }: container.mkContainerConfig cfg {
services.vaultwarden = {
enable = true;
dbBackend = "postgresql";
dbBackend = "sqlite";
environmentFile = "/var/lib/bitwarden_rs/Env";
config = {
DATABASE_URL = "postgresql://vaultwarden:vaultwarden@${container.config.postgres.address}:${toString container.config.postgres.port}/vaultwarden";
# DATABASE_URL = "postgresql://vaultwarden:vaultwarden@${container.config.postgres.address}:${toString container.config.postgres.port}/vaultwarden";
DATA_FOLDER = "/var/lib/bitwarden_rs";
DOMAIN = "http://${cfg.domain}";
SIGNUPS_ALLOWED = false;

View file

@ -6,6 +6,7 @@ in {
"data"
"tmp"
"nginxtmp"
"config"
];
containers.paste = container.mkContainer cfg {

View file

@ -22,7 +22,6 @@ in {
privatebin = paste;
onlyoffice = office;
paperless = paper;
vaultwarden = pass;
invidious = yt;
};

View file

@ -11,15 +11,10 @@ in {
hostPath = "${cfg.storage}/data";
isReadOnly = false;
};
} // builtins.listToAttrs (lib.imap0 (i: path:
{
name = "/book/${toString i}";
value = {
hostPath = path;
isReadOnly = true;
};
}
) cfg.book);
}
// container.attachMedia "book" cfg.book true
// container.attachMedia "manga" cfg.manga true
;
config = { pkgs, ... }: container.mkContainerConfig cfg {
services.kavita = {

View file

@ -14,6 +14,11 @@ in {
};
config = { lib, ... }: container.mkContainerConfig cfg {
networking = {
nameservers = lib.mkForce [
container.config.dns.address
];
};
services.uptime-kuma = {
enable = true;
settings = {

View file

@ -1,4 +1,4 @@
{ container, ... } @args: let
{ container, lib, ... } @args: let
cfg = container.config.watch;
in {
systemd.tmpfiles.rules = container.mkContainerDir cfg [
@ -16,7 +16,31 @@ in {
hostPath = "${cfg.storage}/cache";
isReadOnly = false;
};
};
"/cache" = {
hostPath = "${cfg.storage}/cache";
isReadOnly = false;
};
"/dev/dri" = {
hostPath = "/dev/dri";
isReadOnly = false;
};
}
// container.attachMedia "anime" cfg.anime true
// container.attachMedia "download" cfg.download true
// container.attachMedia "movie" cfg.movie true
// container.attachMedia "music" cfg.music true
// container.attachMedia "photo" cfg.photo true
// container.attachMedia "show" cfg.show true
// container.attachMedia "study" cfg.study true
// container.attachMedia "work" cfg.work true
// container.attachMedia "youtube" cfg.youtube true;
allowedDevices = [
{
modifier = "rwm";
node = "/dev/dri";
}
];
config = { ... }: container.mkContainerConfig cfg {
services.jellyfin = {

View file

@ -37,6 +37,16 @@
forceSSL = false;
};
attachMedia = type: paths: ro: builtins.listToAttrs (lib.imap0 (i: path:
{
name = "/${type}/${toString i}";
value = {
hostPath = path;
isReadOnly = ro;
};
}
) paths);
localAccess = "192.168.1.0/24";
config = {
@ -106,6 +116,7 @@
port = 8000;
};
paper = {
inherit (media) paper;
address = "10.1.0.40";
domain = "paper.${domain}";
port = 28981;
@ -154,7 +165,7 @@
storage = "${storage}/rabbitmq";
};
read = {
inherit (media) book;
inherit (media) book manga;
address = "10.1.0.39";
domain = "read.${domain}";
port = 5000;
@ -192,6 +203,7 @@
storage = "${storage}/vpn";
};
watch = {
inherit (media) anime download movie music photo show study work youtube;
address = "10.1.0.11";
domain = "watch.${domain}";
port = 8096;

View file

@ -51,21 +51,21 @@
(mkLink "Cloud" "fa-cloud" "https://${container.config.cloud.domain}")
(mkLink "Download" "fa-download" "https://${container.config.download.domain}")
(mkLink "Git" "fab fa-git-alt" "https://${container.config.download.domain}")
# (mkLink "Iot" "fa-home" "https://${container.config.iot.domain}")
# (mkLink "Mail" "fa-envelope" "https://${container.config.mail.domain}")
# (mkLink "Paper" "fa-paperclip" "https://${container.config.paper.domain}")
# (mkLink "Pass" "fa-key" "https://${container.config.pass.domain}")
# (mkLink "Paste" "fa-paste" "https://${container.config.paste.domain}")
# (mkLink "Print" "fa-print" "https://${container.config.print.domain}")
# (mkLink "Read" "fa-book" "https://${container.config.read.domain}")
# (mkLink "Search" "fa-search" "https://${container.config.search.domain}")
# (mkLink "Stock" "fa-boxes-stacked" "https://${container.config.stock.domain}")
(mkLink "Iot" "fa-home" "https://${container.config.iot.domain}")
(mkLink "Mail" "fa-envelope" "https://${container.config.mail.domain}")
(mkLink "Paper" "fa-paperclip" "https://${container.config.paper.domain}")
(mkLink "Pass" "fa-key" "https://${container.config.pass.domain}")
(mkLink "Paste" "fa-paste" "https://${container.config.paste.domain}/s")
(mkLink "Print" "fa-print" "https://${container.config.print.domain}")
(mkLink "Read" "fa-book" "https://${container.config.read.domain}")
(mkLink "Search" "fa-search" "https://${container.config.search.domain}")
(mkLink "Stock" "fa-boxes-stacked" "https://${container.config.stock.domain}")
# (mkLink "Tool" "fa-toolbox" "https://${container.config.tool.domain}")
# (mkLink "Watch" "fa-film" "https://${container.config.watch.domain}")
# (mkLink "YouTube" "fab fa-youtube" "https://${container.config.yt.domain}")
(mkLink "Watch" "fa-film" "https://${container.config.watch.domain}")
(mkLink "YouTube" "fab fa-youtube" "https://${container.config.yt.domain}")
])
(mkGroup "System" "fa-shield" [
(mkLink "Hdd" "fa-hard-drive" "https://${container.config.hdd.domain}")
# (mkLink "Hdd" "fa-hard-drive" "https://${container.config.hdd.domain}")
(mkLink "NixOS Search" "fa-snowflake" "https://search.nixos.org")
(mkLink "Printer" "fa-print" "https://${container.config.printer.domain}")
(mkLink "Router" "fa-route" "https://${container.config.router.domain}")

View file

@ -265,7 +265,6 @@
modules = [
./module/AmdCpu.nix
./module/AmdGpu.nix
./module/Docker.nix
./module/Ftpd.nix
./module/RemoteBuilder.nix
./module/Sway.nix

View file

@ -1,108 +0,0 @@
{ pkgs
, const
, lib
, config
, util
, poetry2nixJobber
, pkgsJobber
, ... }: let
externalInterface = "enp4s0";
args = let
storage = "/storage/hot/container";
domain = "local";
host = "192.168.1.3";
media = {
download = [ "/tmp/download" ];
photo = [ "/tmp/in" "/tmp/out" ];
book = [ "/tmp/book_1" "/tmp/book_2" ];
};
in {
inherit storage domain host pkgs const lib config util media;
inherit poetry2nixJobber pkgsJobber;
container = import ../../container args;
};
in {
imports = [
# (import ../../container/Proxy.nix args)
];
networking.nat = {
enable = true;
internalInterfaces = [ "ve-+" ];
inherit externalInterface;
forwardPorts = with args.container.config; [
# Dns Server.
{
destination = "${dns.address}:53";
proto = "udp";
sourcePort = 53;
} {
destination = "${dns.address}:53";
proto = "tcp";
sourcePort = 53;
}
# Reverse proxy.
{
destination = "${proxy.address}:80";
proto = "tcp";
sourcePort = 80;
} {
destination = "${proxy.address}:443";
proto = "tcp";
sourcePort = 443;
}
# Cups.
{
destination = "${print.address}:${toString print.port}";
proto = "tcp";
sourcePort = 631;
} {
destination = "${print.address}:6566";
proto = "tcp";
sourcePort = 6566;
}
# Wireguard.
{
destination = "${vpn.address}:${toString vpn.port}";
proto = "udp";
sourcePort = 51820;
}
# Deluge.
{
destination = "${download.address}:${toString download.port}";
proto = "tcp";
sourcePort = 8112;
} {
destination = "${download.address}:54630-54631";
proto = "udp";
sourcePort = "54630:54631";
} {
destination = "${download.address}:54630-54631";
proto = "tcp";
sourcePort = "54630:54631";
}
# Mail.
{
destination = "${mail.address}:25";
proto = "tcp";
sourcePort = 25;
} {
destination = "${mail.address}:465";
proto = "tcp";
sourcePort = 465;
} {
destination = "${mail.address}:993";
proto = "tcp";
sourcePort = 993;
}
];
};
}

View file

@ -1,6 +1,5 @@
{ ... }: {
imports = [
# ./Container.nix
./Filesystem.nix
];
}

View file

@ -1,4 +1,4 @@
{ pkgs, style, util, ... } @args: let
{ pkgs, util, ... } @args: let
bash = import ../../module/common/bash args;
script = pkgs.writeText "backupScript" ''
source ${bash.modules}
@ -12,7 +12,7 @@
path_src="/storage/hot"
path_mount="/storage/cold_1"
path_backup="''${path_mount}/backup"
path_docker="''${path_backup}/home"
path_container="''${path_backup}/home"
path_media="/storage/cold_1/media /storage/cold_2/media"
# Check if backup drive is mounted.
@ -36,10 +36,10 @@
archive ColdMedia.txt && rm ColdMedia.txt || report "Backup : Failed to archive media list!"
cd -
# Backup docker.
docker=$(archive docker/)
bupsize=$(tdu ''${docker} | awk '{print $1}')
mv ''${docker} ''${path_docker}/ || report "Backup : Failed to save docker!"
# Backup containers.
container=$(archive container/)
bupsize=$(tdu ''${container} | awk '{print $1}')
mv ''${container} ''${path_container}/ || report "Backup : Failed to save containers!"
# Backup some media.
cd ''${path_src}/media/
@ -56,9 +56,9 @@
archive_prune ColdMediaTxt 30
cd -
# Prune old Docker copies.
cd ''${path_docker}
archive_prune Docker 7
# Prune old container copies.
cd ''${path_container}
archive_prune Container 7
cd -
# Prune game saves.

145
host/home/Container.nix Normal file
View file

@ -0,0 +1,145 @@
{ pkgs
, const
, lib
, config
, util
, poetry2nixJobber
, pkgsJobber
, ... }: let
externalInterface = "enp7s0";
args = let
storage = "/storage/hot/container";
domain = "voronind.com";
host = "192.168.1.2";
media = {
anime = [ "/storage/cold_1/media/anime" "/storage/cold_2/media/anime" ];
book = [ "/storage/hot/media/book" ];
download = [ "/storage/hot/download" ];
manga = [ "/storage/cold_1/media/manga" "/storage/cold_2/media/manga" ];
movie = [ "/storage/cold_1/media/movie" "/storage/cold_2/media/movie" ];
music = [ "/storage/hot/media/music" "/storage/cold_2/media/music" ];
paper = [ "/storage/hot/media/paper" ];
photo = [ "${storage}/cloud/data/data/cakee/files/media/photo" "/storage/cold_1/backup/tmp/photo" ];
show = [ "/storage/cold_1/media/show" "/storage/cold_2/media/show" ];
study = [ "/storage/cold_1/media/study" "/storage/cold_2/media/study" ];
work = [ "/storage/cold_2/media/work" ];
youtube = [ "/storage/cold_1/media/youtube" "/storage/cold_2/media/youtube" ];
};
in {
inherit storage domain host pkgs const lib config util media;
inherit poetry2nixJobber pkgsJobber;
container = import ../../container args;
};
in {
imports = [
(import ../../container/Change.nix args)
(import ../../container/Cloud.nix args)
(import ../../container/Ddns.nix args)
(import ../../container/Dns.nix args)
(import ../../container/Download.nix args)
(import ../../container/Git.nix args)
# (import ../../container/Hdd.nix args)
(import ../../container/Home.nix args)
(import ../../container/Iot.nix args)
(import ../../container/Jobber.nix args)
(import ../../container/Mail.nix args)
(import ../../container/Office.nix args)
(import ../../container/Paper.nix args)
(import ../../container/Pass.nix args)
(import ../../container/Paste.nix args)
(import ../../container/Photoprocess.nix args)
(import ../../container/Postgres.nix args)
(import ../../container/Print.nix args)
(import ../../container/Proxy.nix args)
(import ../../container/Rabbitmq.nix args)
(import ../../container/Read.nix args)
(import ../../container/Redis.nix args)
(import ../../container/Search.nix args)
(import ../../container/Status.nix args)
(import ../../container/Stock.nix args)
(import ../../container/Vpn.nix args)
(import ../../container/Watch.nix args)
(import ../../container/Yt.nix args)
];
networking.nat = {
enable = true;
internalInterfaces = [ "ve-+" ];
inherit externalInterface;
forwardPorts = with args.container.config; [
# Dns Server.
{
destination = "${dns.address}:53";
proto = "udp";
sourcePort = 53;
} {
destination = "${dns.address}:53";
proto = "tcp";
sourcePort = 53;
}
# Reverse proxy.
#{
# destination = "${proxy.address}:80";
# proto = "tcp";
# sourcePort = 80;
#} {
{
destination = "${proxy.address}:443";
proto = "tcp";
sourcePort = 443;
}
# Cups.
{
destination = "${print.address}:${toString print.port}";
proto = "tcp";
sourcePort = 631;
} {
destination = "${print.address}:6566";
proto = "tcp";
sourcePort = 6566;
}
# Wireguard.
{
destination = "${vpn.address}:${toString vpn.port}";
proto = "udp";
sourcePort = 51820;
}
# Deluge.
{
destination = "${download.address}:${toString download.port}";
proto = "tcp";
sourcePort = 8112;
} {
destination = "${download.address}:54630-54631";
proto = "udp";
sourcePort = "54630:54631";
} {
destination = "${download.address}:54630-54631";
proto = "tcp";
sourcePort = "54630:54631";
}
# Mail.
{
destination = "${mail.address}:25";
proto = "tcp";
sourcePort = 25;
} {
destination = "${mail.address}:465";
proto = "tcp";
sourcePort = 465;
} {
destination = "${mail.address}:993";
proto = "tcp";
sourcePort = 993;
}
];
};
}

View file

@ -1,30 +0,0 @@
{ pkgs, style, util, ... } @args: let
bash = import ../../module/common/bash args;
script = ''
docker exec -u 33 cloud php -f /var/www/html/cron.php || notify 'Nextcloud : Failed to run cron.'
'';
in {
systemd.services.nextcloud = util.mkStaticSystemdService {
enable = true;
description = "Nextcloud worker.";
serviceConfig = {
Type = "oneshot";
};
path = with pkgs; [
bashInteractive
docker
];
script = ''
${pkgs.bashInteractive}/bin/bash ${script}
'';
};
systemd.timers.nextcloud = {
timerConfig = {
OnCalendar = "hourly";
Persistent = false;
Unit = "nextcloud.service";
};
wantedBy = [ "timers.target" ];
};
}

View file

@ -1,28 +0,0 @@
{ pkgs, util, ... }: let
script = ''
in="/storage/hot/docker/cloud/data/data/cakee/files/media/photo/"
out="/storage/cold_1/backup/tmp/photo/"
docker run --rm -v "''${in}":/in -v "''${out}":/out voronind.com/photoprocess:latest
'';
in {
systemd.services.photos_process = util.mkStaticSystemdService {
enable = true;
description = "Process uploaded photos.";
serviceConfig = {
Type = "oneshot";
};
path = with pkgs; [
docker
];
script = script;
};
systemd.timers.photos_process = {
timerConfig = {
OnCalendar = "daily";
Persistent = true;
Unit = "photos_process.service";
};
wantedBy = [ "timers.target" ];
};
}

View file

@ -1,27 +0,0 @@
{ pkgs, util, ... }: let
script = ''
music="/storage/hot/media/music/"
docker run --rm -v "''${music}":/music voronind.com/yamusic:latest
'';
in {
systemd.services.yandex_music = util.mkStaticSystemdService {
enable = true;
description = "Sync music from Yandex.Music.";
serviceConfig = {
Type = "oneshot";
};
path = with pkgs; [
docker
];
script = script;
};
systemd.timers.yandex_music = {
timerConfig = {
OnCalendar = "daily";
Persistent = true;
Unit = "yandex_music.service";
};
wantedBy = [ "timers.target" ];
};
}

View file

@ -1,10 +1,8 @@
{ ... }: {
imports = [
./Backup.nix
./Container.nix
./Filesystem.nix
./Network.nix
./Nextcloud.nix
./PhotosProcess.nix
./YandexMusic.nix
];
}

View file

@ -53,14 +53,14 @@ in {
Default = "Whoogle";
Add = [
{
Alias = "w";
Description = "Google search proxy.";
IconURL = "https://google.voronind.com/favicon.ico";
Alias = "s";
Description = "Searx Search";
IconURL = "https://search.voronind.com/favicon.ico";
Method = "POST";
Name = "Whoogle";
Name = "Searx";
PostData = "q={searchTerms}";
SuggestURLTemplate = "https://google.voronind.com/autocomplete?q={searchTerms}";
URLTemplate = "https://google.voronind.com/search?q=%{searchTerms}";
SuggestURLTemplate = "https://search.voronind.com/autocomplete?q={searchTerms}";
URLTemplate = "https://search.voronind.com/search?q=%{searchTerms}";
}
];
};