This commit is contained in:
2026-03-09 10:50:12 +03:00
commit f1a81a6408
119 changed files with 8378 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
{
config,
xlib,
inputs,
...
}:
let
stable = import inputs.nixpkgs-beets {
system = "x86_64-linux";
};
in
{
services.calibre-web = {
package = stable.calibre-web;
enable = true;
# dataDir = "${xlib.dirs.services-mnt-folder}/calibre-web";
options = {
calibreLibrary = "${xlib.dirs.services-mnt-folder}/calibre-web-library";
enableBookUploading = true;
enableKepubify = true;
enableBookConversion = false;
};
listen.ip = "0.0.0.0";
listen.port = 8083;
openFirewall = true;
};
fileSystems."/var/lib/calibre-web" = {
device = "${xlib.dirs.services-mnt-folder}/calibre-web";
options = [
"bind"
"nofail"
];
};
}
+30
View File
@@ -0,0 +1,30 @@
{
lib,
...
}:
{
imports = [
../software/beets
./calibre-web.nix
./immich.nix
./miniflux.nix
./nextcloud.nix
./nginx.nix
./open-webui.nix
./postgresql.nix
./samba.nix
./stirling-pdf.nix
./syncthing.nix
./systemd.nix
./transmission.nix
./uptime-kuma.nix
./netdata.nix
# ./mealie.nix
# ./memos.nix
# ./nfs.nix
# ./node-red.nix
# ./rsync.nix
# ./trilium.nix
# ./zerotier.nix
];
}
+54
View File
@@ -0,0 +1,54 @@
{
config,
lib,
pkgs,
inputs,
xlib,
...
}:
let
master = import inputs.nixpkgs-master {
system = "x86_64-linux";
};
in
{
services = {
immich = {
enable = true;
# package = master.immich;
port = 2283;
host = "0.0.0.0";
openFirewall = true;
accelerationDevices = null;
machine-learning.enable = true;
mediaLocation = "${xlib.dirs.services-mnt-folder}/immich";
database = {
enableVectors = false;
enableVectorChord = true;
};
};
};
# fileSystems."${config.services.immich.mediaLocation}" = {
# device = "${xlib.dirs.services-folder}/immich";
# options = [
# "bind"
# "nofail"
# ];
# };
systemd.tmpfiles.rules = [
"z ${config.services.immich.mediaLocation} 0755 immich immich -"
];
users.users.immich.extraGroups = [
"video"
"render"
];
environment = {
systemPackages = with pkgs; [
immich-cli
];
};
}
+15
View File
@@ -0,0 +1,15 @@
{
config,
...
}:
{
services.mealie = {
enable = true;
listenAddress = "0.0.0.0";
port = 9000;
database.createLocally = true;
settings = {
ALLOW_SIGNUP = "false";
};
};
}
+26
View File
@@ -0,0 +1,26 @@
{
config,
xlib,
...
}:
{
services.memos = {
enable = true;
openFirewall = true;
settings = {
MEMOS_MODE = "prod";
MEMOS_ADDR = "0.0.0.0";
MEMOS_PORT = "5230";
MEMOS_DATA = config.services.memos.dataDir;
MEMOS_DRIVER = "sqlite";
MEMOS_INSTANCE_URL = "http://0.0.0.0:5230";
};
# user = "${xlib.device.username}";
# group = "users";
dataDir = "/mnt/services/memos";
};
systemd.tmpfiles.rules = [
"z /mnt/services/memos 0750 memos memos -"
];
}
+24
View File
@@ -0,0 +1,24 @@
{
config,
inputs,
xlib,
...
}:
{
services.miniflux = {
enable = true;
config = {
ADMIN_USERNAME = "";
CLEANUP_FREQUENCY = 48;
LISTEN_ADDR = "0.0.0.0:6061";
};
# adminCredentialsFile = "${inputs.zeroq-credentials}/services/miniflux/admin-pass.txt";
adminCredentialsFile = config.sops.secrets.minifluxenv.path;
};
sops.secrets.minifluxenv = {
format = "dotenv";
sopsFile = ./secrets/miniflux.env;
mode = "0650";
};
}
+25
View File
@@ -0,0 +1,25 @@
{
config,
inputs,
lib,
pkgs,
...
}:
{
services = {
netdata = {
enable = false;
config = {
web = {
"allow connections from" = "localhost netdata.local *";
"default port" = "19999";
"bind to" = "0.0.0.0";
};
};
};
};
networking.firewall.allowedTCPPorts = [
19999
];
}
+190
View File
@@ -0,0 +1,190 @@
{
config,
lib,
pkgs,
inputs,
xlib,
...
}:
let
master = import inputs.nixpkgs-master {
system = "x86_64-linux";
# config.allowUnfree = true;
# config.allowUnfreePredicate = true;
};
in
{
services = {
nextcloud-whiteboard-server = {
enable = true;
settings = {
NEXTCLOUD_URL = "http://nextcloud.local";
};
secrets = [ "${inputs.zeroq-credentials}/services/nextcloud/jwt-secret.txt" ];
};
nextcloud = {
enable = true;
package = pkgs.nextcloud33;
hostName = "nextcloud.local";
database.createLocally = true;
home = "${xlib.dirs.services-mnt-folder}/nextcloud";
configureRedis = true;
caching = {
redis = true;
memcached = true;
};
maxUploadSize = "5G";
config = {
dbtype = "pgsql";
dbuser = "nextcloud";
dbname = "nextcloud";
adminuser = "oqyude";
adminpassFile = "${inputs.zeroq-credentials}/services/nextcloud/admin-pass.txt";
};
settings = {
log_type = "file";
trusted_domains = [
"nextcloud.zeroq.ru"
"100.64.0.0"
"192.168.1.20"
"localhost"
"nextcloud.local"
];
trusted_proxies = [
"100.64.1.0"
];
overwriteprotocol = "https";
};
extraAppsEnable = true;
appstoreEnable = false;
notify_push = {
enable = false;
bendDomainToLocalhost = true;
};
phpPackage = pkgs.php85;
extraApps = {
inherit (config.services.nextcloud.package.packages.apps)
# gpoddersync
# integration_paperless
# memories
# nextpod
# onlyoffice
# phonetrack
# repod
# sociallogin
bookmarks
calendar
collectives
contacts
cookbook
cospend
dav_push
deck
files_retention
forms
groupfolders
impersonate
mail
music
#tasks?
tasks
# news
notes
# notify_push
polls
previewgenerator
richdocuments
spreed
tables
user_oidc
user_saml
whiteboard
;
# inherit (pkgs.nextcloud31Packages.apps)
# # end_to_end_encryption
# # maps
# tasks
# ;
};
};
collabora-online = {
enable = true;
port = 9980;
# package = master.collabora-online;
settings = {
server_name = "office.zeroq.ru";
ssl = {
enable = false;
termination = true;
ssl_verification = false;
};
net = {
listen = "0.0.0.0";
post_allow.host = [
"0.0.0.0"
];
};
storage.wopi = {
"@allow" = true;
host = [
"0.0.0.0/0"
];
};
};
};
onlyoffice = {
enable = false;
hostname = "0.0.0.0";
jwtSecretFile = "${inputs.zeroq-credentials}/services/onlyoffice/jwt.txt";
};
};
# fonts.packages = [ work.corefonts ];
networking.hosts = {
"localhost" = [ "nextcloud.local" ];
};
systemd.services.nextcloud-config-collabora =
let
inherit (config.services.nextcloud) occ;
wopi_url = "http://localhost:${toString config.services.collabora-online.port}";
public_wopi_url = "https://office.zeroq.ru";
wopi_allowlist = lib.concatStringsSep "," [
"0.0.0.0/0"
];
in
{
wantedBy = [ "multi-user.target" ];
after = [
"nextcloud-setup.service"
"coolwsd.service"
];
requires = [ "coolwsd.service" ];
script = ''
${occ}/bin/nextcloud-occ config:app:set richdocuments wopi_url --value ${lib.escapeShellArg wopi_url}
${occ}/bin/nextcloud-occ config:app:set richdocuments public_wopi_url --value ${lib.escapeShellArg public_wopi_url}
${occ}/bin/nextcloud-occ config:app:set richdocuments wopi_allowlist --value ${lib.escapeShellArg wopi_allowlist}
${occ}/bin/nextcloud-occ richdocuments:setup
'';
serviceConfig = {
Type = "oneshot";
};
};
# fileSystems."${config.services.nextcloud.home}" = {
# device = "${xlib.dirs.services-folder}/nextcloud";
# options = [
# "bind"
# "nofail"
# ];
# };
systemd.tmpfiles.rules = [
"z ${config.services.nextcloud.home} 0750 nextcloud nextcloud -"
];
environment.systemPackages = [
pkgs.nc4nix # Packaging helper for Nextcloud apps
];
}
+24
View File
@@ -0,0 +1,24 @@
{
config,
lib,
xlib,
...
}:
{
systemd.tmpfiles.rules = [
"z /export 0755 nobody nogroup -"
];
services.nfs = {
server = {
enable = false;
exports = ''
/export 192.168.1.20(rw,fsid=0,no_subtree_check) 192.168.1.102(rw,fsid=0,no_subtree_check)
/export/root 192.168.1.20(rw,nohide,insecure,no_subtree_check) 192.168.1.102(rw,nohide,insecure,no_subtree_check)
'';
};
};
# fileSystems."/export/root" = {
# device = "/";
# options = [ "bind" ];
# };
}
+98
View File
@@ -0,0 +1,98 @@
{
config,
lib,
pkgs,
xlib,
...
}:
{
services = {
nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
virtualHosts = {
"nextcloud.local" = {
forceSSL = false;
enableACME = false;
listen = [
{
addr = "100.64.0.0";
port = 10000;
}
{
addr = "192.168.1.20";
port = 10000;
}
];
};
# "localhost:19999" = {
# forceSSL = false;
# enableACME = false;
# listen = [
# {
# addr = "100.64.0.0";
# port = 19999;
# }
# {
# addr = "192.168.1.20";
# port = 19999;
# }
# ];
# };
"zeroq.local" = {
forceSSL = false;
enableACME = false;
root = pkgs.writeTextDir "index.html" ''
<!doctype html>
<html>
<body>
<pre>This server is running in backend.</pre>
</body>
</html>
'';
listen = [
{
addr = "100.64.0.0";
port = 80;
}
{
addr = "192.168.1.20";
port = 80;
}
];
};
# "localhost:8000" = {
# forceSSL = false;
# enableACME = false;
# listen = [
# {
# addr = "100.64.0.0";
# port = 9980;
# }
# {
# addr = "192.168.1.20";
# port = 9980;
# }
# ];
# };
# "office.zeroq.ru" = {
# forceSSL = false;
# enableACME = false;
# locations."/" = {
# proxyPass = "http://onlyoffice.local:8000";
# proxyWebsockets = true;
# };
# extraConfig = ''
# # Force nginx to return relative redirects. This lets the browser
# # figure out the full URL. This ends up working better because it's in
# # front of the reverse proxy and has the right protocol, hostname & port.
# absolute_redirect off;
# '';
# };
};
};
};
}
+21
View File
@@ -0,0 +1,21 @@
{
config,
lib,
pkgs,
xlib,
inputs,
...
}:
{
services.node-red = {
enable = false;
port = 1880;
openFirewall = true;
userDir = "${xlib.dirs.services-mnt-folder}/node-red";
configFile = "${inputs.zeroq-credentials}/configs/node-red/settings.js";
};
systemd.tmpfiles.rules = [
"z ${config.services.node-red.userDir} 0750 node-red node-red -"
];
}
+28
View File
@@ -0,0 +1,28 @@
{
config,
inputs,
lib,
pkgs,
...
}:
{
services = {
open-webui = {
enable = false;
host = "0.0.0.0";
port = 11112;
openFirewall = true;
environment = {
ANONYMIZED_TELEMETRY = "False";
DO_NOT_TRACK = "True";
SCARF_NO_ANALYTICS = "True";
OPENAI_API_BASE_URL = "http://192.168.1.100:1234/v1";
#OLLAMA_API_BASE_URL = "http://127.0.0.1:1234";
WEBUI_AUTH = "True";
ENABLE_SIGNUP = "False";
ENABLE_SIGNUP_PASSWORD_CONFIRMATION = "True";
ENABLE_VERSION_UPDATE_CHECK = "False";
};
};
};
}
+36
View File
@@ -0,0 +1,36 @@
{
config,
inputs,
lib,
pkgs,
xlib,
...
}:
let
master = import inputs.nixpkgs-master {
system = "x86_64-linux";
};
in
{
services = {
postgresql = {
enable = true;
package = pkgs.postgresql_17;
# dataDir = "${xlib.dirs.services-mnt-folder}/postgresql";
};
# postgresqlBackup.enable = true;
};
fileSystems."/var/lib/postgresql" = {
device = "${xlib.dirs.services-mnt-folder}/postgresql";
options = [
"bind"
"nofail"
];
};
systemd.tmpfiles.rules = [
"z ${xlib.dirs.services-mnt-folder}/postgresql 0760 postgres postgres -"
# "z ${config.services.postgresql.dataDir} 0760 postgres postgres -"
];
}
+70
View File
@@ -0,0 +1,70 @@
{
config,
lib,
pkgs,
xlib,
...
}:
{
services = {
rsync = {
enable = true;
jobs = {
archivesta-mobile-music = {
user = "root";
group = "root";
timerConfig = {
OnCalendar = "daily";
Persistent = true;
};
sources = [
"${xlib.dirs.server-home}/Music/"
];
destination = "${xlib.dirs.mobile-drive}/Music/";
settings = {
archive = true;
delete = true;
mkpath = true;
verbose = true;
};
};
archivesta-mobile-neo = {
user = "root";
group = "root";
timerConfig = {
OnCalendar = "daily";
Persistent = true;
};
sources = [
"${xlib.dirs.server-home}/Hosts/epral/Neo Backup/"
];
destination = "${xlib.dirs.mobile-drive}/Neo Backup/";
settings = {
archive = true;
delete = true;
mkpath = true;
verbose = true;
};
};
archivesta-services = {
user = "root";
group = "root";
timerConfig = {
OnCalendar = "daily";
Persistent = true;
};
sources = [
"${xlib.dirs.services-folder}/"
];
destination = "${xlib.dirs.archive-drive}/Services/";
settings = {
archive = true;
delete = true;
mkpath = true;
verbose = true;
};
};
};
};
};
}
+53
View File
@@ -0,0 +1,53 @@
{
config,
xlib,
...
}:
{
services.samba = {
enable = true;
settings = {
global = {
"invalid users" = [ ];
"passwd program" = "/run/wrappers/bin/passwd %u";
security = "user";
};
nixos = {
"path" = "/etc/nixos";
"browseable" = "yes";
"read only" = "no";
"valid users" = "${xlib.device.username}";
"guest ok" = "no";
"writable" = "yes";
"create mask" = 755;
"directory mask" = 755;
"force user" = "${xlib.device.username}";
"force group" = "users";
};
root = {
"path" = "/";
"browseable" = "yes";
"read only" = "no";
"valid users" = "${xlib.device.username}";
"guest ok" = "no";
"writable" = "yes";
#"create mask" = 0644;
#"directory mask" = 0644;
"force user" = "root";
"force group" = "root";
};
"${xlib.device.username}" = {
"path" = "${xlib.dirs.server-home}";
"browseable" = "yes";
"read only" = "no";
"valid users" = "${xlib.device.username}";
"guest ok" = "no";
"writable" = "yes";
"create mask" = 700;
"directory mask" = 700;
"force user" = "${xlib.device.username}";
"force group" = "users";
};
};
};
}
+8
View File
@@ -0,0 +1,8 @@
ADMIN_USERNAME=ENC[AES256_GCM,data:OhS8ZIE0Tw==,iv:LChSD428nAuCW0pIfJ6Jc9Vor6ZW+XbrU0zZa2SQ29E=,tag:8I26KuAkMP7lXInuoiIP2Q==,type:str]
ADMIN_PASSWORD=ENC[AES256_GCM,data:X7k4qIshq5cpB1m6hNGRlw==,iv:JZoTU4LJ8nw3T2dUTdODgDRH6gXiEzvPVp4F9E18pnw=,tag:03nY8zBntbpB2AJS2mizow==,type:str]
sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXcjByc2NHcEd1M1hmL3ZU\nWGRsMXBGYUtKTHFBOExDOU10S3NJTXd5WVdRClMzcHZDZVhDMTNLbEFVRDhHb3pL\nVnRXWXJTaTZCcDFRdzFsNG94NURwVXMKLS0tIFdpajcyaGdLRXM2YTRvcE55N2M5\nV2N3TEFDajhkRHVRMDQ5bTNWeHh0TTQKqwiC/ZOjLBsqO5qLvL2WtLrl2nOjb1fZ\nHxiCSutJfgGfftfk9h7nVK/ee5O3HvUlgXOjaFeD1CZMqukOIpZJhw==\n-----END AGE ENCRYPTED FILE-----\n
sops_age__list_0__map_recipient=age13l2gtk0nzr484zprp7e0pkrt0ne0j4asyn2pjmlaw73nte7t7d8q4sqtxm
sops_lastmodified=2025-10-09T22:05:48Z
sops_mac=ENC[AES256_GCM,data:1SzZFKwcKjGggKpo03T23kcYazz+bJJ3mWgQMGg+1sBkmDRxmsfiUV2bjhQOeuJIBJn5yRomQvgUAjYGNsLp8dfasChZ65KiTVSCd1rDbN2gT4tIzwWM6Dqs6LaMosU0eYzPq3JTLphy+KjLMMJtb46DSY0yf8izOV1N9xdGaLc=,iv:4vslV1ooPd/m+khKOUgFHBWoDf7EBqJmmC4TkzqwRFc=,tag:OfhcRMQsPevSn41hsyWFOg==,type:str]
sops_unencrypted_suffix=_unencrypted
sops_version=3.11.0
+17
View File
@@ -0,0 +1,17 @@
{
config,
inputs,
...
}:
# let
# pkgs-stable = import inputs.nixpkgs-stable { system = "x86_64-linux"; };
# in
{
services.stirling-pdf = {
enable = false;
# package = pkgs-stable.stirling-pdf;
environment = {
SERVER_PORT = 6060;
};
};
}
+23
View File
@@ -0,0 +1,23 @@
{
config,
xlib,
inputs,
...
}:
let
master = import inputs.nixpkgs-master {
system = "x86_64-linux";
};
in
{
services.syncthing = {
enable = true;
# package = master.syncthing;
systemService = true;
guiAddress = "0.0.0.0:8384";
configDir = "${xlib.dirs.storage}/Syncthing/${xlib.device.hostname}";
dataDir = "${xlib.dirs.server-home}";
group = "users";
user = "${xlib.device.username}";
};
}
+64
View File
@@ -0,0 +1,64 @@
{
config,
lib,
pkgs,
xlib,
...
}:
{
systemd = {
services = {
rsync-archivesta = {
# Archivesta
description = "Backup data using rsync";
requisite = [ "mnt-archive.mount" ]; # hard-code
script = ''
${pkgs.rsync}/bin/rsync -rtv --delete ${xlib.dirs.services-folder}/ ${xlib.dirs.archive-drive}/Services/
'';
serviceConfig = {
Type = "oneshot";
User = "root";
Group = "root";
Nice = 19;
IOSchedulingClass = "idle";
};
};
rsync-archivesta-lite = {
# Archivesta Lite
description = "Backup data using rsync";
requisite = [ "mnt-mobile.mount" ]; # hard-code
script = ''
${pkgs.rsync}/bin/rsync -rtv --delete ${xlib.dirs.server-home}/Music/ ${xlib.dirs.mobile-drive}/Music/
${pkgs.rsync}/bin/rsync -rtv --delete "${xlib.dirs.server-home}/Hosts/epral/Neo Backup/" "${xlib.dirs.mobile-drive}/Neo Backup/"
'';
serviceConfig = {
Type = "oneshot";
User = "root";
Group = "root";
Nice = 19;
IOSchedulingClass = "idle";
};
};
};
timers = {
rsync-archivesta = {
description = "Run rsync backup daily";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "daily";
Persistent = true;
Unit = "rsync-archivesta.service";
};
};
rsync-archivesta-lite = {
description = "Run rsync backup weekly";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "weekly";
Persistent = true;
Unit = "rsync-archivesta-lite.service";
};
};
};
};
}
+25
View File
@@ -0,0 +1,25 @@
{
config,
pkgs,
xlib,
...
}:
{
services.transmission = {
enable = false;
#credentialsFile = "${xlib.dirs.server-home}/server/transmission/settings.json";
openRPCPort = true;
package = pkgs.transmission_4;
user = "${xlib.device.username}";
group = "users";
settings = {
download-dir = "${xlib.dirs.server-home}/Downloads";
incomplete-dir = "${xlib.dirs.server-home}/Downloads/Temp";
incomplete-dir-enabled = true;
rpc-bind-address = "0.0.0.0";
rpc-port = 9091;
rpc-whitelist-enabled = false;
umask = 0;
};
};
}
+20
View File
@@ -0,0 +1,20 @@
{
config,
xlib,
...
}:
{
services.trilium-server = {
enable = false;
nginx = {
enable = true;
hostName = "trilium";
};
host = "0.0.0.0";
dataDir = "/mnt/services/trilium";
};
systemd.tmpfiles.rules = [
"z /mnt/services/trilium 0750 trilium trilium -"
];
}
+29
View File
@@ -0,0 +1,29 @@
{
config,
lib,
pkgs,
xlib,
inputs,
...
}:
{
services.uptime-kuma = {
enable = true;
settings = {
PORT = "4001";
HOST = "0.0.0.0";
};
};
systemd.tmpfiles.rules = [
"z ${xlib.dirs.services-mnt-folder}/uptime-kuma 0755 nobody nogroup -"
];
fileSystems."/var/lib/private/uptime-kuma" = {
device = "${xlib.dirs.services-mnt-folder}/uptime-kuma";
options = [
"bind"
"nofail"
];
};
}
+23
View File
@@ -0,0 +1,23 @@
{
config,
lib,
pkgs,
...
}:
{
services = {
zerotierone = {
enable = false;
joinNetworks = [
"db64858fedde087e"
];
port = 9993;
};
};
# environment = {
# systemPackages = with pkgs; [
# zerotierone
# ];
# };
}