Compare commits

138 Commits
Author SHA1 Message Date
oqyude 0fdf6c965c tape-rotation freezed 2026-09-23 22:05:13 +03:00
oqyude 5bccf7586d nix flake update 2026-09-23 22:03:40 +03:00
oqyude 2912581b99 tape rotation added 2026-09-23 21:58:39 +03:00
oqyude 72b4bdfbd8 glances fix 2026-09-22 18:31:00 +03:00
oqyude 44b85e1ebc cleaning 2026-09-22 18:05:10 +03:00
oqyude b57ca3eedf 3x-ui next 2026-09-16 16:09:51 +03:00
oqyude 309644eab2 fixes 2026-09-15 21:22:33 +03:00
oqyude ba5a2b378e nix flake update 2026-09-15 21:22:27 +03:00
oqyude 7441e7f98a 3x-ui regress 2026-09-15 00:54:31 +03:00
oqyude 99b5a8f1eb jray upd 2026-09-08 21:58:51 +03:00
oqyude 1c3a524b42 iperf3 added 2026-09-08 21:37:38 +03:00
oqyude be064aca66 nix flake update 2026-09-02 23:32:34 +03:00
oqyude 839b97d01a justray and usbtree 2026-09-02 17:08:18 +03:00
oqyude 482d32e1a6 microfix 2026-09-02 13:35:58 +03:00
oqyude e1d276097d refactoring 2026-08-29 04:05:38 +03:00
oqyude 7f5ea81f37 3x-ui: make module generic via xlib.services.3x-ui options
The 3x-ui container config was hardcoded for vds: it mounted the LE
cert for pubray1.zeroq.su and published host:15380→container:443 for
Xray REALITY. The server imports the same module but for x.zeroq.su
(no REALITY inbound, no cert needed by 3x-ui itself yet).

Add two options so each device picks what it needs:
  - xlib.services.3x-ui.certDomain: domain whose LE cert is mounted
    at /root/cert/{fullchain,key}.pem. null means no cert mount.
  - xlib.services.3x-ui.reality443Forwarding: when true, also publish
    host:15380→container:443 for nginx stream SNI-routed REALITY.

vds sets both. Server sets only certDomain (kept harmless; nginx
still terminates TLS for x.zeroq.su, so the mounted cert is unused
until/unless 3x-ui is reconfigured to terminate TLS itself).
2026-08-28 01:17:59 +03:00
oqyude 11af2c150a vds: drop pubrayx1.zeroq.su from SNI map — Xray now served under pubray1
All Xray REALITY clients already connect to VDS_IP via
pubray1.zeroq.su (or any of its subdomains). Removing the explicit
pubrayx1.zeroq.su → xray rule means the default route catches it.
This way we only have to publish one domain (pubray1.zeroq.su)
in subscriptions instead of two.

Companion change in x-ui.db (separate runbook step): subURI set
to https://pubray1.zeroq.su/subs/ so regenerated subscriptions
emit URLs under pubray1.zeroq.su, not x.zeroq.su.
2026-08-28 00:56:28 +03:00
oqyude 26e53e96bd vds: SNI-route TLS on 443 to Xray (15380→443) and 3x-ui panel (2049)
nginx stream + ssl_preread reads the ClientHello SNI and forwards the
raw TCP stream (no TLS termination) to either:
  - 3x-ui panel on 127.0.0.1:2049 (SNI=pubray1.zeroq.su)
  - Xray on 127.0.0.1:15380 (SNI=pubrayx1.zeroq.su or default)

podman maps host:15380 → container:443 so Xray inside sees the client
on port 443 (matching its REALITY config) even though the host-side
port from podman's perspective is 15380. Host:2049 still maps to
container:2049 — 3x-ui now terminates TLS itself using the Let's
Encrypt cert mounted from /var/lib/acme/pubray1.zeroq.su/.

x-ui.db: webCertFile, webKeyFile and webDomain set so the panel
answers HTTPS on 2049. nginx no longer owns a server block on 443 —
only an ACME-only vhost for cert renewal.

REALITY inbound on container:443 still needs to be created via the
panel UI (the xrayTemplateConfig doesn't have it yet). The host-side
and routing plumbing is ready for it.
2026-08-28 00:36:54 +03:00
oqyude 0c2b45ea6f Revert "vds/nginx: forward real client IP to 3x-ui"
This reverts commit 2cd636b6d4.
2026-08-28 00:12:14 +03:00
oqyude 2cd636b6d4 vds/nginx: forward real client IP to 3x-ui
With podman bridge networking, 3x-ui no longer sees the actual
client IP — it sees the bridge gateway. Without explicit
proxy_set_header directives, subscription URLs, geo-rules, logs
and fail2ban will all treat every request as coming from the same
IP.

Apply Host/X-Real-IP/X-Forwarded-For/X-Forwarded-Proto to all
3x-ui locations so the panel keeps working as if it were on
host network.
2026-08-27 23:28:41 +03:00
oqyude 2bc02c316d podman changes 2026-08-27 23:21:18 +03:00
oqyude 0bbb19b429 nix flake update 2026-08-24 01:33:25 +03:00
oqyude cbf731495a minecraft: use jdk25 for fabric 26.2 server 2026-08-12 00:22:53 +03:00
oqyude b933436a6e minecraft: use linkFarmFromDrvs for mods 2026-08-11 23:36:28 +03:00
oqyude 0585f234ba minecraft: add 26.2 mods (lithium/ferritecore/krypton) 2026-08-11 23:34:26 +03:00
oqyude 133db71db0 minecraft-server setup 2026-08-11 23:14:16 +03:00
oqyude 411c118500 br v4 2026-08-11 22:13:53 +03:00
oqyude 056e5895fe br v3 2026-08-11 04:03:42 +03:00
oqyude 843f0bafa1 br v2 2026-08-11 03:05:52 +03:00
oqyude 871fad26d4 big refactoring 2026-08-11 02:31:00 +03:00
oqyude cc12ab5bba refactoring 2026-08-10 03:36:19 +03:00
oqyude e66bbef553 3x-ui on server 2026-08-09 23:51:49 +03:00
oqyude 5b3da95fc2 path refactoring 2026-08-09 01:11:23 +03:00
oqyude 27d81a27e2 nix flake update 2026-08-08 19:24:19 +03:00
oqyude cedc856a02 server preparing migration 2026-08-08 19:24:14 +03:00
oqyude 5f6288bd15 unused code 2026-08-08 17:48:43 +03:00
oqyude 682ab4aa01 path moving 2026-08-07 20:40:27 +03:00
oqyude f61d45a279 termux-api: set CMAKE_POLICY_VERSION_MINIMUM=3.5
Upstream CMakeLists.txt declares cmake_minimum_required(3.0.0), but modern
CMake removed compatibility with < 3.5 and refuses to configure.
2026-08-07 19:32:08 +03:00
oqyude caad27900b termux: declarative ~/.ssh/config + termux-api package
- home/termux.nix: programs.ssh.settings with the 7 known hosts
  (replaces hand-copied ~/.ssh/config; ssh aliases z-s/z-st/z-o/z-ot
  removed, lamet/pubray-1 kept since they have no Host entry)
- modules/termux/termux-api.nix: build termux-api 0.59.1 (cmake,
  am resolved from PATH, shebangs fixed); adds termux-battery-status,
  termux-notification, termux-clipboard-*, etc. Needs the Termux:API
  Android app (com.termux.api from F-Droid) as the actual backend
- mobile.nix: enable android-integration.am (termux-am backend for am)
2026-08-07 19:28:29 +03:00
oqyude 1841f9394c termux: create channels/nixpkgs under real symlink target (dangling symlink blocks mkdir -p) 2026-08-07 03:37:43 +03:00
oqyude d5d62393e3 termux: create .nix-defexpr/channels/nixpkgs/.keep via activation (home-manager cannot link into symlinked dir) 2026-08-07 03:35:19 +03:00
oqyude 58c6e5d48e termux: drop tailscaled (cannot run in proot, SELinux netlink), export SVDIR=/etc/service in zshenv 2026-08-07 03:31:06 +03:00
oqyude 566bc12f00 supervisor termux 2026-08-07 03:03:47 +03:00
oqyude bc9b2dc792 sshd setup for termux 2026-08-07 01:38:46 +03:00
oqyude af90756661 termux setup 2026-08-06 22:57:19 +03:00
oqyude 1856f9e4fd droid: set user.shell to zsh (nix-on-droid manages passwd, chsh is useless) 2026-08-06 18:59:37 +03:00
oqyude 6b426eaa55 add termux device type with shared home-manager userspace module 2026-08-06 17:53:11 +03:00
oqyude 8434688515 nix-on-droid testing branch + lock 2026-08-06 16:19:48 +03:00
oqyude 2a8b15ce01 test 2026-08-06 14:42:27 +03:00
oqyude 30bf6f8da6 gitignore update 2026-08-06 11:53:51 +03:00
oqyude c846fa2321 add nix-on-droid epral config 2026-08-05 16:23:16 +03:00
oqyude 38948e0462 small changes 2026-08-05 11:57:07 +03:00
oqyude c9b15dea59 power settings for server 2026-08-04 11:26:31 +03:00
oqyude 868fa7cdd7 nix flake update 2026-08-03 11:19:04 +03:00
oqyude cb502e8972 coredns server fix 2026-07-31 10:52:24 +03:00
oqyude 5739ccfcaf nextcloud changes 2026-07-28 03:02:52 +03:00
oqyude 1f1b6efdf0 nix flake update 2026-07-25 23:51:36 +03:00
oqyude f1ac4662fd onlyoffice try to deny regress 2026-07-17 12:42:44 +03:00
oqyude 63c46c80ef navidrome setup 2026-07-17 12:32:29 +03:00
oqyude 521d922961 nextcloud update 2026-07-16 23:34:06 +03:00
oqyude e5e9dfd1de samba fixup 2026-07-16 17:33:19 +03:00
oqyude 867a3227b8 calibre fixup 2026-07-16 01:14:47 +03:00
oqyude 7e8cc45a85 nix flake update 2026-07-16 00:14:03 +03:00
oqyude 69c53ccd65 fixup for onlyoffice (disabling) 2026-07-16 00:12:52 +03:00
oqyude 536bdf801e homebox added 2026-07-15 23:08:18 +03:00
oqyude 9a2372caf8 nix flake update 2026-07-12 18:01:46 +03:00
oqyude 870f36ec9d opencode serve on su 2026-07-10 11:17:45 +03:00
oqyude 85ea78b4b8 varlib reconfig 2026-07-08 12:55:40 +03:00
oqyude 6079ccc25a nixpkgs unstable set 2026-07-07 12:19:07 +03:00
oqyude 5dd7a585a5 nix flake update 2026-07-06 01:56:06 +03:00
oqyude 7cbdd5860b proxy-suite added 2026-07-04 23:33:33 +03:00
oqyude f2740e87a0 node backup added 2026-07-04 22:54:38 +03:00
oqyude d8300035cf syncthing arpa 2026-07-03 21:15:55 +03:00
oqyude 1607482cb8 samba extend 2026-07-01 22:57:41 +03:00
oqyude 3ec5efb090 local dns test and chrony added 2026-06-29 23:03:17 +03:00
oqyude e2e0e57918 new era dns 2026-06-24 11:44:13 +03:00
oqyude 0893ad28e7 new era nextcloud 2026-06-24 03:15:07 +03:00
oqyude ee75c68ec3 dns fix 2026-06-24 02:30:55 +03:00
oqyude ba7b36f16e step-ca config 2026-06-24 00:15:03 +03:00
oqyude c77915d0d1 nix flake update 2026-06-21 10:43:21 +03:00
oqyude 86e74f585a dns-server setup 2026-06-17 12:25:24 +03:00
oqyude 3c3e3c75fb n8n removed 2026-06-15 22:35:21 +03:00
oqyude acd8b33a8b coredns added 2026-06-14 22:10:22 +03:00
oqyude 624b63bc02 n8n added 2026-06-14 19:05:58 +03:00
oqyude 544aafd919 step-ca added 2026-06-14 01:59:39 +03:00
oqyude 6468c6583e nix flake update 2026-06-13 00:11:38 +03:00
oqyude b2b4883627 try to setup gitea 2026-06-10 12:38:23 +03:00
oqyude ebd2e99066 try to fix onlyoffice
now its working in lan)
2026-06-09 23:13:35 +03:00
oqyude 7514df3df3 cpp tools in wsl 2026-06-08 21:56:04 +03:00
oqyude 8ca46a632c nix flake update 2026-06-05 16:50:35 +03:00
oqyude aee5162344 nextcloud for lan 2026-06-04 20:40:17 +03:00
oqyude b001652162 bentopdf added 2026-05-31 14:26:24 +03:00
oqyude e0e908c79d nix flake update 2026-05-30 18:15:23 +03:00
oqyude f6027f7b9a nix flake update 2026-05-25 20:18:58 +03:00
oqyude 4820c7d745 systemd units for rsync rewrite 2026-05-18 15:11:27 +03:00
oqyude 52e88c1da1 systemd-routine - prebuild 2026-05-18 14:19:51 +03:00
oqyude 98c923f98f nix flake update 2026-05-16 12:40:20 +03:00
oqyude cde8866383 win+space
староверим)
2026-05-06 13:01:22 +03:00
oqyude acf2452b84 beets env update 2026-05-06 12:39:54 +03:00
oqyude 81ab80c94a fixes 2026-05-05 20:30:00 +03:00
oqyude c752cb2e7f pcbu-desktop try 2026-05-04 20:23:20 +03:00
oqyude 397bf49326 nix-serve added 2026-05-04 09:19:53 +03:00
oqyude 2df6ee7c3a nix flake update and changed to nixos-unstable 2026-05-03 19:00:04 +03:00
oqyude 1d84fb7354 nix flake update 2026-05-02 11:27:32 +03:00
oqyude 86e20597a7 refact, beets 3.14py 2026-04-21 12:24:54 +03:00
oqyude 58d631c0fb something 2026-04-17 20:46:49 +03:00
oqyude da6aad4fcd beets changes 2026-04-17 12:57:49 +03:00
oqyude a319150b99 nix flake update 2026-04-17 11:56:10 +03:00
oqyude 94b7d30c02 syn ddos defence 2026-04-13 11:13:54 +03:00
oqyude 7f1f714e8c glances added 2026-04-11 12:54:52 +03:00
oqyude f5c6d40c89 systemd-mounts...
lix frozen-removed, rovr frozen-removed
2026-04-10 14:07:07 +03:00
oqyude fb1637c44e nix flake update 2026-04-10 11:31:20 +03:00
oqyude a5a2763f66 new domain 2026-04-10 10:57:20 +03:00
oqyude bcd4bcffd5 beets fixed 2026-04-07 01:05:23 +03:00
oqyude c17d01c3a1 nix flake update 2026-04-06 16:11:57 +03:00
oqyude 557351e27b remnawave setup pause 2026-04-06 15:57:45 +03:00
oqyude c4b52f942c try to setup peerix and removed 2026-04-06 15:53:31 +03:00
oqyude 4d54a3b6fb remnawave editing 2026-04-05 02:37:56 +03:00
oqyude c3f8acad12 remnawave init 2026-04-05 02:28:14 +03:00
oqyude cf77fa88bf n8n enable 2026-04-01 12:50:28 +03:00
oqyude efcb4232a5 try to setup onlyoffice 2026-03-31 01:47:42 +03:00
oqyude 5909a72654 sops and onlyoffice evolution 2026-03-30 15:50:00 +03:00
oqyude 7d731bd1c4 ref 2026-03-29 14:46:01 +03:00
oqyude 713bccc3b1 nix flake update 2026-03-29 12:57:26 +03:00
oqyude c8c7c68c04 some fix 2026-03-27 17:56:12 +03:00
oqyude 6297df804e nix flake update 2026-03-23 17:52:28 +03:00
oqyude 8797821d94 rovr package added 2026-03-16 23:22:18 +03:00
oqyude 6f278b36e7 disable unused 2026-03-16 18:22:17 +03:00
oqyude ce19d10585 try to setup tuckr 2026-03-16 18:21:24 +03:00
oqyude e7daeccb27 netdata enabled 2026-03-12 11:40:58 +03:00
oqyude be816fe3bd turn on swap 2026-03-10 15:43:16 +03:00
oqyude af373baecc refind is rofl
121

1

12

12

1

12

12

12

1

asd
2026-03-09 22:07:18 +03:00
oqyude efa1ca2f0f beets channel change 2026-03-09 20:06:00 +03:00
oqyude e36db0e4ed nix flake update 2026-03-09 19:44:12 +03:00
oqyude a24f20cefb unused flake inputs removed 2026-03-09 19:44:12 +03:00
oqyude 40d2d29055 refind bootloader appear 2026-03-09 19:44:12 +03:00
oqyude 3d3baf1780 try to setup fresh-editor, no result
1

1

1

1

1

12
2026-03-09 12:08:59 +03:00
oqyude f1a81a6408 Init 2026-03-09 10:50:12 +03:00
151 changed files with 4903 additions and 4921 deletions
+1
View File
@@ -0,0 +1 @@
* text=auto eol=lf
+2
View File
@@ -0,0 +1,2 @@
.vscode
.omo
+1 -1
View File
@@ -1 +1 @@
I'm a super newbie who just posted my stuff here. Now maybe simple newbie
I'm a super newbie who just posted my stuff here. Now maybe about intermediate
+15 -27
View File
@@ -1,30 +1,18 @@
{ inputs, ... }@flakeContext:
let
nixosModule =
{
config,
lib,
modulesPath,
pkgs,
xlib,
...
}:
{
imports = [
inputs.self.nixosModules.default
];
system = {
stateVersion = "26.05";
};
};
in
inputs.nixpkgs.lib.nixosSystem {
{
deviceType = "minimal";
modules = [
nixosModule
(
{
inputs,
...
}:
{
imports = [
inputs.self.nixosModules.default
];
system.stateVersion = "26.05";
}
)
];
system = "x86_64-linux";
specialArgs = {
deviceType = "minimal";
};
}
+15 -7
View File
@@ -1,12 +1,20 @@
{ inputs, ... }@flakeContext:
let
mkSystem = import ../lib/mkSystem.nix flakeContext;
in
{
nixosConfigurations = {
default = import ./any.nix flakeContext; # default
atoridu = import ./mini-pc.nix flakeContext; # atoridu
rydiwo = import ./mini-laptop.nix flakeContext; # rydiwo
otreca = import ./vds.nix flakeContext; # vds
otreca-new = import ./vds-new.nix flakeContext; # vds-new
sapphira = import ./server.nix flakeContext; # sapphira
wsl = import ./wsl.nix flakeContext; # wsl
default = mkSystem (import ./any.nix); # default
atoridu = mkSystem (import ./mini-pc.nix); # atoridu
rydiwo = mkSystem (import ./mini-laptop.nix); # rydiwo
otreca = mkSystem (import ./vds.nix); # vds
sapphira = mkSystem (import ./server.nix); # sapphira
wsl = mkSystem (import ./wsl.nix); # wsl
};
nixOnDroidConfigurations = {
epral = import ./mobile.nix flakeContext; # epral (Android via nix-on-droid)
# Alias so a plain `nix-on-droid switch` from a local clone
# (~/.config/nix-on-droid) picks up the device config without `#epral`.
default = import ./mobile.nix flakeContext;
};
}
+1 -1
View File
@@ -18,7 +18,7 @@
};
};
swap = {
size = "2G";
size = "6G";
content = {
type = "swap";
};
+1 -1
View File
@@ -20,7 +20,7 @@
};
};
swap = {
size = "1G";
size = "4G";
content = {
type = "swap";
};
+5 -5
View File
@@ -14,11 +14,11 @@
boot = {
initrd = {
supportedFilesystems = [
"nfs"
"nfsv4"
"overlay"
];
# supportedFilesystems = [
# "nfs"
# "nfsv4"
# "overlay"
# ];
availableKernelModules = [
"nvme"
"xhci_pci"
+8 -3
View File
@@ -28,6 +28,7 @@
kernel = {
sysctl = {
"fs.inotify.max_user_watches" = "204800";
"net.ipv4.ip_forward" = 1;
};
};
kernelModules = [
@@ -51,9 +52,13 @@
};
};
# swapDevices = [
# { device = "/dev/disk/by-partlabel/disk-main-swap"; }
# ];
zramSwap = {
enable = true;
};
swapDevices = [
{ device = "/dev/disk/by-partlabel/disk-main-swap"; }
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
-23
View File
@@ -1,23 +0,0 @@
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
fileSystems = {
"/" = {
device = lib.mkForce "/dev/disk/by-partlabel/disk-main-root"; # "/dev/disk/by-partlabel/disk-main-root";
fsType = "ext4";
};
};
# swapDevices = [
# { device = "/dev/disk/by-partlabel/disk-main-swap"; }
# ];
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}
+7 -3
View File
@@ -13,9 +13,13 @@
};
};
# swapDevices = [
# { device = "/dev/disk/by-partlabel/disk-main-swap"; }
# ];
swapDevices = [
{ device = "/dev/disk/by-partlabel/disk-main-swap"; }
];
zramSwap = {
enable = true;
};
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
+32 -134
View File
@@ -1,143 +1,41 @@
{
inputs,
...
}@flakeContext:
let
nixosModule =
{
config,
lib,
pkgs,
xlib,
...
}:
{
xlib.device = {
type = "secondary";
hostname = "rydiwo";
};
imports = with inputs; [
nixos-hardware.nixosModules.chuwi-minibook-x
./hardware/mini-laptop.nix
self.nixosModules.default
];
boot = {
kernelPackages = lib.mkDefault pkgs.linuxPackages_xanmod_stable;
loader = {
systemd-boot.enable = lib.mkDefault true;
efi.canTouchEfiVariables = lib.mkDefault true;
};
};
fileSystems."${xlib.dirs.lamet-drive}" = {
device = "/dev/disk/by-uuid/DC76BD3576BD116E";
fsType = "ntfs3";
options = [
"defaults"
"uid=1000"
"gid=1000"
"fmask=0000"
"dmask=0000"
"nofail"
deviceType = "secondary";
hostname = "rydiwo";
modules = [
(
{
lib,
pkgs,
xlib,
inputs,
...
}:
{
imports = with inputs; [
nixos-hardware.nixosModules.chuwi-minibook-x
./hardware/mini-laptop.nix
self.nixosModules.default
];
};
hardware = {
bluetooth.enable = true;
};
networking = {
hostName = "${xlib.device.hostname}";
networkmanager.enable = true;
firewall.enable = false;
};
i18n = {
extraLocaleSettings = {
LC_ADDRESS = "ru_RU.UTF-8";
LC_IDENTIFICATION = "ru_RU.UTF-8";
LC_MEASUREMENT = "ru_RU.UTF-8";
LC_MONETARY = "ru_RU.UTF-8";
LC_NAME = "ru_RU.UTF-8";
LC_NUMERIC = "ru_RU.UTF-8";
LC_PAPER = "ru_RU.UTF-8";
LC_TELEPHONE = "ru_RU.UTF-8";
LC_TIME = "ru_RU.UTF-8";
};
};
services = {
xserver = {
videoDrivers = [
"nomodeset"
];
};
syncthing = {
enable = true;
systemService = true;
configDir = "${xlib.dirs.user-storage}/Syncthing/${config.system.name}";
dataDir = "${xlib.dirs.user-home}";
group = "users";
user = "${xlib.device.username}";
};
# pipewire = {
# enable = lib.mkDefault true;
# systemWide = true;
# alsa.enable = false;
# alsa.support32Bit = true;
# pulse.enable = true;
# jack.enable = true;
# extraConfig.pipewire = {
# "99-default.conf" = {
# "context.properties" = {
# "default.clock.rate" = 96000;
# "default.clock.allowed-rates" = [
# 44100
# 48000
# 96000
# ];
# "default.clock.quantum" = 1024;
# "default.clock.min-quantum" = 256;
# "default.clock.max-quantum" = 2048;
# };
# };
# };
# };
thermald.enable = true;
earlyoom.enable = true;
openssh = {
enable = true;
allowSFTP = true;
hostKeys = [
{
path = "/etc/ssh/id_ed25519";
type = "ed25519";
}
];
settings = {
PasswordAuthentication = false;
PermitRootLogin = "yes";
UsePAM = true;
boot = {
kernelPackages = lib.mkDefault pkgs.linuxPackages_xanmod_stable;
loader = {
systemd-boot.enable = lib.mkDefault true;
efi.canTouchEfiVariables = lib.mkDefault true;
};
};
};
security = {
rtkit.enable = true;
};
hardware.intel-gpu-tools.enable = true;
fileSystems = xlib.helpers.mkNtfsMount {
path = xlib.dirs.lamet-drive;
uuid = "DC76BD3576BD116E";
mask = "0000";
};
system.stateVersion = "26.05";
};
in
inputs.nixpkgs.lib.nixosSystem {
modules = with inputs; [
nixosModule
xlib.ssh.enable = true;
hardware.intel-gpu-tools.enable = true;
system.stateVersion = "26.05";
}
)
];
system = "x86_64-linux";
specialArgs = {
deviceType = "secondary";
};
}
+49 -129
View File
@@ -1,123 +1,57 @@
{
inputs,
...
}@flakeContext:
let
nixosModule =
{
config,
lib,
pkgs,
xlib,
...
}:
{
xlib.device = {
type = "primary";
hostname = "atoridu";
};
deviceType = "primary";
hostname = "atoridu";
modules = [
(
{
lib,
pkgs,
xlib,
inputs,
...
}:
{
imports = with inputs; [
./hardware/mini-pc.nix
./disko/mini-pc.nix
./hardware/logitech.nix
self.nixosModules.default
];
imports = with inputs; [
./hardware/mini-pc.nix
./disko/mini-pc.nix
./hardware/logitech.nix
self.nixosModules.default
];
fileSystems = lib.listToAttrs (
map (xlib.helpers.mkNtfsMount) [
{
path = xlib.dirs.therima-drive;
uuid = "C0A2DDEFA2DDEA44";
enable = false;
}
{
path = xlib.dirs.vetymae-drive;
uuid = "6408433908430A0E";
enable = false;
}
{
path = xlib.dirs.soptur-drive;
uuid = "C00C56E40C56D54E";
enable = false;
}
]
);
fileSystems = {
"${xlib.dirs.therima-drive}" = {
enable = false;
device = "/dev/disk/by-uuid/C0A2DDEFA2DDEA44";
fsType = "ntfs3";
options = [
"defaults"
"uid=1000"
"gid=1000"
"fmask=0007"
"dmask=0007"
"nofail"
];
boot = {
kernelPackages = lib.mkDefault pkgs.linuxPackages_xanmod_stable;
loader = {
systemd-boot.enable = lib.mkDefault true;
efi.canTouchEfiVariables = lib.mkDefault true;
};
};
"${xlib.dirs.vetymae-drive}" = {
enable = false;
device = "/dev/disk/by-uuid/6408433908430A0E";
fsType = "ntfs3";
options = [
"defaults"
"uid=1000"
"gid=1000"
"fmask=0007"
"dmask=0007"
"nofail"
];
};
"${xlib.dirs.soptur-drive}" = {
enable = false;
device = "/dev/disk/by-uuid/C00C56E40C56D54E";
fsType = "ntfs3";
options = [
"defaults"
"uid=1000"
"gid=1000"
"fmask=0007"
"dmask=0007"
"nofail"
];
};
};
boot = {
kernelPackages = lib.mkDefault pkgs.linuxPackages_xanmod_stable;
#kernelParams = [ "usbcore.autosuspend=-1" ];
loader = {
systemd-boot.enable = lib.mkDefault true;
efi.canTouchEfiVariables = lib.mkDefault true;
};
};
hardware = {
bluetooth.enable = true;
};
# networking.firewall.allowedTCPPorts = [ ... ];
# networking.firewall.allowedUDPPorts = [ ... ];
networking = {
hostName = "${xlib.device.hostname}";
networkmanager.enable = true;
firewall.enable = false;
};
i18n = {
extraLocaleSettings = {
LC_ADDRESS = "ru_RU.UTF-8";
LC_IDENTIFICATION = "ru_RU.UTF-8";
LC_MEASUREMENT = "ru_RU.UTF-8";
LC_MONETARY = "ru_RU.UTF-8";
LC_NAME = "ru_RU.UTF-8";
LC_NUMERIC = "ru_RU.UTF-8";
LC_PAPER = "ru_RU.UTF-8";
LC_TELEPHONE = "ru_RU.UTF-8";
LC_TIME = "ru_RU.UTF-8";
};
};
services = {
#logrotate.checkConfig = false;
#power-profiles-daemon.enable = false;
xserver = {
services.xserver = {
videoDrivers = [
"amdgpu"
];
};
syncthing = {
enable = true;
systemService = true;
configDir = "${xlib.dirs.user-storage}/Syncthing/${config.system.name}";
dataDir = "${xlib.dirs.user-home}";
group = "users";
user = "${xlib.device.username}";
};
pipewire = {
services.pipewire = {
enable = lib.mkDefault true;
systemWide = true;
alsa.enable = false;
@@ -140,24 +74,10 @@ let
};
};
};
thermald.enable = true;
earlyoom.enable = true;
};
nixpkgs.config.pulseaudio = true;
nixpkgs.config.pulseaudio = true;
security = {
rtkit.enable = true;
};
system.stateVersion = "26.05";
};
in
inputs.nixpkgs.lib.nixosSystem {
modules = [
nixosModule
system.stateVersion = "26.05";
}
)
];
system = "x86_64-linux";
specialArgs = {
deviceType = "primary";
};
}
+125
View File
@@ -0,0 +1,125 @@
{
inputs,
...
}@flakeContext:
let
# Host: epral (Android device via nix-on-droid, aarch64-linux)
# Integrates with the base defaultModule (imports.self.nixosModules.default),
# which is trimmed for the "termux" device type: NixOS-only modules
# (essentials, users.nix, home-manager, sops-nix, disko, grub2-themes)
# and nixpkgs.overlays are skipped so it evaluates under nix-on-droid's
# module system (class = "nixOnDroid").
nixOnDroidModule =
{
lib,
pkgs,
xlib,
...
}:
{
imports = [
inputs.self.nixosModules.strict
];
xlib.device = {
type = "termux";
hostname = "epral";
};
# Login shell. nix-on-droid writes /etc/passwd from user.shell on every
# activation, so `chsh` is useless here — set it in nix instead.
# (default is bashInteractive)
user.shell = "${pkgs.zsh}/bin/zsh";
# SSH user (matches `User oqyude` in the client's ~/.ssh/config).
# Default is "nix-on-droid"; home stays at the read-only
# /data/data/com.termux.nix/files/home either way.
user.userName = "oqyude";
# Minimal termux settings (nix-on-droid options only:
# environment.*, nix.*, time.*, user.*, system.*, android-integration.*)
# user.userName defaults to "nix-on-droid"; set it to override.
# user.home is read-only: /data/data/com.termux.nix/files/home
# Simply install just the packages
environment.packages = with pkgs; [
# User-facing stuff that you really really want to have
vim # or some other editor, e.g. nano or neovim
nano
# Some common stuff that people expect to have
bzip2
diffutils
findutils
git
gnugrep
gnupg
gnused
gnutar
gzip
hostname
man
ncurses
openssh
procps
psmisc # provides killall (attr `killall` was removed from nixpkgs)
treefmt
tzdata
unzip
util-linux # renamed from utillinux
zip
];
# Backup etc files instead of failing to activate generation if a file already exists in /etc
environment.etcBackupExtension = ".bak";
# Shared userspace home-manager config (same cozy shell as on NixOS hosts).
# nix-on-droid forces home.username / home.homeDirectory from user.*,
# so the strict module must not set them.
# xlib is injected via home-manager.extraSpecialArgs (the HM submodule
# does not inherit the nix-on-droid module args).
home-manager = {
useGlobalPkgs = true;
backupFileExtension = "hm-bak";
extraSpecialArgs = {
inherit xlib;
};
config =
{ ... }:
{
imports = [
../home/termux.nix
];
home.stateVersion = "24.05";
};
};
# Read the changelog before changing this value
system.stateVersion = "24.05";
# Set up nix for flakes
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
# Set your time zone
time.timeZone = "Europe/Moscow";
android-integration.termux-setup-storage.enable = true;
# Provides `am` (termux-am) — required by termux-api's broadcast backend.
android-integration.am.enable = true;
};
in
inputs.nix-on-droid.lib.nixOnDroidConfiguration {
pkgs = import inputs.nixpkgs {
system = "aarch64-linux";
};
modules = [
nixOnDroidModule
];
extraSpecialArgs = {
deviceType = "termux";
};
}
+76 -130
View File
@@ -1,137 +1,83 @@
{ inputs, ... }@flakeContext:
let
nixosModule =
{
config,
lib,
pkgs,
xlib,
...
}:
{
xlib.device = {
type = "server";
hostname = "sapphira";
};
{
deviceType = "server";
hostname = "sapphira";
modules = [
(
{
lib,
pkgs,
xlib,
inputs,
...
}:
{
imports = [
./hardware/server.nix
inputs.self.nixosModules.default
];
imports = [
./hardware/server.nix
inputs.self.nixosModules.default
];
boot = {
kernelPackages = pkgs.linuxPackages_xanmod_stable;
hardwareScan = true;
loader = {
systemd-boot.enable = lib.mkDefault true;
efi.canTouchEfiVariables = lib.mkDefault true;
};
};
hardware = {
bluetooth.enable = true;
graphics = {
enable = true;
extraPackages = with pkgs; [
intel-media-driver
intel-ocl
intel-vaapi-driver
];
};
intel-gpu-tools.enable = true;
};
# swapDevices = [
# { device = "/dev/disk/by-partlabel/disk-main-swap"; }
# ];
fileSystems = {
# External drive
"${xlib.dirs.server-home}" = {
device = "/dev/disk/by-uuid/37e53ebc-5343-a94d-9fe2-0ca39e13a8de";
fsType = "ext4";
};
# Archive drive
"/mnt/archive" = {
device = "/dev/disk/by-label/archive";
fsType = "exfat";
options = [
"nofail"
"uid=1000"
"gid=1000"
];
};
# Mobile SD-Card
"/mnt/mobile" = {
device = "/dev/disk/by-uuid/7EB1-DC99";
fsType = "exfat";
options = [
"nofail"
"uid=1000"
"gid=1000"
];
};
"${xlib.dirs.services-mnt-folder}" = {
device = "${xlib.dirs.services-folder}";
options = [
"bind"
"nofail"
# "uid=1000"
# "gid=1000"
# "fmask=0000"
# "dmask=0000"
];
};
};
systemd.tmpfiles.rules = [
"z ${xlib.dirs.services-mnt-folder} 0777 root root -"
];
services = {
power-profiles-daemon.enable = lib.mkForce false;
earlyoom.enable = true;
auto-cpufreq.enable = false;
throttled.enable = true;
journald = {
extraConfig = ''
SystemMaxUse=512M
'';
};
openssh = {
enable = true;
allowSFTP = true;
hostKeys = [
{
path = "/etc/ssh/id_ed25519";
type = "ed25519";
}
];
settings = {
PasswordAuthentication = false;
PermitRootLogin = "yes";
UsePAM = true;
boot = {
# kernelPackages = pkgs.linuxPackages_xanmod_stable;
hardwareScan = true;
loader = {
systemd-boot.enable = lib.mkDefault true;
efi.canTouchEfiVariables = lib.mkDefault true;
};
};
};
networking = {
hostName = "${xlib.device.hostname}";
networkmanager.enable = true;
firewall.enable = false;
};
hardware = {
bluetooth.enable = true;
graphics = {
enable = true;
extraPackages = with pkgs; [
intel-media-driver
intel-ocl
intel-vaapi-driver
];
};
intel-gpu-tools.enable = true;
};
system = {
stateVersion = "25.05";
};
};
in
inputs.nixpkgs.lib.nixosSystem {
modules = [
nixosModule
fileSystems =
(xlib.helpers.mkExfatMount {
path = xlib.dirs.archive-drive;
label = "archive";
})
// (xlib.helpers.mkExfatMount {
path = xlib.dirs.mobile-drive;
uuid = "7EB1-DC99";
})
// (xlib.helpers.mkBindMount {
what = xlib.dirs.services-folder;
where = xlib.dirs.services-mnt-folder;
})
// {
# External drive
"${xlib.dirs.server-home}" = {
device = "/dev/disk/by-uuid/37e53ebc-5343-a94d-9fe2-0ca39e13a8de";
fsType = "ext4";
};
};
systemd.tmpfiles.rules = [
"z ${xlib.dirs.services-mnt-folder} 0777 root root -"
];
xlib.ssh.enable = true;
networking = {
networkmanager.enable = true;
firewall.enable = false;
# nameservers = [
# "192.168.1.1"
# "127.0.0.1"
# ];
};
system = {
stateVersion = "25.05";
};
}
)
];
system = "x86_64-linux";
specialArgs = {
deviceType = "server";
};
}
-177
View File
@@ -1,177 +0,0 @@
{ inputs, ... }@flakeContext:
let
nixosModule =
{
config,
lib,
modulesPath,
pkgs,
xlib,
...
}:
{
xlib.device = {
type = "vds-new";
hostname = "otreca-new";
};
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
(modulesPath + "/profiles/qemu-guest.nix")
./disko/vds.nix
./hardware/vds.nix
inputs.self.nixosModules.default
];
boot = {
kernelPackages = pkgs.linuxPackages_xanmod_stable;
hardwareScan = true;
loader = {
grub = {
enable = true;
device = "nodev";
useOSProber = false;
efiSupport = false;
};
systemd-boot.enable = lib.mkDefault false;
};
};
services = {
earlyoom.enable = true;
journald = {
extraConfig = ''
SystemMaxUse=512M
'';
};
samba = {
enable = true;
openFirewall = 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" = "/home/${xlib.device.username}";
"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";
};
};
};
openssh = {
enable = true;
allowSFTP = true;
openFirewall = true;
hostKeys = [
{
path = "/etc/ssh/id_ed25519";
type = "ed25519";
}
];
settings = {
PasswordAuthentication = false;
PermitRootLogin = "yes";
UsePAM = true;
};
};
tailscale = {
enable = true;
openFirewall = true;
};
};
networking = {
nameservers = [
"1.1.1.1"
"8.8.8.8"
"2001:4860:4860::8844"
"2001:4860:4860::8888"
"2606:4700:4700::1111"
"2606:4700:4700::1001"
];
hostName = "${xlib.device.hostname}";
networkmanager.enable = true;
tempAddresses = "disabled";
dhcpcd = {
enable = true;
IPv6rs = true;
};
firewall = {
enable = true;
allowPing = true;
};
enableIPv6 = true;
interfaces.ens3 = {
useDHCP = true;
# ipv4.addresses = [
# {
# address = "31.57.158.109";
# prefixLength = 24;
# }
# ];
# ipv6.addresses = [
# {
# address = "2a13:7c00:6:102:f816:3eff:fe91:6b9e";
# prefixLength = 64;
# }
# ];
};
# defaultGateway = {
# address = "31.57.158.1";
# interface = "ens3";
# };
# defaultGateway6 = {
# address = "2a13:7c00:6:102::1";
# interface = "ens3";
# };
};
system = {
stateVersion = "25.05";
};
};
in
inputs.nixpkgs.lib.nixosSystem {
modules = [
nixosModule
];
system = "x86_64-linux";
specialArgs = {
deviceType = "vds-new";
};
}
+119 -174
View File
@@ -1,177 +1,122 @@
{ inputs, ... }@flakeContext:
let
nixosModule =
{
config,
lib,
modulesPath,
pkgs,
xlib,
...
}:
{
xlib.device = {
type = "vds";
hostname = "otreca";
};
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
(modulesPath + "/profiles/qemu-guest.nix")
./disko/vds.nix
./hardware/vds.nix
inputs.self.nixosModules.default
];
boot = {
kernelPackages = pkgs.linuxPackages_xanmod_stable;
hardwareScan = true;
loader = {
grub = {
enable = true;
device = "nodev";
useOSProber = false;
efiSupport = false;
};
systemd-boot.enable = lib.mkDefault false;
};
};
services = {
earlyoom.enable = true;
journald = {
extraConfig = ''
SystemMaxUse=512M
'';
};
samba = {
enable = true;
openFirewall = 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" = "/home/${xlib.device.username}";
"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";
};
};
};
openssh = {
enable = true;
allowSFTP = true;
openFirewall = true;
hostKeys = [
{
path = "/etc/ssh/id_ed25519";
type = "ed25519";
}
];
settings = {
PasswordAuthentication = false;
PermitRootLogin = "yes";
UsePAM = true;
};
};
tailscale = {
enable = true;
openFirewall = true;
};
};
networking = {
nameservers = [
"1.1.1.1"
"8.8.8.8"
"2001:4860:4860::8844"
"2001:4860:4860::8888"
"2606:4700:4700::1111"
"2606:4700:4700::1001"
];
hostName = "${xlib.device.hostname}";
networkmanager.enable = true;
tempAddresses = "disabled";
dhcpcd = {
enable = true;
IPv6rs = true;
};
firewall = {
enable = true;
allowPing = true;
};
enableIPv6 = true;
interfaces.ens3 = {
useDHCP = true;
# ipv4.addresses = [
# {
# address = "31.57.158.109";
# prefixLength = 24;
# }
# ];
# ipv6.addresses = [
# {
# address = "2a13:7c00:6:102:f816:3eff:fe91:6b9e";
# prefixLength = 64;
# }
# ];
};
# defaultGateway = {
# address = "31.57.158.1";
# interface = "ens3";
# };
# defaultGateway6 = {
# address = "2a13:7c00:6:102::1";
# interface = "ens3";
# };
};
system = {
stateVersion = "25.05";
};
};
in
inputs.nixpkgs.lib.nixosSystem {
{
deviceType = "vds";
hostname = "otreca";
modules = [
nixosModule
(
{
config,
lib,
modulesPath,
pkgs,
xlib,
inputs,
...
}:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
(modulesPath + "/profiles/qemu-guest.nix")
./disko/vds.nix
./hardware/vds.nix
inputs.self.nixosModules.default
];
boot = {
# kernelPackages = pkgs.linuxPackages_xanmod_stable;
hardwareScan = true;
loader = {
grub = {
enable = true;
device = "nodev";
useOSProber = false;
efiSupport = false;
};
systemd-boot.enable = lib.mkDefault false;
};
kernel.sysctl = {
"net.ipv4.tcp_syncookies" = 1;
"net.ipv4.tcp_max_syn_backlog" = 4096;
"net.ipv4.tcp_synack_retries" = 3;
"net.ipv4.tcp_syn_retries" = 3;
};
};
xlib.ssh.enable = true;
services.openssh.openFirewall = true;
services.tailscale = {
enable = true;
openFirewall = true;
};
networking = {
nameservers = [
"1.1.1.1"
"8.8.8.8"
];
networkmanager.enable = true;
tempAddresses = "disabled";
dhcpcd = {
enable = true;
IPv6rs = false;
};
firewall = {
enable = true;
allowPing = true;
};
nftables = {
enable = true;
ruleset = ''
table inet filter {
chain input {
type filter hook input priority 0;
# loopback
iif lo accept
# уже установленные
ct state established,related accept
# РЕЖЕМ SYN СРАЗУ
tcp flags syn tcp dport {80,443} limit rate 20/second burst 40 packets accept
tcp flags syn tcp dport {80,443} drop
# остальное по необходимости
}
}
'';
};
enableIPv6 = false;
interfaces.ens3 = {
useDHCP = true;
# ipv4.addresses = [
# {
# address = "31.57.158.109";
# prefixLength = 24;
# }
# ];
# ipv6.addresses = [
# {
# address = "2a13:7c00:6:102:f816:3eff:fe91:6b9e";
# prefixLength = 64;
# }
# ];
};
# defaultGateway = {
# address = "31.57.158.1";
# interface = "ens3";
# };
# defaultGateway6 = {
# address = "2a13:7c00:6:102::1";
# interface = "ens3";
# };
};
system = {
stateVersion = "25.05";
};
}
)
];
system = "x86_64-linux";
specialArgs = {
deviceType = "vds";
};
}
+41 -100
View File
@@ -1,103 +1,44 @@
{ inputs, ... }@flakeContext:
let
nixosModule =
{
config,
lib,
pkgs,
modulesPath,
xlib,
...
}:
{
xlib.device = {
type = "wsl";
hostname = "wsl";
};
imports = [
inputs.nixos-wsl.nixosModules.default
inputs.self.nixosModules.default
];
#zramSwap.enable = true;
services = {
journald = {
extraConfig = ''
SystemMaxUse=512M
'';
};
earlyoom.enable = true;
};
hardware = {
graphics.enable = true;
# amdgpu.opencl.enable = true;
# amdgpu.amdvlk.enable = true;
};
networking = {
# nameservers = [
# "1.1.1.1"
# "8.8.8.8"
# "2001:4860:4860::8844"
# "2001:4860:4860::8888"
# "2606:4700:4700::1111"
# "2606:4700:4700::1001"
# ];
hostName = "${xlib.device.hostname}";
# networkmanager.enable = true;
# tempAddresses = "disabled";
# dhcpcd = {
# enable = true;
# IPv6rs = true;
# };
firewall = {
enable = false;
allowPing = true;
};
enableIPv6 = true;
# interfaces.ens3 = {
# useDHCP = true;
# # ipv4.addresses = [
# # {
# # address = "31.57.158.109";
# # prefixLength = 24;
# # }
# # ];
# ipv6.addresses = [
# {
# address = "2a13:7c00:10:6:f816:3eff:fe36:fe1b";
# prefixLength = 64;
# }
# ];
# };
# # defaultGateway = {
# # address = "31.57.158.1";
# # interface = "ens3";
# # };
# defaultGateway6 = {
# address = "2a13:7c00:10:6::1";
# interface = "ens3";
# };
};
wsl = {
enable = true;
startMenuLaunchers = true;
useWindowsDriver = true;
defaultUser = config.xlib.device.username;
};
system.stateVersion = "24.11";
};
in
inputs.nixpkgs.lib.nixosSystem {
{
deviceType = "wsl";
hostname = "wsl";
modules = [
nixosModule
(
{
config,
lib,
pkgs,
modulesPath,
xlib,
inputs,
...
}:
{
imports = [
inputs.nixos-wsl.nixosModules.default
inputs.self.nixosModules.default
];
hardware = {
graphics.enable = true;
};
networking = {
firewall = {
enable = false;
allowPing = true;
};
enableIPv6 = true;
};
wsl = {
enable = true;
startMenuLaunchers = true;
useWindowsDriver = true;
defaultUser = config.xlib.device.username;
};
system.stateVersion = "24.11";
}
)
];
system = "x86_64-linux";
specialArgs = {
deviceType = "wsl";
};
}
-2
View File
@@ -9,7 +9,6 @@ let
user = "${inputs.self.nixosConfigurations.default.config.xlib.device.username}";
server = "sapphira";
vds = "otreca";
vds-new = "otreca-new";
mini-laptop = "rydiwo";
in
{
@@ -19,7 +18,6 @@ in
nodes = {
"${server}" = mkDeploy "${server}";
"${vds}" = mkDeploy "${vds}";
"${vds-new}" = mkDeploy "${vds-new}";
"${mini-laptop}" = mkDeploy "${mini-laptop}";
};
};
Generated
+305 -162
View File
@@ -1,26 +1,5 @@
{
"nodes": {
"compose2nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"onchg": "onchg"
},
"locked": {
"lastModified": 1768176895,
"narHash": "sha256-GvcYMsrvQ1yjehcKmnlniBQM8HP9U/v7qSvfnxj3VtA=",
"owner": "aksiksi",
"repo": "compose2nix",
"rev": "e36aecd3649f43d745a5f837bf91c27c4499e203",
"type": "github"
},
"original": {
"owner": "aksiksi",
"repo": "compose2nix",
"type": "github"
}
},
"deploy-rs": {
"inputs": {
"flake-compat": [
@@ -34,11 +13,11 @@
]
},
"locked": {
"lastModified": 1770019181,
"narHash": "sha256-hwsYgDnby50JNVpTRYlF3UR/Rrpt01OrxVuryF40CFY=",
"lastModified": 1789404474,
"narHash": "sha256-UXFQ7tFiwn8sPz0EV4CBB2PCf/ZiGIHWn/6MXk81Lxs=",
"owner": "serokell",
"repo": "deploy-rs",
"rev": "77c906c0ba56aabdbc72041bf9111b565cdd6171",
"rev": "e760371d631165e7d8de5b0dcf148e21ec4c16f0",
"type": "github"
},
"original": {
@@ -54,11 +33,11 @@
]
},
"locked": {
"lastModified": 1769524058,
"narHash": "sha256-zygdD6X1PcVNR2PsyK4ptzrVEiAdbMqLos7utrMDEWE=",
"lastModified": 1789770686,
"narHash": "sha256-uZkBR7yHdIKUFB5SZdfgh1qkGfI3XmYmI/lTiquxbck=",
"owner": "nix-community",
"repo": "disko",
"rev": "71a3fc97d80881e91710fe721f1158d3b96ae14d",
"rev": "725ea35e410ad83be4931d1bff7e090eacaf3563",
"type": "github"
},
"original": {
@@ -82,18 +61,24 @@
"type": "github"
}
},
"flake-utils": {
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"justray",
"nixpkgs"
]
},
"locked": {
"lastModified": 1652776076,
"narHash": "sha256-gzTw/v1vj4dOVbpBSJX4J0DwUR6LIyXo7/SuuTJp1kM=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "04c1b180862888302ddfb2e3ad9eaa63afc60cf8",
"lastModified": 1788450739,
"narHash": "sha256-glZLQlzIn1fXH6PazR2iUmTo7kzzyYSshrWhLS9TqCU=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "31729ca8cbdb4fa927b34e5f4353e6a83f39e993",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
@@ -104,11 +89,11 @@
]
},
"locked": {
"lastModified": 1757136219,
"narHash": "sha256-tKU+vq34KHu/A2wD7WdgP5A4/RCmSD8hB0TyQAUlixA=",
"lastModified": 1788271742,
"narHash": "sha256-H4IIqM+fmq9t3ZPHGs9kiuoQzau9AhCGQBSfClqQ/44=",
"owner": "vinceliuice",
"repo": "grub2-themes",
"rev": "80dd04ddf3ba7b284a7b1a5df2b1e95ee2aad606",
"rev": "4c5a77125b93f833edc9bf7b14a899faa8ac79c6",
"type": "github"
},
"original": {
@@ -124,11 +109,11 @@
]
},
"locked": {
"lastModified": 1771037579,
"narHash": "sha256-NX5XuhGcsmk0oEII2PEtMRgvh2KaAv3/WWQsOpxAgR4=",
"lastModified": 1790128814,
"narHash": "sha256-6Gm9q+wW3E4Ey4F6wEbJAwaMsEK6hvCYfTW7yY64ZfA=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "05e6dc0f6ed936f918cb6f0f21f1dad1e4c53150",
"rev": "0b2f1129177f70c5f0f5d88bb53c49ca47d0bfc0",
"type": "github"
},
"original": {
@@ -137,56 +122,148 @@
"type": "github"
}
},
"musnix": {
"justray": {
"inputs": {
"flake-parts": "flake-parts",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1767232402,
"narHash": "sha256-li+h6crnhc5Zqs+M6pn7D7M0W9M63ECNennDjRgzioE=",
"owner": "musnix",
"repo": "musnix",
"rev": "d65f98e0b1f792365f1705653d7b2d266ceeff6e",
"lastModified": 1790165840,
"narHash": "sha256-nQ3uCXiUGTLD/UtuChc2XlStYg9a33PYrkDitmmqxW8=",
"owner": "luynrs",
"repo": "justray",
"rev": "4073f3fb223613e4d780dafad6f93b5c266061a2",
"type": "github"
},
"original": {
"owner": "musnix",
"repo": "musnix",
"owner": "luynrs",
"repo": "justray",
"type": "github"
}
},
"nix-pre-commit": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [
"compose2nix",
"onchg",
"nixpkgs"
]
},
"nfqws2-keenetic": {
"flake": false,
"locked": {
"lastModified": 1653259102,
"narHash": "sha256-XfCEu4zur/N2Dk4v8wFiQAgJ7bgNqPqwWp1vBXkeczM=",
"owner": "jmgilman",
"repo": "nix-pre-commit",
"rev": "6a99b2711c7eac9960939d8eb91e84322b22d50c",
"lastModified": 1789144514,
"narHash": "sha256-G+LvvXDqzYm8SOXNc3N+HIzvD9DR3J+WT+HHDdmjB0Y=",
"owner": "nfqws",
"repo": "nfqws2-keenetic",
"rev": "fa22c177b340e73d8b8a94b295af20e0228c4c22",
"type": "github"
},
"original": {
"owner": "jmgilman",
"repo": "nix-pre-commit",
"owner": "nfqws",
"repo": "nfqws2-keenetic",
"type": "github"
}
},
"nix-formatter-pack": {
"inputs": {
"nixpkgs": [
"nix-on-droid",
"nixpkgs"
],
"nmd": [
"nix-on-droid",
"nmd"
],
"nmt": "nmt"
},
"locked": {
"lastModified": 1705252799,
"narHash": "sha256-HgSTREh7VoXjGgNDwKQUYcYo13rPkltW7IitHrTPA5c=",
"owner": "Gerschtli",
"repo": "nix-formatter-pack",
"rev": "2de39dedd79aab14c01b9e2934842051a160ffa5",
"type": "github"
},
"original": {
"owner": "Gerschtli",
"repo": "nix-formatter-pack",
"type": "github"
}
},
"nix-minecraft": {
"inputs": {
"flake-compat": [
"flake-compat"
],
"nixpkgs": [
"nixpkgs"
],
"systems": [
"nix-systems"
]
},
"locked": {
"lastModified": 1790137578,
"narHash": "sha256-luzO2Bo/RxUHqTPxBttSB1QVzM9Y5s+Iwpip6SjWdWo=",
"owner": "Infinidoge",
"repo": "nix-minecraft",
"rev": "2e6a1d1ceb4da6b6ffb3980bc7993b3d057cd4db",
"type": "github"
},
"original": {
"owner": "Infinidoge",
"repo": "nix-minecraft",
"type": "github"
}
},
"nix-on-droid": {
"inputs": {
"home-manager": [
"home-manager"
],
"nix-formatter-pack": "nix-formatter-pack",
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-docs": "nixpkgs-docs",
"nixpkgs-for-bootstrap": "nixpkgs-for-bootstrap",
"nmd": "nmd"
},
"locked": {
"lastModified": 1772387862,
"narHash": "sha256-o7q9flWMCsFW2mkz8TQhvPUcwFczO7VX9I6U2u2vN4o=",
"owner": "nix-community",
"repo": "nix-on-droid",
"rev": "67b105336cb06b764366bfe241afa2352de6a926",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "testing",
"repo": "nix-on-droid",
"type": "github"
}
},
"nix-systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"nixos-hardware": {
"inputs": {
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1770882871,
"narHash": "sha256-nw5g+xl3veea+maxJ2/81tMEA/rPq9aF1H5XF35X+OE=",
"lastModified": 1789978172,
"narHash": "sha256-FIRXajv1pPZ+l6On6ekkmcQ6le0Zi0ncRUoR3nB0vKA=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "af04cb78aa85b2a4d1c15fc7270347e0d0eda97b",
"rev": "9ebcb7766700d7e006d9505247bd7ce0426f4232",
"type": "github"
},
"original": {
@@ -206,11 +283,11 @@
]
},
"locked": {
"lastModified": 1770657009,
"narHash": "sha256-v/LA5ZSJ+JQYzMSKB4sySM0wKfsAqddNzzxLLnbsV/E=",
"lastModified": 1789164534,
"narHash": "sha256-DoYGPM6QpnYBLWj9gGw6ZwAzIX+HrAVov1BoT+8Jixo=",
"owner": "nix-community",
"repo": "NixOS-WSL",
"rev": "5b50ea1aaa14945d4794c80fcc99c4aa1db84d2d",
"rev": "72c92b11bb8289e6651c7fef29cc0a885fd6a255",
"type": "github"
},
"original": {
@@ -222,112 +299,101 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1770843696,
"narHash": "sha256-LovWTGDwXhkfCOmbgLVA10bvsi/P8eDDpRudgk68HA8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2343bbb58f99267223bc2aac4fc9ea301a155a16",
"type": "github"
"lastModified": 1789546076,
"narHash": "sha256-vWkSk5bbfTqdtMoSgD9FshACO8JCvXTFi+3cqEp0mH0=",
"rev": "b1b875982b17dabde9b4a37f3e229e74913e6db3",
"type": "tarball",
"url": "https://releases.nixos.org/nixos/unstable/nixos-26.11pre1074753.b1b875982b17/nixexprs.tar.xz"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
"type": "tarball",
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
}
},
"nixpkgs-master": {
"nixpkgs-docs": {
"locked": {
"lastModified": 1771056776,
"narHash": "sha256-0l776LxthDY08ujQ1h83k9z6K5vBg1bGc415AWeFOOI=",
"lastModified": 1705957679,
"narHash": "sha256-Q8LJaVZGJ9wo33wBafvZSzapYsjOaNjP/pOnSiKVGHY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d22fe1660f1f1ccbd52c9d2c09e92fe3861dd691",
"rev": "9a333eaa80901efe01df07eade2c16d183761fa3",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "master",
"ref": "release-23.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-stable": {
"nixpkgs-for-bootstrap": {
"locked": {
"lastModified": 1770770419,
"narHash": "sha256-iKZMkr6Cm9JzWlRYW/VPoL0A9jVKtZYiU4zSrVeetIs=",
"lastModified": 1772047000,
"narHash": "sha256-7DaQVv4R97cii/Qdfy4tmDZMB2xxtyIvNGSwXBBhSmo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6c5e707c6b5339359a9a9e215c5e66d6d802fd7a",
"rev": "1267bb4920d0fc06ea916734c11b0bf004bbe17e",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.11",
"repo": "nixpkgs",
"rev": "1267bb4920d0fc06ea916734c11b0bf004bbe17e",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1790046670,
"narHash": "sha256-MYiI+CzL0tuWgRPjGsKCDHqYs2T3OzMlMQWOYWG0qso=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6774f7bc253789b113a4f39285dc0fa100abeacc",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"noctalia": {
"nmd": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
"nix-on-droid",
"nixpkgs-docs"
],
"scss-reset": "scss-reset"
},
"locked": {
"lastModified": 1771045170,
"narHash": "sha256-esBQIlClWRgYYvtYW27N79fCbOUkuFj3gxwJrb8WFX4=",
"owner": "noctalia-dev",
"repo": "noctalia-shell",
"rev": "92612c09a9dce53d5dd60e53f066160f1cdf13b4",
"type": "github"
"lastModified": 1705050560,
"narHash": "sha256-x3zzcdvhJpodsmdjqB4t5mkVW22V3wqHLOun0KRBzUI=",
"owner": "~rycee",
"repo": "nmd",
"rev": "66d9334933119c36f91a78d565c152a4fdc8d3d3",
"type": "sourcehut"
},
"original": {
"owner": "noctalia-dev",
"repo": "noctalia-shell",
"type": "github"
"owner": "~rycee",
"repo": "nmd",
"type": "sourcehut"
}
},
"nypkgs": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"nmt": {
"flake": false,
"locked": {
"lastModified": 1761401328,
"narHash": "sha256-1Mylp3ZHkft5Sg5VzMpRRvSNsuuO/Oj+cBqjkFoOnRg=",
"owner": "yunfachi",
"repo": "nypkgs",
"rev": "193c13630997d000e72e9ae6f6bfe9b71f5c4b3f",
"type": "github"
"lastModified": 1648075362,
"narHash": "sha256-u36WgzoA84dMVsGXzml4wZ5ckGgfnvS0ryzo/3zn/Pc=",
"owner": "rycee",
"repo": "nmt",
"rev": "d83601002c99b78c89ea80e5e6ba21addcfe12ae",
"type": "gitlab"
},
"original": {
"owner": "yunfachi",
"repo": "nypkgs",
"type": "github"
}
},
"onchg": {
"inputs": {
"nix-pre-commit": "nix-pre-commit",
"nixpkgs": [
"compose2nix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1720368454,
"narHash": "sha256-NUSw3G2gsQX8/G64/pDBb1oitM+x13m7nFRvpiI4a+s=",
"owner": "aksiksi",
"repo": "onchg-rs",
"rev": "c42b693d10920874b3644ef1502e33318409d69c",
"type": "github"
},
"original": {
"owner": "aksiksi",
"repo": "onchg-rs",
"type": "github"
"owner": "rycee",
"repo": "nmt",
"type": "gitlab"
}
},
"plasma-manager": {
@@ -340,11 +406,11 @@
]
},
"locked": {
"lastModified": 1770766818,
"narHash": "sha256-12RCFLyAedyMOdenUi7cN3ioJPEGjA/ZG1BLjugfUVs=",
"lastModified": 1785762349,
"narHash": "sha256-jZhZkzAwc7f3exzcTDJWP2WCAchCv0iNC3UF/QsahdQ=",
"owner": "nix-community",
"repo": "plasma-manager",
"rev": "44b928068359b7d2310a34de39555c63c93a2c90",
"rev": "a19a2a029fa180911bd89c554dca1616e10f4c1d",
"type": "github"
},
"original": {
@@ -353,29 +419,66 @@
"type": "github"
}
},
"proxy-suite": {
"inputs": {
"nfqws2-keenetic": "nfqws2-keenetic",
"nixpkgs": [
"nixpkgs"
],
"z2k": "z2k",
"zapret": "zapret"
},
"locked": {
"lastModified": 1790130850,
"narHash": "sha256-k7c+KGZmNLP0ZB9jnKKJUXUTvEJC8A6kHQmZlcN8kNQ=",
"owner": "FUFSoB",
"repo": "proxy-suite-flake",
"rev": "8f65fa9c255e9350fb09f3d3cc9054034918bf49",
"type": "github"
},
"original": {
"owner": "FUFSoB",
"repo": "proxy-suite-flake",
"type": "github"
}
},
"root": {
"inputs": {
"compose2nix": "compose2nix",
"deploy-rs": "deploy-rs",
"disko": "disko",
"flake-compat": "flake-compat",
"grub2-themes": "grub2-themes",
"home-manager": "home-manager",
"musnix": "musnix",
"justray": "justray",
"nix-minecraft": "nix-minecraft",
"nix-on-droid": "nix-on-droid",
"nix-systems": "nix-systems",
"nixos-hardware": "nixos-hardware",
"nixos-wsl": "nixos-wsl",
"nixpkgs": "nixpkgs",
"nixpkgs-master": "nixpkgs-master",
"nixpkgs-stable": "nixpkgs-stable",
"noctalia": "noctalia",
"nypkgs": "nypkgs",
"nixpkgs": "nixpkgs_2",
"plasma-manager": "plasma-manager",
"proxy-suite": "proxy-suite",
"sops-nix": "sops-nix",
"utils": "utils",
"zapret": "zapret",
"zeroq-credentials": "zeroq-credentials"
}
},
"scss-reset": {
"flake": false,
"locked": {
"lastModified": 1631450058,
"narHash": "sha256-muDlZJPtXDIGevSEWkicPP0HQ6VtucbkMNygpGlBEUM=",
"owner": "andreymatin",
"repo": "scss-reset",
"rev": "0cf50e27a4e95e9bb5b1715eedf9c54dee1a5a91",
"type": "github"
},
"original": {
"owner": "andreymatin",
"repo": "scss-reset",
"type": "github"
}
},
"sops-nix": {
"inputs": {
"nixpkgs": [
@@ -383,11 +486,11 @@
]
},
"locked": {
"lastModified": 1770683991,
"narHash": "sha256-xVfPvXDf9QN3Eh9dV+Lw6IkWG42KSuQ1u2260HKvpnc=",
"lastModified": 1789890976,
"narHash": "sha256-GKwH3zpy7tartuJMG0Rv/xUsdetG1QLmTVv8UKgJLmA=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "8b89f44c2cc4581e402111d928869fe7ba9f7033",
"rev": "7214124c20c1542c90deb54af50e2f53ae02711f",
"type": "github"
},
"original": {
@@ -429,18 +532,58 @@
"type": "github"
}
},
"zapret": {
"z2k": {
"flake": false,
"locked": {
"lastModified": 1767430655,
"narHash": "sha256-f9PricXeNm3lG1tk2TepPPY+wxM5y0ezo1HSzNn4BQ8=",
"owner": "oqyude",
"repo": "zapret-easyflake",
"rev": "302e77aae5fc6030a9c3bcc781d6514d87b19d11",
"lastModified": 1789186266,
"narHash": "sha256-d9gg7s66P3pkN7d4l72ryaGC9Ayoqg4tbHaoDNbDTT4=",
"owner": "necronicle",
"repo": "z2k",
"rev": "7beb9754d65a2cafd9c1d26d382bcb61d453d5b3",
"type": "github"
},
"original": {
"owner": "oqyude",
"repo": "zapret-easyflake",
"owner": "necronicle",
"ref": "z2k-enhanced",
"repo": "z2k",
"type": "github"
}
},
"zapret": {
"inputs": {
"nixpkgs": [
"proxy-suite",
"nixpkgs"
],
"zapret-flowseal": "zapret-flowseal"
},
"locked": {
"lastModified": 1788726932,
"narHash": "sha256-MehJgJpN7BGMaDES9I0aj/YG6JkRlSj5RiZDZfclNpc=",
"owner": "kartavkun",
"repo": "zapret-discord-youtube",
"rev": "64a8ee76f4f2e4a8d2751cb732f13448ee1e4fcf",
"type": "github"
},
"original": {
"owner": "kartavkun",
"repo": "zapret-discord-youtube",
"type": "github"
}
},
"zapret-flowseal": {
"flake": false,
"locked": {
"lastModified": 1788121958,
"narHash": "sha256-WMpxbtA2OH340e4uuXR0tcUW0D6V9Kzs0KI1iKqkXBM=",
"owner": "Flowseal",
"repo": "zapret-discord-youtube",
"rev": "6cec828910d0809863205702182a3557d9d0e8c3",
"type": "github"
},
"original": {
"owner": "Flowseal",
"repo": "zapret-discord-youtube",
"type": "github"
}
},
+47 -33
View File
@@ -3,15 +3,11 @@
inputs = {
# My
zeroq-credentials.url = "git+ssh://git@github.com/oqyude/zeroq-credentials.git"; # flake of creds
zapret.url = "github:oqyude/zapret-easyflake"; # stupid flake of zapret
# nixpkgs
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
# nixpkgs-last-unstable.url = "github:NixOS/nixpkgs/6b4955211758ba47fac850c040a27f23b9b4008f";
# nixpkgs-calibre.url = "github:NixOS/nixpkgs/e6f23dc08d3624daab7094b701aa3954923c6bbb";
nixpkgs-master.url = "github:NixOS/nixpkgs/master";
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-25.11";
#nixpkgs-fingerprint.url = "github:NixOS/nixpkgs/nixos-24.11";
# nixpkgs-fingerprint.url = "github:NixOS/nixpkgs/nixos-24.11";
# nix-community
nixos-wsl = {
@@ -21,6 +17,13 @@
nixpkgs.follows = "nixpkgs";
};
};
nix-on-droid = {
url = "github:nix-community/nix-on-droid/testing"; # testing branch, used on the device
inputs = {
nixpkgs.follows = "nixpkgs";
home-manager.follows = "home-manager";
};
};
deploy-rs = {
url = "github:serokell/deploy-rs";
inputs = {
@@ -29,21 +32,24 @@
utils.follows = "utils";
};
};
justray = {
url = "github:luynrs/justray";
inputs = {
nixpkgs.follows = "nixpkgs";
};
};
utils.url = "github:numtide/flake-utils";
flake-compat.url = "github:edolstra/flake-compat";
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
nix-systems.url = "github:nix-systems/default";
# nixos-facter-modules.url = "github:numtide/nixos-facter-modules";
# flake-utils.url = "github:numtide/flake-utils";
# flake-parts.url = "github:hercules-ci/flake-parts";
# nur = {
# url = "github:nix-community/NUR";
# noctalia = {
# url = "github:noctalia-dev/noctalia-shell";
# inputs.nixpkgs.follows = "nixpkgs";
# };
noctalia = {
url = "github:noctalia-dev/noctalia-shell";
inputs.nixpkgs.follows = "nixpkgs";
};
home-manager = {
url = "github:nix-community/home-manager"; # flake:home-manager
inputs.nixpkgs.follows = "nixpkgs";
@@ -60,14 +66,30 @@
home-manager.follows = "home-manager";
};
};
proxy-suite = {
url = "github:FUFSoB/proxy-suite-flake";
inputs.nixpkgs.follows = "nixpkgs";
};
sops-nix = {
url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
grub2-themes = {
url = "github:vinceliuice/grub2-themes";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-minecraft = {
url = "github:Infinidoge/nix-minecraft";
inputs = {
flake-compat.follows = "flake-compat";
nixpkgs.follows = "nixpkgs";
systems.follows = "nix-systems";
};
};
# nix-index-database = {
# url = "github:nix-community/nix-index-database";
# inputs.nixpkgs.follows = "nixpkgs";
# };
compose2nix = {
url = "github:aksiksi/compose2nix";
inputs.nixpkgs.follows = "nixpkgs";
};
# extras
# nix-gaming.url = "github:fufexan/nix-gaming";
@@ -78,23 +100,15 @@
# flake-compat.follows = "flake-compat";
# };
# };
musnix = {
url = "github:musnix/musnix";
inputs.nixpkgs.follows = "nixpkgs";
};
grub2-themes = {
url = "github:vinceliuice/grub2-themes";
inputs.nixpkgs.follows = "nixpkgs";
};
nypkgs = {
# https://github.com/yunfachi/nypkgs
url = "github:yunfachi/nypkgs";
inputs.nixpkgs.follows = "nixpkgs";
};
sops-nix = {
url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
# musnix = {
# url = "github:musnix/musnix";
# inputs.nixpkgs.follows = "nixpkgs";
# };
# nypkgs = {
# # https://github.com/yunfachi/nypkgs
# url = "github:yunfachi/nypkgs";
# inputs.nixpkgs.follows = "nixpkgs";
# };
# stylix = {
# url = "github:danth/stylix";
# inputs = {
+1 -1
View File
@@ -5,7 +5,7 @@
imports = [
./gramps.nix
./streamrip.nix
./v2rayn.nix
# ./v2rayn.nix
./yt-dlp.nix
];
}
-11
View File
@@ -4,18 +4,7 @@
xlib,
...
}:
let
streamripPath = "${xlib.dirs.wsl-storage}/streamrip";
in
{
xdg = {
configFile = {
"streamrip" = {
source = config.lib.file.mkOutOfStoreSymlink streamripPath;
target = "streamrip";
};
};
};
home.packages = [
pkgs.streamrip
];
-12
View File
@@ -1,21 +1,9 @@
{
config,
pkgs,
xlib,
...
}:
let
streamripPath = "${xlib.dirs.wsl-storage}/streamrip";
in
{
# xdg = {
# configFile = {
# "streamrip" = {
# source = config.lib.file.mkOutOfStoreSymlink streamripPath;
# target = "streamrip";
# };
# };
# };
home.packages = [
pkgs.yt-dlp-light
];
+44 -45
View File
@@ -9,58 +9,57 @@ let
...
}:
let
mkHomeModule = username: {
imports = [
(./. + "/${xlib.device.type}.nix")
];
home = {
username = username;
stateVersion = lib.mkDefault "25.05";
homeDirectory =
if username == "root" then lib.mkDefault "/${username}" else lib.mkDefault "/home/${username}";
enableNixpkgsReleaseCheck = false;
mkUser =
username:
{
imports ? [ ],
headless ? false,
}:
{
inherit imports;
home = {
username = username;
stateVersion = lib.mkDefault "26.05";
homeDirectory =
if username == "root" then lib.mkDefault "/${username}" else lib.mkDefault "/home/${username}";
enableNixpkgsReleaseCheck = false;
};
# Headless hosts: no GUI user dirs
xdg = lib.mkIf headless {
enable = true;
autostart.enable = true;
userDirs = {
enable = true;
createDirectories = false;
desktop = null;
documents = null;
download = null;
music = null;
pictures = null;
publicShare = null;
templates = null;
videos = null;
};
};
};
};
mkRootModule = username: {
home = {
username = username;
stateVersion = lib.mkDefault "25.05";
homeDirectory =
if username == "root" then lib.mkDefault "/${username}" else lib.mkDefault "/home/${username}";
enableNixpkgsReleaseCheck = false;
};
};
mkOthersModule = username: {
imports = [
(./. + "/others/${xlib.device.type}.nix")
];
home = {
username = username;
stateVersion = lib.mkDefault "25.05";
homeDirectory =
if username == "root" then lib.mkDefault "/${username}" else lib.mkDefault "/home/${username}";
enableNixpkgsReleaseCheck = false;
};
};
in
{
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
users = {
root = mkRootModule "root";
"${xlib.device.username}" = mkHomeModule xlib.device.username;
}
//
lib.optionalAttrs
(builtins.elem xlib.device.type [
"test"
#"secondary"
#"primary"
])
{
snity = mkOthersModule "snity";
};
root = mkUser "root" { };
"${xlib.device.username}" = mkUser xlib.device.username {
imports = [
(./. + "/${xlib.device.type}.nix")
];
headless = builtins.elem xlib.device.type [
"server"
"vds"
"wsl"
];
};
};
sharedModules = [
inputs.plasma-manager.homeModules.plasma-manager
];
-28
View File
@@ -8,25 +8,6 @@
programs = {
mangohud.enable = true;
keepassxc.enable = true;
zed-editor = {
enable = false;
extensions = [
"nix"
];
userSettings = {
"telemetry" = {
"diagnostics" = false;
"metrics" = false;
};
"ui_font_size" = 20;
"buffer_font_size" = 26;
"theme" = {
"mode" = "system";
"light" = "Ayu Light";
"dark" = "Ayu Dark";
};
};
};
};
services = {
kdeconnect.enable = true;
@@ -34,12 +15,6 @@
};
home = {
packages = with pkgs; [
# Surfing
# (brave.override {
# commandLineArgs = [
# "--password-store=basic" # on purpose to make it break "--password-store=gnome-libsecret"
# ];
# })
brave
v2rayn
@@ -48,8 +23,6 @@
# amdgpu_top
vscodium
ayugram-desktop
# vesktop
# discord
gramps
kdePackages.filelight
localsend
@@ -75,7 +48,6 @@
# Games
#ludusavi
#prismlauncher
steam
#lutris
# AI
-52
View File
@@ -1,52 +0,0 @@
{
config,
lib,
pkgs,
xlib,
...
}:
let
symlinksPaths = {
"/home/oqyude/Games/PrismLaunchers" = "${config.home.homeDirectory}/Games/PrismLaunchers";
"${config.home.homeDirectory}/Games/PrismLaunchers/${config.home.username}" =
".local/share/PrismLauncher";
};
mkLinks = lib.mapAttrs' (sourcePath: targetPath: {
name = targetPath;
value.source = config.lib.file.mkOutOfStoreSymlink "${sourcePath}";
}) symlinksPaths;
in
{
imports = [
../minimal.nix
../modules/packages.nix
../modules/plasma-manager.nix
];
xdg = {
enable = true;
autostart.enable = true;
userDirs = {
enable = true;
createDirectories = true;
desktop = "${config.xdg.dataHome}/desktop";
documents = null;
download = "${config.home.homeDirectory}/Downloads";
music = "${config.home.homeDirectory}/Music";
pictures = "${config.home.homeDirectory}/Pictures";
publicShare = "${config.home.homeDirectory}/Misc/Public";
templates = null;
videos = "${config.home.homeDirectory}/Pictures/Videos";
};
};
home = {
file = mkLinks;
pointerCursor = {
enable = true;
x11.enable = true;
gtk.enable = true;
size = 24;
name = "Qogir";
package = pkgs.qogir-icon-theme;
};
};
}
-52
View File
@@ -1,52 +0,0 @@
{
config,
lib,
pkgs,
xlib,
...
}:
let
symlinksPaths = {
"/home/oqyude/Games/PrismLaunchers" = "${config.home.homeDirectory}/Games/PrismLaunchers";
"${config.home.homeDirectory}/Games/PrismLaunchers/${config.home.username}" =
".local/share/PrismLauncher";
};
mkLinks = lib.mapAttrs' (sourcePath: targetPath: {
name = targetPath;
value.source = config.lib.file.mkOutOfStoreSymlink "${sourcePath}";
}) symlinksPaths;
in
{
imports = [
../minimal.nix
../modules/packages.nix
../modules/plasma-manager.nix
];
xdg = {
enable = true;
autostart.enable = true;
userDirs = {
enable = true;
createDirectories = true;
desktop = "${config.xdg.dataHome}/desktop";
documents = null;
download = "${config.home.homeDirectory}/Downloads";
music = "${config.home.homeDirectory}/Music";
pictures = "${config.home.homeDirectory}/Pictures";
publicShare = "${config.home.homeDirectory}/Misc/Public";
templates = null;
videos = "${config.home.homeDirectory}/Pictures/Videos";
};
};
home = {
file = mkLinks;
pointerCursor = {
enable = true;
x11.enable = true;
gtk.enable = true;
size = 24;
name = "Qogir";
package = pkgs.qogir-icon-theme;
};
};
}
+1 -5
View File
@@ -8,12 +8,8 @@
let
symlinksPaths = {
# cfg
"${xlib.dirs.user-storage}/ssh/config" = ".ssh/config";
"${xlib.dirs.user-storage}/beets" = ".config/beets";
"${xlib.dirs.user-storage}/ludusavi" = ".config/ludusavi";
"${xlib.dirs.user-storage}/solaar" = ".config/solaar";
"${xlib.dirs.user-storage}/easyeffects" = ".config/easyeffects";
"${xlib.dirs.user-storage}/KeePassXC" = ".config/keepassxc";
"${xlib.dirs.user-storage}/v2rayN" = ".local/share/v2rayN";
"/etc/nixos" = "Configuration";
@@ -36,7 +32,7 @@ in
./modules/dconf.nix
./modules/packages.nix
./modules/plasma-manager.nix
./modules/noctalia.nix
# ./modules/noctalia.nix
];
xdg = {
enable = true;
+2 -7
View File
@@ -8,18 +8,13 @@
let
symlinksPaths = {
# cfg
"${xlib.dirs.user-storage}/ssh/config" = ".ssh/config";
"${xlib.dirs.user-storage}/beets" = ".config/beets";
"${xlib.dirs.user-storage}/ludusavi" = ".config/ludusavi";
"${xlib.dirs.user-storage}/solaar" = ".config/solaar";
"${xlib.dirs.user-storage}/easyeffects" = ".config/easyeffects";
"${xlib.dirs.user-storage}/KeePassXC" = ".config/keepassxc";
"${xlib.dirs.user-storage}/v2rayN" = ".local/share/v2rayN";
"/etc/nixos" = "Configuration";
"${config.home.homeDirectory}/Games/PrismLaunchers/${config.home.username}" =
".local/share/PrismLauncher";
#"${xlib.dirs.lamet-drive}/Users/oqyude/Music" = "Music";
"${xlib.dirs.lamet-drive}/Users/oqyude/Music" = "Music";
};
mkLinks = lib.mapAttrs' (sourcePath: targetPath: {
name = targetPath;
@@ -32,7 +27,7 @@ in
./modules/dconf.nix
./modules/packages.nix
./modules/plasma-manager.nix
./modules/noctalia.nix
# ./modules/noctalia.nix
];
xdg = {
enable = true;
+2 -28
View File
@@ -5,38 +5,12 @@
xlib,
...
}:
let
symlinksPaths = {
"${config.home.homeDirectory}/External/Music" = "Music";
"${xlib.dirs.storage}/beets" = ".config/beets";
"${xlib.dirs.storage}/ssh/config" = ".ssh/config";
"${xlib.dirs.storage}/ssh/known_hosts" = ".ssh/known_hosts";
};
mkLinks = lib.mapAttrs' (sourcePath: targetPath: {
name = targetPath;
value.source = config.lib.file.mkOutOfStoreSymlink "${sourcePath}";
}) symlinksPaths;
in
{
imports = [
./minimal.nix
];
home.file = mkLinks;
xdg = {
enable = true;
autostart.enable = true;
userDirs = {
enable = true;
createDirectories = false;
desktop = null;
documents = null;
download = null;
music = null;
pictures = null;
publicShare = null;
templates = null;
videos = null;
};
home.file = xlib.helpers.mkSymlinks config {
"${config.home.homeDirectory}/External/Music" = "Music";
};
home.activation = {
yaziSync = ''
+283
View File
@@ -0,0 +1,283 @@
{
config,
lib,
pkgs,
xlib,
...
}:
# Shared "strict" home-manager module.
# Works in BOTH contexts:
# - NixOS hosts (via home-manager.sharedModules or homeConfigurations)
# - nix-on-droid (via home-manager.config in droid/epral.nix)
# Only home-manager options are used here — no systemd.*, no services.*,
# no users.*, no environment.systemPackages. All paths are parameterized
# through config.home.homeDirectory so /home/oqyude (NixOS) and
# /data/data/com.termux.nix/files/home (termux) both work.
#
# NOTE: intentionally duplicates parts of modules/essentials/{shell,packages}.nix
# (which stay NixOS-only for now). When this module is wired into NixOS hosts
# via sharedModules, deduplicate those files.
{
home = {
packages = with pkgs; [
# Lazy (alias lc)
lazycli
# IDE
fresh-editor # EDITOR
# Base utils
curl
wget
fd
tree
dust
gdu
mc
rsync
jq
unzip
zip
zstd
# Net diagnostic
mtr
dnsutils
# Monitoring
htop
];
sessionVariables = {
TUCKR_HOME = "$HOME/Storage/dotfiles";
EDITOR = "fresh";
};
file = {
".nanorc".text = ''
set nowrap
set tabstospaces
set tabsize 2
'';
# Authorized keys for sshd (see modules/termux/default.nix).
# Declarative for now — the Store/.ssh symlink scheme is postponed.
".ssh/authorized_keys".text = ''
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKduJia+unaQQdN6X5syaHvnpIutO+yZwvfiCP4qKQ/P
'';
};
};
programs = {
# ---- Shell: zsh ----
zsh = {
enable = true;
enableCompletion = true;
syntaxHighlighting.enable = true;
history.size = 10000;
oh-my-zsh = {
enable = true;
theme = "robbyrussell";
};
loginExtra = "clear && fastfetch && cd ~/.config/nix-on-droid";
# .zshenv — sourced by zsh in ALL sessions incl. non-login ssh commands.
# runit from nixpkgs defaults to /var/service as SVDIR, but our tree
# lives at ~/service (symlinked as /etc/service). Export it so that
# `sv status sshd` works without qualifying the path.
envExtra = "export SVDIR=/etc/service";
initContent = ''
beet-p() {
local base="${config.home.homeDirectory}/.config/beets/My"
local rel
rel=$(realpath --relative-to="$base" "$PWD")
beet mod "path:$rel" playlist="$*"
}
beet-ims() {
beet im ./ -S $*
}
beet-path() {
realpath --relative-to="${config.home.homeDirectory}/.config/beets/My" "$1"
}
'';
shellAliases = {
# shell
ff = "clear && fastfetch";
l = "ls -l";
lg = "lazygit";
lc = "lazycli";
gp = "git pull";
ns = "nix-on-droid switch --flake ~/.config/nix-on-droid#${xlib.device.hostname}";
gp-ns = "gp && ns";
gc = "git add . && git commit -m 'dev: автокоммит $(date +'%Y-%m-%d %H:%M:%S')'";
y = "yazi";
nix-shellp = "nix-shell --run $SHELL -p";
beet-path-library = "realpath --relative-to='${config.home.homeDirectory}/.config/beets/My' .";
z-proxy = "export ALL_PROXY=socks5://localhost:10808";
zh-proxy = "export HTTPS_PROXY=http://localhost:10808 && export HTTP_PROXY=http://localhost:10808";
nix-dir = "cd ~/.config/nix-on-droid";
q-ssh = "sv-start"; # start all supervised services (sshd, ...); manage with `sv status sshd` etc
# beets
beet-ima = "beet im ./ -A";
# ssh (hosts live in programs.ssh.settings below)
# NOTE: lamet / pubray-1 have no Host entry yet — kept as aliases.
z-l = "ssh lamet";
z-lt = "ssh lamet-tailscale";
z-p-1 = "ssh pubray-1";
z-map-local-proxy = "ssh -R 10808:localhost:10808";
# Extras
plasma-manager = "nix run github:nix-community/plasma-manager";
pip2nix = "nix run github:nix-community/pip2nix --"; # https://github.com/nix-community/pip2nix
pip2nix-g = "nix run github:nix-community/pip2nix -- generate -r";
json2nix = "nix run github:sempruijs/json2nix";
};
};
# ---- Editor ----
# NOTE: programs.nano is a NixOS-only module (does not exist in
# home-manager); write ~/.nanorc directly instead.
# ---- TUI tools ----
bat.enable = true;
lazygit.enable = true;
fzf.enable = true;
btop.enable = true;
broot.enable = true;
bottom.enable = true;
fastfetch.enable = true;
yazi = {
enable = true;
# explicit: shared module must behave identically on NixOS (26.05, "y")
# and nix-on-droid (24.05, legacy "yy")
shellWrapperName = "y";
plugins = {
inherit (pkgs.yaziPlugins)
gitui
git
sudo
ouch
rsync
diff
mount
chmod
dupes
lazygit
toggle-pane
rich-preview
smart-filter
full-border
recycle-bin
;
};
flavors = {
nord = pkgs.yaziPlugins.nord;
};
theme = {
flavor = {
light = "nord";
dark = "nord";
};
};
keymap = {
mgr.prepend_keymap = [
{
on = [
"M"
];
run = "plugin mount";
desc = "Mount manager";
}
{
on = [
"g"
"i"
];
run = "plugin lazygit";
desc = "run lazygit";
}
{
run = "plugin ouch --args=zip";
on = [
"g"
"C"
];
desc = "Compress with ouch";
}
];
};
settings = {
mgr.ratio = [
1
1
4
];
};
};
# ---- VCS ----
git = {
enable = true;
settings = {
user = {
name = "oqyude";
email = "oqyude@gmail.com";
};
pull = {
rebase = true;
};
};
};
# ---- SSH ----
# Declarative ~/.ssh/config, same as the one previously copied by hand.
# matchBlocks is deprecated in current home-manager; use `settings`
# (bare attr names become `Host` headers, keys are upstream directives).
ssh = {
enable = true;
# Reproduce the old enableDefaultConfig values explicitly.
enableDefaultConfig = false;
settings = {
"*" = {
ForwardAgent = false;
AddKeysToAgent = "no";
Compression = false;
ServerAliveInterval = 0;
ServerAliveCountMax = 3;
HashKnownHosts = false;
UserKnownHostsFile = "~/.ssh/known_hosts";
ControlMaster = "no";
ControlPath = "~/.ssh/master-%r@%n:%p";
ControlPersist = "no";
};
sapphira = {
HostName = "192.168.1.20";
User = "oqyude";
};
sapphira-tailscale = {
HostName = "100.64.0.0";
User = "oqyude";
};
otreca-old = {
HostName = "217.60.3.12";
User = "oqyude";
};
otreca = {
HostName = "109.248.161.5";
User = "oqyude";
};
otreca-tailscale = {
HostName = "100.64.1.0";
User = "oqyude";
};
rydiwo = {
HostName = "192.168.1.102";
User = "oqyude";
};
epral = {
HostName = "192.168.1.101";
User = "oqyude";
Port = 8022;
};
};
};
};
}
-27
View File
@@ -1,27 +0,0 @@
{
config,
pkgs,
xlib,
...
}:
{
imports = [
./minimal.nix
];
xdg = {
enable = true;
autostart.enable = true;
userDirs = {
enable = true;
createDirectories = false;
desktop = null;
documents = null;
download = null;
music = null;
pictures = null;
publicShare = null;
templates = null;
videos = null;
};
};
}
-19
View File
@@ -1,27 +1,8 @@
{
config,
pkgs,
xlib,
...
}:
{
imports = [
./minimal.nix
];
xdg = {
enable = true;
autostart.enable = true;
userDirs = {
enable = true;
createDirectories = false;
desktop = null;
documents = null;
download = null;
music = null;
pictures = null;
publicShare = null;
templates = null;
videos = null;
};
};
}
+4 -30
View File
@@ -5,41 +5,15 @@
xlib,
...
}:
let
symlinksPaths = {
"${config.home.homeDirectory}/External/Music" = "Music";
"${xlib.dirs.wsl-home}" = "External";
"${xlib.dirs.wsl-storage}/beets" = ".config/beets";
"${xlib.dirs.wsl-storage}/ssh/config" = ".ssh/config";
"${xlib.dirs.wsl-storage}/ssh/known_hosts" = ".ssh/known_hosts";
"${xlib.dirs.wsl-storage}/flow" = ".config/flow";
};
mkLinks = lib.mapAttrs' (sourcePath: targetPath: {
name = targetPath;
value.source = config.lib.file.mkOutOfStoreSymlink "${sourcePath}";
}) symlinksPaths;
in
{
imports = [
./apps
./minimal.nix
];
home.file = mkLinks;
xdg = {
enable = true;
autostart.enable = true;
userDirs = {
enable = true;
createDirectories = false;
desktop = null;
documents = null;
download = null;
music = null;
pictures = null;
publicShare = null;
templates = null;
videos = null;
};
home.file = xlib.helpers.mkSymlinks config {
"${config.home.homeDirectory}/External/Music" = "Music";
"${xlib.dirs.wsl-home}" = "External";
"${xlib.dirs.wsl-storage}" = "Storage";
};
home.activation = {
yaziSync = ''
+27
View File
@@ -0,0 +1,27 @@
{
inputs,
...
}:
{
deviceType,
hostname ? null,
modules ? [ ],
system ? "x86_64-linux",
}:
let
lib = inputs.nixpkgs.lib;
in
lib.nixosSystem {
inherit system;
modules = modules ++ [
{
xlib.device = {
type = deviceType;
}
// lib.optionalAttrs (hostname != null) { inherit hostname; };
}
];
specialArgs = {
inherit deviceType inputs;
};
}
+153
View File
@@ -0,0 +1,153 @@
{
lib,
...
}:
# Shared pure helper functions for module definitions.
# Injected into every module via `xlib.helpers` (see options.nix).
let
# tmpfiles rule: "type dir mode user group -"
mkTmpfile =
type: dir: mode: user: group:
"${type} ${dir} ${mode} ${user} ${group} -";
# several tmpfiles types for the same dir, e.g. ["d" "z"] or ["d" "Z"]
mkTmpDirs =
{
dir,
mode,
user,
group,
types ? [
"d"
"z"
],
}:
map (type: mkTmpfile type dir mode user group) types;
# fileSystems bind mount
mkBindMount =
{
what,
where,
}:
{
"${where}" = {
device = what;
fsType = "none";
options = [
"bind"
"nofail"
];
};
};
# systemd.mounts bind mount (automount variant)
mkSystemdBind =
{
what,
where,
}:
{
enable = true;
options = "bind,x-systemd.automount,nofail";
requires = [ "local-fs.target" ];
type = "none";
wantedBy = [ "multi-user.target" ];
inherit what where;
};
# Full "service storage" block: services-mnt source dir + /var/lib target,
# tmpfiles d/z + automount bind. Used as:
# storage = xlib.helpers.mkServiceStorage { name = "x"; user = "x"; group = "x"; };
# systemd = storage.systemd;
mkServiceStorage =
{
name,
user,
group,
mode ? "0755",
target ? "/var/lib/${name}",
base ? "/mnt/services",
}:
let
sourceDir = "${base}/${name}";
in
{
inherit sourceDir target;
systemd = {
tmpfiles.rules = mkTmpDirs {
dir = sourceDir;
inherit mode user group;
};
mounts = [
(mkSystemdBind {
what = sourceDir;
where = target;
})
];
};
};
# ntfs3 mount, e.g. fileSystems = mkNtfsMount { path = ...; uuid = ...; }
mkNtfsMount =
{
path,
uuid,
mask ? "0007",
enable ? null,
}:
{
"${path}" = {
device = "/dev/disk/by-uuid/${uuid}";
fsType = "ntfs3";
options = [
"defaults"
"uid=1000"
"gid=1000"
"fmask=${mask}"
"dmask=${mask}"
"nofail"
];
}
// lib.optionalAttrs (enable != null) { inherit enable; };
};
# exfat mount, e.g. fileSystems = mkExfatMount { path = ...; uuid = ...; }
mkExfatMount =
{
path,
uuid ? null,
label ? null,
}:
{
"${path}" = {
device = if uuid != null then "/dev/disk/by-uuid/${uuid}" else "/dev/disk/by-label/${label}";
fsType = "exfat";
options = [
"nofail"
"uid=1000"
"gid=1000"
];
};
};
# home-manager out-of-store symlinks: path = source (target name = attr name)
mkSymlinks =
config: paths:
lib.mapAttrs' (sourcePath: targetPath: {
name = targetPath;
value.source = config.lib.file.mkOutOfStoreSymlink "${sourcePath}";
}) paths;
in
{
inherit
mkTmpfile
mkTmpDirs
mkBindMount
mkSystemdBind
mkServiceStorage
mkNtfsMount
mkExfatMount
mkSymlinks
;
}
+136
View File
@@ -0,0 +1,136 @@
{
config,
lib,
pkgs,
xlib,
...
}:
let
panel = "${xlib.dirs.services-nodes-folder}/${xlib.device.hostname}/3x-ui";
certDomain = xlib.services."3x-ui".certDomain or null;
certMounts =
if certDomain == null then
[ ]
else
# LE cert mounted read-only so 3x-ui can terminate TLS itself.
# The 3x-ui settings table must point webCertFile / webKeyFile at
# /root/cert/fullchain.pem and /root/cert/key.pem.
map (f: "/var/lib/acme/${certDomain}/${f}:/root/cert/${f}:ro") [
"fullchain.pem"
"key.pem"
];
basePorts = [
# 2049/tcp — 3x-ui web panel
# 2096/tcp — subscription endpoint
# 14380-15379/tcp+udp — Xray inbounds (matches firewall open range)
"0.0.0.0:2049:2049/tcp"
"0.0.0.0:2096:2096/tcp"
"0.0.0.0:14380-15379:14380-15379/tcp"
"0.0.0.0:14380-15379:14380-15379/udp"
];
# VDS-only: nginx stream forwards host:443 → host:15380 → container:443,
# so Xray inside the container sees its REALITY inbound on its real
# configured port 443.
realityPorts = lib.optional xlib.services."3x-ui".reality443Forwarding "0.0.0.0:15380:443/tcp";
in
{
virtualisation = {
podman = {
enable = true;
autoPrune = {
enable = true;
flags = [ "--all" ];
};
dockerCompat = true;
};
oci-containers = {
backend = "podman";
containers."3xui_app" = {
image = "ghcr.io/mhsanaei/3x-ui:latest";
environment = {
"XRAY_VMESS_AEAD_FORCED" = "false";
"XUI_ENABLE_FAIL2BAN" = "true";
"TZ" = "Europe/Moscow";
};
volumes = [
"${panel}/cert/:/root/cert:rw"
"${panel}/db/:/etc/x-ui:rw"
]
++ certMounts;
log-driver = "journald";
# Adding a new inbound through the 3x-ui panel on a port outside
# the 14380-15379 range requires extending basePorts and rebuilding.
ports = basePorts ++ realityPorts;
};
};
};
systemd = {
services = {
"podman-3xui_app" = {
serviceConfig.Restart = lib.mkOverride 90 "always";
partOf = [ "podman-compose-3x-ui-root.target" ];
wantedBy = [ "podman-compose-3x-ui-root.target" ];
};
"podman-update-3xui_app" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
TimeoutSec = 300;
};
script = ''
podman pull ghcr.io/mhsanaei/3x-ui:latest
systemctl restart podman-3xui_app.service
'';
};
};
# Starts/stops together with all 3x-ui compose resources.
targets."podman-compose-3x-ui-root" = {
unitConfig.Description = "Root target generated by compose2nix.";
wantedBy = [ "multi-user.target" ];
};
# timers."podman-update-3xui_app" = {
# wantedBy = [ "timers.target" ];
# timerConfig = {
# OnCalendar = "weekly";
# Persistent = true;
# };
# };
tmpfiles.rules = [
(xlib.helpers.mkTmpfile "d" xlib.dirs.services-mnt-folder "0755" "root" "root")
(xlib.helpers.mkTmpfile "d" xlib.dirs.services-nodes-folder "0755" "root" "root")
(xlib.helpers.mkTmpfile "d" "${xlib.dirs.services-nodes-folder}/${xlib.device.hostname}" "0755"
"root"
"root"
)
(xlib.helpers.mkTmpfile "d" panel "0755" "root" "root")
(xlib.helpers.mkTmpfile "d" "${panel}/db" "0755" "root" "root")
(xlib.helpers.mkTmpfile "d" "${panel}/cert" "0755" "root" "root")
# Relabel panel dir for SELinux so containers can access it.
(xlib.helpers.mkTmpfile "Z" panel "0755" "root" "root")
];
};
# Enable container name DNS for all Podman networks.
networking.firewall = {
allowedUDPPortRanges = [
{
from = 14380;
to = 15380;
}
];
allowedTCPPortRanges = [
{
from = 14380;
to = 15380;
}
];
interfaces =
let
matchAll = if !config.networking.nftables.enable then "podman+" else "podman*";
in
{
"${matchAll}".allowedUDPPorts = [ 53 ];
};
};
}
+121
View File
@@ -0,0 +1,121 @@
{
pkgs,
lib,
config,
xlib,
...
}:
{
# Runtime
virtualisation.podman = {
enable = true;
autoPrune.enable = true;
dockerCompat = true;
dockerSocket.enable = true;
defaultNetwork.settings.dns_enabled = true;
};
# Enable container name DNS for all Podman networks.
networking.firewall.interfaces =
let
matchAll = if !config.networking.nftables.enable then "podman+" else "podman*";
in
{
"${matchAll}".allowedUDPPorts = [ 53 ];
};
virtualisation.oci-containers.backend = "podman";
# Containers
virtualisation.oci-containers.containers."openhands-app" = {
image = "ghcr.io/openhands/openhands:latest";
environment = {
"AGENT_SERVER_IMAGE_REPOSITORY" = "ghcr.io/openhands/agent-server";
"AGENT_SERVER_IMAGE_TAG" = "31536c8-python";
"WORKSPACE_MOUNT_PATH" = "${xlib.dirs.services-mnt-folder}/containers/openhands/workspace";
};
volumes = [
"${xlib.dirs.services-mnt-folder}/containers/openhands/userspace:/.openhands:rw"
"${xlib.dirs.services-mnt-folder}/containers/openhands/workspace:/opt/workspace_base:rw"
"/run/podman/podman.sock:/var/run/docker.sock:rw"
];
ports = [
"3000:3000/tcp"
];
log-driver = "journald";
extraOptions = [
# "--network=host"
"--add-host=host.docker.internal:host-gateway"
"--network-alias=openhands"
"--network=openhands_default"
];
};
systemd.services."podman-openhands-app" = {
serviceConfig = {
Restart = lib.mkOverride 90 "no";
};
after = [
"podman-network-openhands_default.service"
];
requires = [
"podman-network-openhands_default.service"
];
partOf = [
"podman-compose-openhands-root.target"
];
wantedBy = [
"podman-compose-openhands-root.target"
];
};
# Networks
systemd.services."podman-network-openhands_default" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStop = "podman network rm -f openhands_default";
};
script = ''
podman network inspect openhands_default || podman network create openhands_default
'';
partOf = [ "podman-compose-openhands-root.target" ];
wantedBy = [ "podman-compose-openhands-root.target" ];
};
# Builds
# systemd.services."podman-build-openhands-app" = {
# enable = false;
# path = [
# pkgs.podman
# pkgs.git
# ];
# serviceConfig = {
# Type = "oneshot";
# TimeoutSec = 300;
# };
# script = ''
# cd ${xlib.dirs.services-mnt-folder}/containers/openhands/source
# podman build -t openhands:latest -f ./containers/app/Dockerfile .
# '';
# };
# Root service
# When started, this will automatically create all resources and start
# the containers. When stopped, this will teardown all resources.
systemd.targets."podman-compose-openhands-root" = {
unitConfig = {
Description = "Root target generated by compose2nix.";
};
wantedBy = [ "multi-user.target" ];
};
systemd.tmpfiles.rules = [
"d ${xlib.dirs.services-mnt-folder} 0755 root root -"
"d ${xlib.dirs.services-mnt-folder}/containers 0755 root root -"
"d ${xlib.dirs.services-mnt-folder}/containers/openhands 0755 root root -"
"d ${xlib.dirs.services-mnt-folder}/containers/openhands/userspace 0755 root root -"
"d ${xlib.dirs.services-mnt-folder}/containers/openhands/workspace 0755 root root -"
];
}
+15
View File
@@ -0,0 +1,15 @@
{
config,
lib,
pkgs,
inputs,
xlib,
...
}:
{
systemd.tmpfiles.rules = [
"d ${xlib.dirs.services-mnt-folder} 0755 root root -"
"d ${xlib.dirs.services-mnt-folder}/containers 0755 root root -"
"d ${xlib.dirs.services-mnt-folder}/containers/remnanode 0755 root root -"
];
}
@@ -0,0 +1,115 @@
# Auto-generated by compose2nix.
{
pkgs,
lib,
config,
...
}:
{
# Runtime
virtualisation.podman = {
enable = true;
autoPrune.enable = true;
dockerCompat = true;
};
# Enable container name DNS for all Podman networks.
networking.firewall.interfaces =
let
matchAll = if !config.networking.nftables.enable then "podman+" else "podman*";
in
{
"${matchAll}".allowedUDPPorts = [ 53 ];
};
virtualisation.oci-containers.backend = "podman";
# Containers
virtualisation.oci-containers.containers."remnawave-panel-1" = {
image = "localhost/compose2nix/remnawave-panel-1";
environment = {
"API_INSTANCES" = "1";
"APP_PORT" = "3000";
"BANDWIDTH_USAGE_NOTIFICATIONS_ENABLED" = "false";
"BANDWIDTH_USAGE_NOTIFICATIONS_THRESHOLD" = "[60, 80]";
"CLOUDFLARE_TOKEN" = "ey...";
"DATABASE_URL" = "postgresql://remnawave:remnawave@remnawave-db:5432/postgres";
"FRONT_END_DOMAIN" = "*";
"IS_DOCS_ENABLED" = "false";
"IS_TELEGRAM_NOTIFICATIONS_ENABLED" = "false";
"JWT_API_TOKENS_SECRET" =
"787aa44c10130a9fa17ea3ea50c1248dd3e868f74941b96c09d608051399f88b95b67cd68d045aa39658b4b3fe933bf2b2c1437522498976f39f85ae1eab40da";
"JWT_AUTH_SECRET" =
"2bc14bacb6b82ce9e3ef69f8dd7bfb6b8a531f4f516902735d1d8f1bac8ff9b5077398f95b942b1adafc0ca1da4cdfd24a18539fa6eb26bee3f597a45deac94a";
"METRICS_PASS" = "admin";
"METRICS_PORT" = "3001";
"METRICS_USER" = "admin";
"NOT_CONNECTED_USERS_NOTIFICATIONS_AFTER_HOURS" = "[6, 24, 48]";
"NOT_CONNECTED_USERS_NOTIFICATIONS_ENABLED" = "false";
"PANEL_DOMAIN" = "rw.zeroq.ru";
"POSTGRES_DB" = "remnawave";
"POSTGRES_PASSWORD" = "gQLqOm2jK/Z1oBXCD18XSgr76M8ZqkVhHZbNKvZQXnY=";
"POSTGRES_USER" = "remnawave";
"REDIS_SOCKET" = "/var/run/valkey/valkey.sock";
"SCALAR_PATH" = "/scalar";
"SUB_PUBLIC_DOMAIN" = "rw.zeroq.ru/api/sub";
"SWAGGER_PATH" = "/docs";
# "TELEGRAM_BOT_TOKEN" = "change_me";
# "TELEGRAM_NOTIFY_CRM" = "change_me";
# "TELEGRAM_NOTIFY_NODES" = "change_me";
# "TELEGRAM_NOTIFY_SERVICE" = "change_me";
# "TELEGRAM_NOTIFY_TBLOCKER" = "change_me";
# "TELEGRAM_NOTIFY_USERS" = "change_me";
"WEBHOOK_ENABLED" = "false";
"WEBHOOK_SECRET_HEADER" = "vsmu67Kmg6R8FjIOF1WUY8LWBHie4scdEqrfsKmyf4IAf8dY3nFS0wwYHkhh6ZvQ";
"WEBHOOK_URL" = "https://your-webhook-url.com/endpoint";
};
ports = [
"3003:3003/tcp"
];
log-driver = "journald";
extraOptions = [
"--network-alias=remnawave-panel-1"
"--network=remnawavebackend_default"
];
};
systemd.services."podman-remnawave-panel-1" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
};
partOf = [
"podman-compose-remnawave-root.target"
];
wantedBy = [
"podman-compose-remnawave-root.target"
];
};
# Builds
systemd.services."podman-build-remnawave-panel-1" = {
path = [
pkgs.podman
pkgs.git
];
serviceConfig = {
Type = "oneshot";
TimeoutSec = 300;
};
script = ''
cd /mnt/s/Deploy/remnawave-backend
podman build -t compose2nix/remnawave-panel-1 .
'';
};
# Root service
# When started, this will automatically create all resources and start
# the containers. When stopped, this will teardown all resources.
systemd.targets."podman-compose-remnawave-root" = {
unitConfig = {
Description = "Root target generated by compose2nix.";
};
wantedBy = [ "multi-user.target" ];
};
}
@@ -0,0 +1,290 @@
# Auto-generated by compose2nix.
{
pkgs,
lib,
config,
...
}:
{
# Runtime
virtualisation.podman = {
enable = true;
autoPrune.enable = true;
dockerCompat = true;
};
# Enable container name DNS for all Podman networks.
networking.firewall.interfaces =
let
matchAll = if !config.networking.nftables.enable then "podman+" else "podman*";
in
{
"${matchAll}".allowedUDPPorts = [ 53 ];
};
virtualisation.oci-containers.backend = "podman";
# Containers
virtualisation.oci-containers.containers."remnawave" = {
image = "remnawave/backend:2";
environment = {
"API_INSTANCES" = "1";
"APP_PORT" = "3000";
"BANDWIDTH_USAGE_NOTIFICATIONS_ENABLED" = "false";
"BANDWIDTH_USAGE_NOTIFICATIONS_THRESHOLD" = "[60, 80]";
"CLOUDFLARE_TOKEN" = "ey...";
"DATABASE_URL" = "postgresql://remnawave:remnawave@remnawave-db:5432/postgres";
"FRONT_END_DOMAIN" = "*";
"IS_DOCS_ENABLED" = "false";
"IS_TELEGRAM_NOTIFICATIONS_ENABLED" = "false";
"JWT_API_TOKENS_SECRET" =
"787aa44c10130a9fa17ea3ea50c1248dd3e868f74941b96c09d608051399f88b95b67cd68d045aa39658b4b3fe933bf2b2c1437522498976f39f85ae1eab40da";
"JWT_AUTH_SECRET" =
"2bc14bacb6b82ce9e3ef69f8dd7bfb6b8a531f4f516902735d1d8f1bac8ff9b5077398f95b942b1adafc0ca1da4cdfd24a18539fa6eb26bee3f597a45deac94a";
"METRICS_PASS" = "admin";
"METRICS_PORT" = "3001";
"METRICS_USER" = "admin";
"NOT_CONNECTED_USERS_NOTIFICATIONS_AFTER_HOURS" = "[6, 24, 48]";
"NOT_CONNECTED_USERS_NOTIFICATIONS_ENABLED" = "false";
"PANEL_DOMAIN" = "rw.zeroq.ru";
"POSTGRES_DB" = "remnawave";
"POSTGRES_PASSWORD" = "gQLqOm2jK/Z1oBXCD18XSgr76M8ZqkVhHZbNKvZQXnY=";
"POSTGRES_USER" = "remnawave";
"REDIS_SOCKET" = "/var/run/valkey/valkey.sock";
"SCALAR_PATH" = "/scalar";
"SUB_PUBLIC_DOMAIN" = "rw.zeroq.ru/api/sub";
"SWAGGER_PATH" = "/docs";
"TELEGRAM_BOT_TOKEN" = "change_me";
"TELEGRAM_NOTIFY_CRM" = "change_me";
"TELEGRAM_NOTIFY_NODES" = "change_me";
"TELEGRAM_NOTIFY_SERVICE" = "change_me";
"TELEGRAM_NOTIFY_TBLOCKER" = "change_me";
"TELEGRAM_NOTIFY_USERS" = "change_me";
"WEBHOOK_ENABLED" = "false";
"WEBHOOK_SECRET_HEADER" = "vsmu67Kmg6R8FjIOF1WUY8LWBHie4scdEqrfsKmyf4IAf8dY3nFS0wwYHkhh6ZvQ";
"WEBHOOK_URL" = "https://your-webhook-url.com/endpoint";
};
volumes = [
"valkey-socket:/var/run/valkey:rw"
];
ports = [
"127.0.0.1:3000:3000/tcp"
"127.0.0.1:3001:3001/tcp"
];
dependsOn = [
"remnawave-db"
"remnawave-redis"
];
log-driver = "journald";
extraOptions = [
"--health-cmd=curl -f http://localhost:3001/health"
"--health-interval=30s"
"--health-retries=3"
"--health-start-period=30s"
"--health-timeout=5s"
"--hostname=remnawave"
"--network-alias=remnawave"
"--network=remnawave-network"
];
};
systemd.services."podman-remnawave" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
};
after = [
"podman-network-remnawave-network.service"
"podman-volume-valkey-socket.service"
];
requires = [
"podman-network-remnawave-network.service"
"podman-volume-valkey-socket.service"
];
partOf = [
"podman-compose-remnawave-root.target"
];
wantedBy = [
"podman-compose-remnawave-root.target"
];
};
virtualisation.oci-containers.containers."remnawave-db" = {
image = "postgres:17.6";
environment = {
"API_INSTANCES" = "1";
"APP_PORT" = "3000";
"BANDWIDTH_USAGE_NOTIFICATIONS_ENABLED" = "false";
"BANDWIDTH_USAGE_NOTIFICATIONS_THRESHOLD" = "[60, 80]";
"CLOUDFLARE_TOKEN" = "ey...";
"DATABASE_URL" = "postgresql://remnawave:remnawave@remnawave-db:5432/postgres";
"FRONT_END_DOMAIN" = "*";
"IS_DOCS_ENABLED" = "false";
"IS_TELEGRAM_NOTIFICATIONS_ENABLED" = "false";
"JWT_API_TOKENS_SECRET" =
"787aa44c10130a9fa17ea3ea50c1248dd3e868f74941b96c09d608051399f88b95b67cd68d045aa39658b4b3fe933bf2b2c1437522498976f39f85ae1eab40da";
"JWT_AUTH_SECRET" =
"2bc14bacb6b82ce9e3ef69f8dd7bfb6b8a531f4f516902735d1d8f1bac8ff9b5077398f95b942b1adafc0ca1da4cdfd24a18539fa6eb26bee3f597a45deac94a";
"METRICS_PASS" = "admin";
"METRICS_PORT" = "3001";
"METRICS_USER" = "admin";
"NOT_CONNECTED_USERS_NOTIFICATIONS_AFTER_HOURS" = "[6, 24, 48]";
"NOT_CONNECTED_USERS_NOTIFICATIONS_ENABLED" = "false";
"PANEL_DOMAIN" = "rw.zeroq.ru";
"POSTGRES_DB" = "";
"POSTGRES_PASSWORD" = "";
"POSTGRES_USER" = "";
"REDIS_SOCKET" = "/var/run/valkey/valkey.sock";
"SCALAR_PATH" = "/scalar";
"SUB_PUBLIC_DOMAIN" = "rw.zeroq.ru/api/sub";
"SWAGGER_PATH" = "/docs";
"TELEGRAM_BOT_TOKEN" = "change_me";
"TELEGRAM_NOTIFY_CRM" = "change_me";
"TELEGRAM_NOTIFY_NODES" = "change_me";
"TELEGRAM_NOTIFY_SERVICE" = "change_me";
"TELEGRAM_NOTIFY_TBLOCKER" = "change_me";
"TELEGRAM_NOTIFY_USERS" = "change_me";
"TZ" = "UTC";
"WEBHOOK_ENABLED" = "false";
"WEBHOOK_SECRET_HEADER" = "vsmu67Kmg6R8FjIOF1WUY8LWBHie4scdEqrfsKmyf4IAf8dY3nFS0wwYHkhh6ZvQ";
"WEBHOOK_URL" = "https://your-webhook-url.com/endpoint";
};
volumes = [
"remnawave-db-data:/var/lib/postgresql/data:rw"
];
ports = [
"127.0.0.1:6767:5432/tcp"
];
log-driver = "journald";
extraOptions = [
"--health-cmd=pg_isready -U \${POSTGRES_USER} -d \${POSTGRES_DB}"
"--health-interval=3s"
"--health-retries=3"
"--health-timeout=10s"
"--hostname=remnawave-db"
"--network-alias=remnawave-db"
"--network=remnawave-network"
];
};
systemd.services."podman-remnawave-db" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
};
after = [
"podman-network-remnawave-network.service"
"podman-volume-remnawave-db-data.service"
];
requires = [
"podman-network-remnawave-network.service"
"podman-volume-remnawave-db-data.service"
];
partOf = [
"podman-compose-remnawave-root.target"
];
wantedBy = [
"podman-compose-remnawave-root.target"
];
};
virtualisation.oci-containers.containers."remnawave-redis" = {
image = "valkey/valkey:9-alpine";
volumes = [
"valkey-socket:/var/run/valkey:rw"
];
cmd = [
"valkey-server"
"--save"
""
"--appendonly"
"no"
"--maxmemory-policy"
"noeviction"
"--loglevel"
"warning"
"--unixsocket"
"/var/run/valkey/valkey.sock"
"--unixsocketperm"
"777"
"--port"
"0"
];
log-driver = "journald";
extraOptions = [
"--health-cmd=[\"valkey-cli\", \"-s\", \"/var/run/valkey/valkey.sock\", \"ping\"]"
"--health-interval=3s"
"--health-retries=3"
"--health-timeout=3s"
"--hostname=remnawave-redis"
"--network-alias=remnawave-redis"
"--network=remnawave-network"
];
};
systemd.services."podman-remnawave-redis" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
};
after = [
"podman-network-remnawave-network.service"
"podman-volume-valkey-socket.service"
];
requires = [
"podman-network-remnawave-network.service"
"podman-volume-valkey-socket.service"
];
partOf = [
"podman-compose-remnawave-root.target"
];
wantedBy = [
"podman-compose-remnawave-root.target"
];
};
# Networks
systemd.services."podman-network-remnawave-network" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStop = "podman network rm -f remnawave-network";
};
script = ''
podman network inspect remnawave-network || podman network create remnawave-network --driver=bridge
'';
partOf = [ "podman-compose-remnawave-root.target" ];
wantedBy = [ "podman-compose-remnawave-root.target" ];
};
# Volumes
systemd.services."podman-volume-remnawave-db-data" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
podman volume inspect remnawave-db-data || podman volume create remnawave-db-data --driver=local
'';
partOf = [ "podman-compose-remnawave-root.target" ];
wantedBy = [ "podman-compose-remnawave-root.target" ];
};
systemd.services."podman-volume-valkey-socket" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
podman volume inspect valkey-socket || podman volume create valkey-socket --driver=local
'';
partOf = [ "podman-compose-remnawave-root.target" ];
wantedBy = [ "podman-compose-remnawave-root.target" ];
};
# Root service
# When started, this will automatically create all resources and start
# the containers. When stopped, this will teardown all resources.
systemd.targets."podman-compose-remnawave-root" = {
unitConfig = {
Description = "Root target generated by compose2nix.";
};
wantedBy = [ "multi-user.target" ];
};
}
+198
View File
@@ -0,0 +1,198 @@
{
config,
lib,
pkgs,
inputs,
xlib,
...
}:
{
# Runtime
virtualisation.podman = {
enable = true;
autoPrune.enable = true;
dockerCompat = true;
};
# Enable container name DNS for all Podman networks.
networking.firewall.interfaces =
let
matchAll = if !config.networking.nftables.enable then "podman+" else "podman*";
in
{
"${matchAll}".allowedUDPPorts = [ 53 ];
};
virtualisation.oci-containers.backend = "podman";
# Containers
virtualisation.oci-containers.containers."remnawave-panel-1" = {
image = "ghcr.io/remnawave/backend:latest";
environment = {
"API_INSTANCES" = "1";
"APP_PORT" = "3000";
"BANDWIDTH_USAGE_NOTIFICATIONS_ENABLED" = "false";
"BANDWIDTH_USAGE_NOTIFICATIONS_THRESHOLD" = "[60, 80]";
"FRONT_END_DOMAIN" = "*";
"IS_DOCS_ENABLED" = "false";
"IS_TELEGRAM_NOTIFICATIONS_ENABLED" = "false";
"METRICS_PASS" = "admin";
"METRICS_PORT" = "3001";
"METRICS_USER" = "admin";
"NOT_CONNECTED_USERS_NOTIFICATIONS_AFTER_HOURS" = "[6, 24, 48]";
"NOT_CONNECTED_USERS_NOTIFICATIONS_ENABLED" = "false";
"PANEL_DOMAIN" = "rw.zeroq.su";
"POSTGRES_DB" = "remnawave";
"POSTGRES_USER" = "remnawave";
"REDIS_SOCKET" = "/var/run/valkey/valkey.sock";
"SCALAR_PATH" = "/scalar";
"SUB_PUBLIC_DOMAIN" = "rw.zeroq.su/api/sub";
"SWAGGER_PATH" = "/docs";
# "TELEGRAM_BOT_TOKEN" = "change_me";
# "TELEGRAM_NOTIFY_CRM" = "change_me";
# "TELEGRAM_NOTIFY_NODES" = "change_me";
# "TELEGRAM_NOTIFY_SERVICE" = "change_me";
# "TELEGRAM_NOTIFY_TBLOCKER" = "change_me";
# "TELEGRAM_NOTIFY_USERS" = "change_me";
"WEBHOOK_ENABLED" = "false";
# "WEBHOOK_URL" = "https://your-webhook-url.com/endpoint";
};
environmentFiles = [
"/run/secrets/remnawave-env"
];
ports = [
"3003:3003/tcp"
];
log-driver = "journald";
extraOptions = [
"--network-alias=remnawave-panel-1"
"--network=host" # "--network=remnawavebackend_default"
];
};
systemd.services."podman-remnawave-panel-1" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
};
partOf = [
"podman-compose-remnawave-root.target"
];
wantedBy = [
"podman-compose-remnawave-root.target"
];
};
# Builds
# systemd.services."podman-build-remnawave-panel-1" = {
# path = [ pkgs.podman pkgs.git ];
# serviceConfig = {
# Type = "oneshot";
# TimeoutSec = 300;
# };
# script = ''
# cd /mnt/s/Deploy/remnawave-backend
# podman build -t compose2nix/remnawave-panel-1 .
# '';
# };
# Root service
# When started, this will automatically create all resources and start
# the containers. When stopped, this will teardown all resources.
systemd.targets."podman-compose-remnawave-root" = {
unitConfig = {
Description = "Root target generated by compose2nix.";
};
wantedBy = [ "multi-user.target" ];
};
services = {
postgresql = {
ensureDatabases = [ "remnawave" ];
ensureUsers = [
{
name = "remnawave";
ensureDBOwnership = true;
}
];
};
};
systemd.services = {
remnawave-env = {
description = "Generate remnawave env file";
requiredBy = [ "podman-remnawave-panel-1.service" ];
before = [ "podman-remnawave-panel-1.service" ];
serviceConfig = {
Type = "oneshot";
User = "root";
};
script = ''
cat > /run/secrets/remnawave-env <<EOF
DATABASE_URL=$(cat ${config.sops.secrets.DATABASE_URL.path})
DATABASE_PASSWORD=$(cat ${config.sops.secrets.DATABASE_PASSWORD.path})
JWT_AUTH_SECRET=$(cat ${config.sops.secrets.JWT_AUTH_SECRET.path})
JWT_API_TOKENS_SECRET=$(cat ${config.sops.secrets.JWT_API_TOKENS_SECRET.path})
WEBHOOK_SECRET_HEADER=$(cat ${config.sops.secrets.WEBHOOK_SECRET_HEADER.path})
EOF
chmod 600 /run/secrets/remnawave-env
'';
wantedBy = [ "multi-user.target" ];
};
remnawave-db-init = {
description = "Initialize Remnawave DB user";
after = [ "postgresql.service" ];
requires = [ "postgresql.service" ];
serviceConfig = {
Type = "oneshot";
User = "postgres";
};
script = ''
PASSWORD=$(cat ${config.sops.secrets.DATABASE_PASSWORD.path})
${pkgs.postgresql}/bin/psql -v ON_ERROR_STOP=1 <<EOF
DO \$\$
BEGIN
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname='remnawave') THEN
EXECUTE format('ALTER ROLE remnawave WITH PASSWORD %L', '$PASSWORD');
END IF;
END
\$\$ LANGUAGE plpgsql;
EOF
'';
wantedBy = [ "multi-user.target" ];
};
};
sops.secrets = {
DATABASE_PASSWORD = {
key = "DATABASE_PASSWORD";
sopsFile = ./secrets/remnawave.yaml;
owner = "postgres";
group = "postgres";
mode = "0400";
};
WEBHOOK_SECRET_HEADER = {
key = "WEBHOOK_SECRET_HEADER";
sopsFile = ./secrets/remnawave.yaml;
mode = "0400";
};
DATABASE_URL = {
key = "DATABASE_URL";
sopsFile = ./secrets/remnawave.yaml;
mode = "0400";
};
JWT_AUTH_SECRET = {
key = "JWT_AUTH_SECRET";
sopsFile = ./secrets/remnawave.yaml;
mode = "0400";
};
JWT_API_TOKENS_SECRET = {
key = "JWT_API_TOKENS_SECRET";
sopsFile = ./secrets/remnawave.yaml;
mode = "0400";
};
};
systemd.tmpfiles.rules = [
"d ${xlib.dirs.services-mnt-folder} 0755 root root -"
"d ${xlib.dirs.services-mnt-folder}/containers 0755 root root -"
"d ${xlib.dirs.services-mnt-folder}/containers/remnawave 0755 root root -"
];
}
+20
View File
@@ -0,0 +1,20 @@
DATABASE_PASSWORD: ENC[AES256_GCM,data:DRactR3j13q9zHFO0puGhBv09CX9YJc9KtFSLuOUVV/U7O/Nmh5Hb4ID0+A=,iv:5ErptccuQIVxfZKIcpfO5yVtcM0zE7kPn4v7kHctTP8=,tag:e3w8Rz+wGLTrxDSNftmkLw==,type:str]
WEBHOOK_SECRET_HEADER: ENC[AES256_GCM,data:ZJYKwG1a8JH0ODeRnrv395plPN7PA18+gi3R/ueGd/r8OrtbVGL8UnZ/6HgW9M+/jCGWNclD5mZfyRg3He6hDg==,iv:PIYCD2n5ED5T24JfG6xhrvStd6jySCoBHhA8hUFIEMk=,tag:WWpfI1q9l9R44FRNaqIiaA==,type:str]
DATABASE_URL: ENC[AES256_GCM,data:6plSDBUKyZVAO/djw3bPTthtS11yljwCGfQcIUqQetxROk5hwwVEGNMd1e6nGgS7eTtqJHW6uStkw58=,iv:RDjCVPDgPhMEbCriW0xjrxzcAolmyD55fbkD95LZMlE=,tag:ovH2D3eTXtHFmZba6u+IZg==,type:str]
JWT_AUTH_SECRET: ENC[AES256_GCM,data:rzsOoIwJwwzCd+QbelcWYjfe1Bt7Y1ihrEn9tsxNyZnfmVVIkpFC948ne3YhUZ0CXYEDJYen/SFQgyyWsPwTwZgcy11mIZnROh4vlOJvPWILB1IlVQF/JDDts3fvXfe9HQ7ujBwkw5uR/33Rm+yxeLHMWTsn644DZSyKFi53QqY=,iv:aB3meC8BeEsLmiF0UMjQ60xipjGTJ0Qg1XqRHNujPFE=,tag:s/YcehFUrArknqHlXo3MYw==,type:str]
JWT_API_TOKENS_SECRET: ENC[AES256_GCM,data:m6EtsdMNDRJk99LEYRgTk5rFNUYux4I2UWo/8AWy+2HJI8tRiOrBO284T3W/N+2/3fbty96sVB/SD8bjIIsxHij51sZTYi4+hdU7VxANGPdiMckKAXtvj3FMsVwrtW4MgRbH0j7taiDtnxVp6F3Cl7Sb0GamKFJjgAZnA3weN/8=,iv:rnNB1AzosstyF3c2pUcvYVTyUWcmo8Du+/b09OgcN9w=,tag:O81gnP2nXJ3JvgkivzVgkw==,type:str]
sops:
age:
- recipient: age13l2gtk0nzr484zprp7e0pkrt0ne0j4asyn2pjmlaw73nte7t7d8q4sqtxm
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3dWxEUDdhV2Z4V3JpNzNL
T0ZkYjlLWTNFV2c0Vm5Vb05xK09sQ0RxU0ZVCjhaSVhsSmoyZCtLYlNOVlNnTGFv
TTU1Y3I5U3UrcXhOOGt6U0hoSGw0YlUKLS0tIEJIbnJwNUk4Z0ZGNTRQRVFjWFhv
d0sreEpsMjV5M2JoRHFnVkpqeGhMM1EKX7K3Q2yj8EZuzCIxWIc+6Xeo+0lidPse
wstbeHV8ygWvOjIxjRGPOETQ17GLLl3eNEsk6P2gytZchmLkLYKKsA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-04-04T23:08:05Z"
mac: ENC[AES256_GCM,data:vWNFqNiWleqvRItVB0X5W/7e/F+LEWmfIKtnjbV5xwgyZ1jkP2N2wkw8CpzDNN5xwrkTdKfziGt+Psg8p72uMfvqns1lgQzvSbT3W8Di7bbIxgvwyBV8qCCpYn95ra/KRmV+oefhhr/1RlBN8wNb3oZI/m7sH8lv9d0sKw5SrE8=,iv:UAOifm4itrG6M3VKi7zelxL73lcpQkGXLSa/dk/hbvM=,tag:rzCK7Id3zQVF8VSDJV3nhg==,type:str]
unencrypted_suffix: _unencrypted
version: 3.12.2
@@ -0,0 +1,17 @@
TAPE_ROTATION_JWT_SECRET=ENC[AES256_GCM,data:xFtVR+6TalkDOlcsUB52QAP1eeZAUzHkCdUTC0eg9oLtXxCtOHNKDynpxWiPdqFCFWmFisOESmNEPgqXkfTThw==,iv:auPyYNpuzBV0YL/RG8DYDTim9N72J6cChWTIQMYgs/0=,tag:yN67SlnBPKzzIqet8IgBXw==,type:str]
TAPE_ROTATION_ADMIN_PASSWORD=ENC[AES256_GCM,data:JCOgdAyDP+7m7lOTXGoCSA==,iv:5WSnfpTyjDO+q59YsFWmgdvajzf5CxfPjpeSkYHMjgg=,tag:tvvm4HWUw71/HcDbIpHu5w==,type:str]
TAPE_ROTATION_APP_URL=ENC[AES256_GCM,data:GJ5klFIFwJm7/7ts+U6KUy5FYbwkXIipHWTMqT8I,iv:JheRMunpnDcCetLGCa91xYYaMYM92H9UYVtphAOP5IE=,tag:edwFhSXRCV9ZHTQaF2huyw==,type:str]
TAPE_ROTATION_CORS_ORIGINS=ENC[AES256_GCM,data:TRWO02hfNBHE4rS5s5qvA1L4gAjTP8yqHDmva2k5,iv:oSNVYZEYwheZQW4KPm8aGq73wr3Ol2E7PS0pU7ra7dM=,tag:J21t12mCWJ6Y2bv0ypCdqA==,type:str]
SMTP_HOST=
SMTP_PORT=ENC[AES256_GCM,data:LCQ=,iv:WLAbIdlHOj3rewluMXWVzilqvDSV/AJWSCX2r1aKs20=,tag:4Epi95JuDt+hpK5SrgZ/Eg==,type:str]
SMTP_USER=
SMTP_PASSWORD=
SMTP_FROM=ENC[AES256_GCM,data:ojS087+VQNecRLOgkiwDooR53SV3,iv:kGpy74EoXEDGnyo706MEJd2JY5FpJmN9Gy6+f7jOwBM=,tag:FaeLO08Prlk8cC84QFpWLw==,type:str]
NOTIFY_EMAIL=
TAPE_LABEL_REGEX=
sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsSUtSTnJtWHo3WXZWME4r\nNU51dk1rb3NmN3lFT1BMc3E1eVBOTDJUNlZrCkJBT2w2dkpXeEgvMWhWcGVNME8w\nSDZ1ekpUTmxJV0kyb2UrRC9XUTBiUFkKLS0tIGx2MCtxcG9lYjY0dmU4Wld4eEND\neFRRNUd3Rm9iYUg2dWh5elFEaW9wZUUKCvTvSHheiciexXbNXNAI9oioTHUSvreX\nIdOHyjfBfcjgfVIMrp5HQkQCC6labOHRcYgmT4WRkXJ11uTLvgLu1Q==\n-----END AGE ENCRYPTED FILE-----\n
sops_age__list_0__map_recipient=age13l2gtk0nzr484zprp7e0pkrt0ne0j4asyn2pjmlaw73nte7t7d8q4sqtxm
sops_lastmodified=2026-09-23T18:58:25Z
sops_mac=ENC[AES256_GCM,data:iLT3sVq0aV+UEztCdnbTBZraER3kXtksEOHl6AaiINTU6BHM0gTmpn5GdjbJykZDJweYdKVk6vYLB+k8JS33hWS9EoPUtme+FIGkbY6duMGpbVP/DZ5rqol1R+ihChfjmsXpnleVY6kWfnt67CH7LrP2HnsQj5njLF/3Qa4DMe8=,iv:yl8HB2E2Dm5LL1B7eLXXXTxJmEOp6HFvgIb3Ah+zVFg=,tag:iKTWq136tkMDgT4aFqGzmQ==,type:str]
sops_unencrypted_suffix=_unencrypted
sops_version=3.13.3
+177
View File
@@ -0,0 +1,177 @@
{
config,
lib,
pkgs,
xlib,
...
}:
# TapeRotation — web app for tracking and rotation of backup tape
# cartridges. https://github.com/ElizarovEugene/TapeRotation
#
# Podman adaptation of the upstream docker-compose deployment. Two
# containers on a shared "taperotation_default" network (mirrors the
# compose project network):
# - taperotation-backend: FastAPI/uvicorn on :8001, SQLite at /data,
# file attachments at /app/uploads
# - taperotation-frontend: nginx serving the built React app on :80,
# proxying /api to http://backend:8001
# The backend container gets the network alias "backend" so the
# frontend's baked-in nginx upstream (compose service name) resolves.
#
# Published host port 5174 → container:80 for the web UI. Keep it out
# of networking.firewall like the other panel ports and front it with an
# nginx vhost, e.g. in server/nginx.nix:
# { domain = "tape-rotation.zeroq.su"; port = 5174; }
# and set APP_URL / CORS_ORIGINS in the sops-encrypted env file.
#
# Instance config lives in one sops-encrypted .env file (mirrors the
# upstream .env.example, sops-nix format = "dotenv", key = "" → whole
# file): sops modules/containers/secrets/tape-rotation.env
# On first boot the admin account is created from ADMIN_USERNAME /
# ADMIN_PASSWORD from that file.
let
panel = "${xlib.dirs.services-nodes-folder}/${xlib.device.hostname}/tape-rotation";
in
{
virtualisation = {
podman = {
enable = true;
autoPrune = {
enable = true;
flags = [ "--all" ];
};
dockerCompat = true;
defaultNetwork.settings.dns_enabled = true;
};
oci-containers = {
backend = "podman";
containers = {
"taperotation-backend" = {
image = "elizaroveugene/taperotation-backend:latest";
environment = {
"DATABASE_URL" = "sqlite:////data/taperotation.db";
"JWT_EXPIRE_MINUTES" = "480";
"ADMIN_USERNAME" = "admin";
"ADMIN_LANGUAGE" = "en";
"NOTIFY_DAYS_BEFORE" = "7";
"TZ" = "Europe/Moscow";
};
environmentFiles = [ "/run/secrets/tape-rotation-env" ];
volumes = [
"${panel}/db:/data:rw"
"${panel}/uploads:/app/uploads:rw"
];
log-driver = "journald";
extraOptions = [
"--network=taperotation_default"
# frontend nginx proxies /api to http://backend:8001
"--network-alias=backend"
];
};
"taperotation-frontend" = {
image = "elizaroveugene/taperotation-frontend:latest";
ports = [
"0.0.0.0:5174:80/tcp"
];
log-driver = "journald";
extraOptions = [
"--network=taperotation_default"
];
};
};
};
};
# Enable container name DNS for all Podman networks.
networking.firewall.interfaces =
let
matchAll = if !config.networking.nftables.enable then "podman+" else "podman*";
in
{
"${matchAll}".allowedUDPPorts = [ 53 ];
};
systemd = {
services = {
"podman-taperotation-backend" = {
serviceConfig.Restart = lib.mkOverride 90 "always";
after = [ "podman-network-taperotation_default.service" ];
requires = [ "podman-network-taperotation_default.service" ];
partOf = [ "podman-compose-tape-rotation-root.target" ];
wantedBy = [ "podman-compose-tape-rotation-root.target" ];
};
"podman-taperotation-frontend" = {
serviceConfig.Restart = lib.mkOverride 90 "always";
after = [
"podman-network-taperotation_default.service"
"podman-taperotation-backend.service"
];
requires = [ "podman-network-taperotation_default.service" ];
partOf = [ "podman-compose-tape-rotation-root.target" ];
wantedBy = [ "podman-compose-tape-rotation-root.target" ];
};
"podman-network-taperotation_default" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStop = "podman network rm -f taperotation_default";
};
script = ''
podman network inspect taperotation_default || podman network create taperotation_default
'';
partOf = [ "podman-compose-tape-rotation-root.target" ];
wantedBy = [ "podman-compose-tape-rotation-root.target" ];
};
"podman-update-taperotation" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
TimeoutSec = 300;
};
script = ''
podman pull elizaroveugene/taperotation-backend:latest
podman pull elizaroveugene/taperotation-frontend:latest
systemctl restart podman-taperotation-backend.service podman-taperotation-frontend.service
'';
};
};
# Starts/stops together with all TapeRotation containers.
targets."podman-compose-tape-rotation-root" = {
unitConfig.Description = "Root target generated by compose2nix.";
wantedBy = [ "multi-user.target" ];
};
# Enable automatic image updates:
# systemd.timers."podman-update-taperotation" = {
# wantedBy = [ "timers.target" ];
# timerConfig = {
# OnCalendar = "weekly";
# Persistent = true;
# };
# };
tmpfiles.rules = [
(xlib.helpers.mkTmpfile "d" xlib.dirs.services-mnt-folder "0755" "root" "root")
(xlib.helpers.mkTmpfile "d" xlib.dirs.services-nodes-folder "0755" "root" "root")
(xlib.helpers.mkTmpfile "d" "${xlib.dirs.services-nodes-folder}/${xlib.device.hostname}"
"0755"
"root"
"root"
)
(xlib.helpers.mkTmpfile "d" panel "0755" "root" "root")
(xlib.helpers.mkTmpfile "d" "${panel}/db" "0755" "root" "root")
(xlib.helpers.mkTmpfile "d" "${panel}/uploads" "0755" "root" "root")
# Relabel panel dir for SELinux so containers can access it.
(xlib.helpers.mkTmpfile "Z" panel "0755" "root" "root")
];
};
sops.secrets."tape-rotation-env" = {
# key = "" → decrypt the whole file, not a single key.
# format = "dotenv" → the file IS one .env ready for environmentFiles:
# every non-comment KEY=VALUE line lands in the container environment.
key = "";
format = "dotenv";
sopsFile = ./secrets/tape-rotation.env;
mode = "0400";
};
}
+43 -31
View File
@@ -1,62 +1,74 @@
{ inputs, ... }@flakeContext:
let
# NixOS-only modules. termux runs nix-on-droid (its own module system,
# class = "nixOnDroid"): options like services.*, users.*, sops.*, disko.*
# and nixpkgs.overlays (flake assertion) do not exist there.
moduleArgs = config: {
inherit inputs;
xlib = config.xlib;
};
defaultModule =
{
config,
deviceType,
lib,
xlib,
deviceType,
...
}:
let
isDesktop = builtins.elem deviceType [
"primary"
"secondary"
];
in
{
imports = with inputs; [
./essentials
./users.nix
./options.nix
(./. + "/${deviceType}") # specific modules
imports =
with inputs;
[
./essentials
./options.nix
./users.nix
home-manager.nixosModules.home-manager # home-manager module
# nix-index-database.nixosModules.nix-index # nix-index module
grub2-themes.nixosModules.default # grub2 themes module
sops-nix.nixosModules.sops # sops module
self.homeConfigurations.default.nixosModule # default homeConfigurations
disko.nixosModules.disko # disko module
noctalia.nixosModules.default
home-manager.nixosModules.home-manager # home-manager module
# nix-index-database.nixosModules.nix-index # nix-index module
grub2-themes.nixosModules.default # grub2 themes module
sops-nix.nixosModules.sops # sops module
justray.nixosModules.default
self.homeConfigurations.default.nixosModule # default homeConfigurations
disko.nixosModules.disko # disko module
]
++ lib.optional isDesktop ./desktop # desktop class: primary/secondary
# device-type module dir; "minimal" has no extra modules
++ lib.optional (!isDesktop && deviceType != "minimal") (./. + "/${deviceType}");
nixpkgs.overlays = with inputs; [
self.nixosOverlays.default
];
nixpkgs.overlays = [
inputs.self.nixosOverlays.default
];
_module.args = {
inputs = inputs;
xlib = config.xlib;
};
networking.hostName = lib.mkDefault config.xlib.device.hostname;
_module.args = moduleArgs config;
};
publicModule =
strictModule =
{
config,
deviceType,
lib,
xlib,
...
}:
{
imports = with inputs; [
./essentials
./users.nix
# ./essentials
# ./users.nix
./options.nix
disko.nixosModules.disko # disko module
sops-nix.nixosModules.sops # sops module
(./. + "/${deviceType}")
# sops-nix.nixosModules.sops
];
_module.args = {
inputs = inputs;
xlib = config.xlib;
};
_module.args = moduleArgs config;
};
in
{
nixosModules = {
default = defaultModule;
public = publicModule;
strict = strictModule;
};
}
+58 -19
View File
@@ -1,7 +1,9 @@
{
config,
inputs,
lib,
pkgs,
xlib,
...
}:
{
@@ -10,6 +12,54 @@
./theming.nix
];
# Things every desktop host has in common
hardware.bluetooth.enable = true;
i18n.extraLocaleSettings = {
LC_ADDRESS = "ru_RU.UTF-8";
LC_IDENTIFICATION = "ru_RU.UTF-8";
LC_MEASUREMENT = "ru_RU.UTF-8";
LC_MONETARY = "ru_RU.UTF-8";
LC_NAME = "ru_RU.UTF-8";
LC_NUMERIC = "ru_RU.UTF-8";
LC_PAPER = "ru_RU.UTF-8";
LC_TELEPHONE = "ru_RU.UTF-8";
LC_TIME = "ru_RU.UTF-8";
};
networking = {
networkmanager.enable = true;
firewall.enable = false;
};
security.rtkit.enable = true;
services = {
syncthing = {
enable = true;
systemService = true;
configDir = "${xlib.dirs.user-storage}/persist/Syncthing/${config.system.name}";
dataDir = "${xlib.dirs.user-home}";
group = "users";
user = "${xlib.device.username}";
};
thermald.enable = true;
xserver = {
enable = true;
xkb = {
layout = "us,ru";
variant = "";
# options = "grp:alt_shift_toggle";
};
};
libinput.enable = true;
colord.enable = true;
printing = {
enable = true;
cups-pdf.enable = true;
};
};
boot = {
plymouth = {
enable = true;
@@ -49,26 +99,15 @@
programs = {
dconf.enable = true;
gamemode.enable = true;
# steam.enable = true;
steam.enable = true;
xwayland.enable = true;
};
services = {
xserver = {
enable = true;
xkb = {
layout = "us,ru";
variant = "";
options = "grp:alt_shift_toggle";
};
};
libinput.enable = true;
colord.enable = true;
printing = {
enable = true;
cups-pdf.enable = true;
};
};
# environment.sessionVariables = {
# NIXOS_OZONE_WL = "1";
# environment = {
# systemPackages = [
# pkgs.pcbu-desktop
# ];
# # sessionVariables = {
# # NIXOS_OZONE_WL = "1";
# # };
# };
}
-1
View File
@@ -6,6 +6,5 @@
./kde.nix
# ./gnome.nix
# ./noctalia.nix
# ./xfce.nix
];
}
-36
View File
@@ -1,36 +0,0 @@
{
config,
lib,
pkgs,
...
}:
{
services.xserver.displayManager.lightdm.enable = true;
#services.displayManager.defaultSession = "lomiri";
# services.xserver.desktopManager.budgie.enable = true;
#services.xserver.displayManager.lightdm.greeters.lomiri.enable= true;
#services.desktopManager.lomiri.enable = true;
#-services.xserver.desktopManager.mate.enable = true;
#-services.xserver.desktopManager.lxqt.enable = true;
# services.xserver.desktopManager.lumina.enable = true;
# services.xserver.desktopManager.cde.enable = true;
# services.xserver.desktopManager.cinnamon.enable = true;
# services.xserver.desktopManager.enlightenment.enable = true;
# services.desktopManager.cosmic.xwayland.enable = true;
# services.desktopManager.cosmic.enable = true;
services.xserver = {
enable = true;
desktopManager = {
#xterm.enable = false;
xfce.enable = true;
xfce.enableWaylandSession = true;
};
};
#- services.xserver.desktopManager.pantheon.enable = true;
#- services.pantheon.apps.enable = true;
}
+2 -1
View File
@@ -7,7 +7,8 @@
./packages.nix
./services.nix
./settings.nix
# ./systemd-routine.nix
./ssh.nix
./systemd-routines.nix
./shell.nix
];
}
+29 -19
View File
@@ -4,11 +4,6 @@
inputs,
...
}:
let
master = import inputs.nixpkgs-master {
system = "x86_64-linux";
};
in
{
environment = {
systemPackages = with pkgs; [
@@ -16,7 +11,7 @@ in
btop
broot
bottom
fastfetchMinimal
fastfetch
# Encrypt
age
@@ -38,6 +33,12 @@ in
lazyjournal
systemctl-tui
# IDE
yaml-language-server
nil
fresh-editor
#flow-control
# Base
curl
# efibootmgr
@@ -53,7 +54,7 @@ in
wget
tree
dust
flow-control
tuckr
# Net Diagnostic
mtr
@@ -72,7 +73,7 @@ in
exfatprogs # for gparted exfat support
# Archivers
rar
# rar
unzip
zstd
zip
@@ -86,25 +87,32 @@ in
# To save
tuios
fresh-editor
# Test
jocalsend
lazydocker
dtop
bluetui
speedtest-cli
# jocalsend
tlrc
lazyssh
mcat
framework-tool-tui
bluetui
snitch
devenv
whosthere
devenv
# Test
rgx
net-tools
usbtree
iperf3
# lazydocker
# dtop
# framework-tool-tui
];
};
environment.variables.EDITOR = "fresh";
programs = {
# nix-ld.enable = true;
justray = {
enable = true;
};
nano = {
enable = true;
nanorc = ''
@@ -118,7 +126,6 @@ in
enable = false;
plugins = {
inherit (pkgs.yaziPlugins)
gitui
git
sudo
ouch
@@ -181,6 +188,9 @@ in
name = "oqyude";
email = "oqyude@gmail.com";
};
pull = {
rebase = true;
};
};
};
lazygit.enable = true;
@@ -192,7 +202,7 @@ in
flake = "/etc/nixos";
clean = {
enable = true;
extraArgs = "--keep 3 --keep-since 2d";
extraArgs = "--keep 2 --keep-since 2d";
dates = "daily";
};
};
+17
View File
@@ -0,0 +1,17 @@
root-ca: ENC[AES256_GCM,data:5WxHCyp8sWl+XMpmMFQGfs+IhZx0r61JVFp7TJsn4pnCwV2KY/eyh6pEF+GF+P7eXALPEWGzdFYTzMJd6KJ+D+Ew0bLomIZ+KVhlxhgVzKG0xThrLpxSuyrrRFFfXzMz7C28v1HlBht6xtwKouPnxQcXDYTLyV52w7FrhWTXPuJ+TvaYDlHJcs3wHY5U+UiCoQZMcM8ddNkgbMqCu+/QC4G213EoJvjhQz+woXzIuqN8SYsOVmQ5su9Xy1sDMc8vIF+vl1Ax1E+T7ZqnE4E/7Y7HNzBQFpBGZjTb3JLUoyO4ALo0S36Yls12MWj/AZBmoBG8yL4wwA48FBHzGyH1aYtbWA/twJLDYzmu9saORW/TKIMrzeruxdufWU9sRs1f2BxpefAa2kZ8QTxhx2+3kUiOC1lipIjdMu9RSeq7q4HmKRTmuuXW087ere+IMhogh11RoshttB1W0/BU/dz6sYwAnCioSoOCd3n+WBGfuMNyeDjkpNJ4veg2HuU/K84rLFjNsxWnRfQML0BjUDHzFypA4dNIDo/FI0Z1cOrPojiqjwKt5Fb0XljTwfDQvkRtcZOQLVln7HfJlsU67YUCBMgJUJUTC3XKo82smZbz8JV1z8I9hVfnSfoEMiqNvDu3wKPGDpjWq0hAKD2R82keKe3Ji33Z2O4HK0e0Q7vSPP/Z5gIAay2S2aS2YLpqlvgzipqiLo2owzM2Mr4NrKRL9Vg36na7bLBPEoz+l9EK8EEiZaq+c8H2+dpmXpdmnUMQDF5yBxs4EU2M6Ga+X+2SYd1q9aZBT0yxykFkQrMUcA==,iv:Ee4tvSVLdk0Clh8vohbajEaKXJlQJjqOIu2lxfWueAI=,tag:oy99+HrMV1uGCdcAy7epug==,type:str]
intermediate-ca: ENC[AES256_GCM,data:NUMdfNy+Opi/UypY1N2N8pZZK99m3VouzLxA7EKwC2sd2Q24uEflRfucjWupAASp7duncfSjmC1jQxCQpSzwV7Qbq3+PkKD+MnrceVzz40G97C5jEKEJG6ln5RdwGX5FeIF9tZpb/gBvkWcyrPQ6wDEpzd9rCDGJgvPzg/PaFuluO6UXKpppyC9Zzl2x/dms+2pV2aQcR0rEPEuXKK7NKxc+Zk3HFgcfhe26mbayZXZxdxs44vwPqPKr6xmWRiERBlCoMEfjLSWAiVjau/RXsW+/5Mtu80rbiRUHUesdZYIX4hqfoj914Mp1gsQ+bihnfBQ3xYyxtskBfHO8+oZNvOcDhx7zl8Vo+giD4435EYEFWNxjzRtbXoR0CHu50obmDDjpPcUpkRNzjpJK3VEJM45SEA2EZyupmf+Y8o4uHmOg/xTciVHLFqVOnchb6pm9WPbkyMT9K/+O9XvN3yVJzab6se6DdnEB/8PeA4s51M0ONk6PrFXSGdfwos84BmD8uaAqGhp64sXpTuunhfcmo02b1pZ2OqlGnjam5ZJOuyJ6vPeVYB/o60Dl/w5QtdeWc93EgsxNRAOyxOsrtSKdQPuZgp7+/I4S6kYaRJS8S7mvqSNdtCdrov1vYSEoHDXtu2XaDaJrStHJsP1FmTAAmXhzeyfGosB9JX7sdOGRkskesREqkzJ5V7+O0k3cpHFJvIZIFyj12rwpPSnrB66BELAQVxkqeol2dfPWn+G1aG9dmtq3T7+C3M5wW7VE41mmVgUrx9o4/8Z3wkHkBxZXiUkN4LfFHcZXmvuHFqRYYBOUpTzxRCkW6dl/gvP0qedMR3/zplhe51Gux7IFW7/s0wvTWHqWrpxirpW+c4l/IGf53Ox7kt3D,iv:atbEM7iZALuT1UipYmxlH0k0FOPJ7VKrfPrmCs3X9Mo=,tag:w6l49PKgjlzTZa1mIVpI4A==,type:str]
sops:
age:
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSamN6dkxYalBZc25EYThR
NnV0YW5oQWgrQWNhSE9Gemt3VGljaE0rTGcwCnYyV2JpdW1GbEZTRElDNFk2Y213
bk1FY1grM2tuc0UzV21ROG5BanpjbFEKLS0tIG83dnpNQzEvYVZ1ODArRjlYSFRY
WHp0NktOQVF0UW1KajhYM3U5WkZCNmsKrN8T73fg7JoT+7WheveOC3Jlxa79EFjs
ePfVY07TKEHsycFhNyjcsFCWMF2ddE7q28A+Sjg+C3SA+/cHO8U9lw==
-----END AGE ENCRYPTED FILE-----
recipient: age13l2gtk0nzr484zprp7e0pkrt0ne0j4asyn2pjmlaw73nte7t7d8q4sqtxm
lastmodified: "2026-06-23T20:42:27Z"
mac: ENC[AES256_GCM,data:XftvodNnD0YXmd1GsNt2w820CWYY3v2pXOtlFYE0k25kuKNeKqqGDgN4geTA/xh6eYMrDut6mryNHOOoWXTuU9r/NvpXotwT5/vW2s4Nq+Cd9XySceJn/Ja6aN8R5ICbq3BhmpmC3SCVXDTce4+MwIHeBmp+Lrff+mXvZ5cT1A4=,iv:FqI/KdPJFHOMHykeZj0oEcuIZsCBWF1WCK4saz9Es7g=,tag:IZ1xHkB4eqkp04L2iAbkOw==,type:str]
unencrypted_suffix: _unencrypted
version: 3.13.1
+8 -3
View File
@@ -1,12 +1,17 @@
{
config,
lib,
pkgs,
xlib,
...
}:
{
services.tailscale.enable = xlib.device.type != "wsl"; # true, if not wsl
# All real hosts (not the bare "minimal" test config) get OOM protection
# and a bounded journal.
services = {
tailscale.enable = xlib.device.type != "wsl"; # true, if not wsl
earlyoom.enable = lib.mkIf (xlib.device.type != "minimal") true;
journald.settings.Journal = lib.mkIf (xlib.device.type != "minimal") {
SystemMaxUse = "512M";
};
};
}
+63 -14
View File
@@ -1,6 +1,7 @@
{
config,
lib,
pkgs,
...
}:
{
@@ -8,33 +9,34 @@
system.nixos.label = "default";
nix = {
channel = {
enable = true;
};
# nixPath = [ "nixpkgs=flake:nixpkgs" ];
# package = pkgs.lixPackageSets.stable.lix; # maybe unstable
channel.enable = false;
nixPath = [ "nixpkgs=flake:nixpkgs" ];
settings = {
require-sigs = false;
substituters = [
"https://nix-cache.zeroq.su"
"https://cache.nixos.org"
"https://nix-community.cachix.org"
"https://mirror.yandex.ru/nixos"
"https://cache.nixos.kz"
"https://cache.xd0.zip"
# "https://cache.xd0.zip"
"https://nixos-cache-proxy.cofob.dev"
# "https://nixos-cache-proxy.sweetdogs.ru"
# "https://nixos-cache-proxy.elxreno.com"
# "https://nixos.snix.store" # https://nixos.snix.store/
];
trusted-public-keys = [
"nix-cache.zeroq.su:be5jFLkiwNyOep/McxSafB3jguBmztxx+oJ46ySyc/s="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
stalled-download-timeout = 4;
connect-timeout = 4;
stalled-download-timeout = 8;
connect-timeout = 8;
auto-optimise-store = true;
fallback = true;
# allow-import-from-derivation = false;
# keep-derivations = true;
# keep-outputs = true;
allow-import-from-derivation = true;
keep-derivations = false;
keep-outputs = false;
experimental-features = [
"flakes"
"nix-command"
@@ -43,10 +45,10 @@
};
nixpkgs = {
# flake = {
# setFlakeRegistry = false;
# setNixPath = false;
# };
flake = {
setFlakeRegistry = false;
setNixPath = false;
};
config.allowUnfree = true;
};
@@ -62,6 +64,34 @@
});
'';
};
pki.certificates = [
''
-----BEGIN CERTIFICATE-----
MIIBlDCCATmgAwIBAgIQUR+DM/LKIbokKxYPGZbCCjAKBggqhkjOPQQDAjAoMQ4w
DAYDVQQKEwVaZXJvUTEWMBQGA1UEAxMNWmVyb1EgUm9vdCBDQTAeFw0yNjA2MTMy
MjU2MDZaFw0zNjA2MTAyMjU2MDZaMCgxDjAMBgNVBAoTBVplcm9RMRYwFAYDVQQD
Ew1aZXJvUSBSb290IENBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgbhGtnlm
qd2Uv1B1VBSeg6NlXFMj4BG/k5gVu9bVFBK4cw9HVx21aHw9HhFW94P2KaySR6bu
K8tLDtzvs0xkyqNFMEMwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8C
AQEwHQYDVR0OBBYEFH07/1blaqp0MVuSZIUHS9W3SjIrMAoGCCqGSM49BAMCA0kA
MEYCIQD1coTa7hqU1PAdnamAIgq1ApadDWpWfNaXPGiLCrkxTwIhAJhj/YSzqTJR
HvurdJ9m2glxV3rQHIUiVqKbQRcibObd
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIBvjCCAWOgAwIBAgIRAMiJigRk8xbvHhCWN6a7D68wCgYIKoZIzj0EAwIwKDEO
MAwGA1UEChMFWmVyb1ExFjAUBgNVBAMTDVplcm9RIFJvb3QgQ0EwHhcNMjYwNjEz
MjI1NjA3WhcNMzYwNjEwMjI1NjA3WjAwMQ4wDAYDVQQKEwVaZXJvUTEeMBwGA1UE
AxMVWmVyb1EgSW50ZXJtZWRpYXRlIENBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD
QgAE2gUlKZ/z9kt5RrdYZHnGE1TVVegn+aDmGpZk5uvF04O9k/sfjD6QE7VtjwNH
ervZKu3iBXGRg92ba0k369VJpKNmMGQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB
/wQIMAYBAf8CAQAwHQYDVR0OBBYEFCtYg4LEAHPIMrDPO7lrxKuFvw4PMB8GA1Ud
IwQYMBaAFH07/1blaqp0MVuSZIUHS9W3SjIrMAoGCCqGSM49BAMCA0kAMEYCIQD2
nNNHqs9/mIstOxetObgg8eqbrPWHXEVQ9CDucNFmQAIhANXAz2z1Rc7hxc6er23W
I8TU6UQc8dledPvalDJLyGym
-----END CERTIFICATE-----
''
];
};
systemd.network.wait-online.enable = false;
@@ -73,4 +103,23 @@
"ru_RU.UTF-8/UTF-8"
];
};
# sops.secrets = {
# intermediate-ca = {
# format = "yaml";
# key = "intermediate-ca";
# sopsFile = ./secrets/settings.yaml;
# # owner = "nobody";
# # group = "nogroup";
# mode = "0700";
# };
# root-ca = {
# format = "yaml";
# key = "root-ca";
# sopsFile = ./secrets/settings.yaml;
# # owner = "nobody";
# # group = "nogroup";
# mode = "0700";
# };
# };
}
+13 -4
View File
@@ -19,15 +19,18 @@
theme = "robbyrussell";
};
shellInit = ''
beet-n() {
echo "$*" | aichat -cer beets
}
beet-p() {
beet mod path:. playlist="$*"
local base="/home/oqyude/.config/beets/My"
local rel
rel=$(realpath --relative-to="$base" "$PWD")
beet mod "path:$rel" playlist="$*"
}
beet-ims() {
beet im ./ -S $*
}
beet-path() {
realpath --relative-to="/home/oqyude/.config/beets/My" "$1"
}
'';
shellAliases = {
# shell
@@ -39,9 +42,12 @@
gp = "git pull";
ns = "nh os switch";
gp-ns = "gp && ns";
gc = "git add . && git commit -m 'dev: автокоммит $(date +'%Y-%m-%d %H:%M:%S')'";
y = "yazi";
nix-shellp = "nix-shell --run $SHELL -p";
beet-path-library = "realpath --relative-to='/home/oqyude/.config/beets/My' .";
z-proxy = "export ALL_PROXY=socks5://localhost:10808";
zh-proxy = "export HTTPS_PROXY=http://localhost:10808 && export HTTP_PROXY=http://localhost:10808";
# beets
beet-ima = "beet im ./ -A";
@@ -66,4 +72,7 @@
json2nix = "nix run github:sempruijs/json2nix";
};
};
environment.sessionVariables = {
TUCKR_HOME = "$HOME/Storage/dotfiles";
};
}
+23
View File
@@ -0,0 +1,23 @@
{
config,
lib,
...
}:
lib.mkIf config.xlib.ssh.enable {
services.openssh = {
enable = true;
allowSFTP = true;
openFirewall = lib.mkDefault false;
hostKeys = [
{
path = "/etc/ssh/id_ed25519";
type = "ed25519";
}
];
settings = {
PasswordAuthentication = false;
PermitRootLogin = "yes";
UsePAM = true;
};
};
}
-26
View File
@@ -1,26 +0,0 @@
{
config,
xlib,
...
}:
{
systemd = {
services.nixos-auto-rebuild = {
description = "Auto rebuild NixOS config";
serviceConfig = {
Type = "oneshot";
User = "${xlib.device.username}";
WorkingDirectory = "/etc/nixos";
ExecStart = "gp-ns";
};
};
timers.nixos-auto-rebuild = {
description = "Run NixOS auto rebuild at 4am daily";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "*-*-* 04:00:00";
Persistent = true;
};
};
};
}
+39
View File
@@ -0,0 +1,39 @@
{
config,
pkgs,
xlib,
...
}:
{
systemd = {
services = {
nixos-prebuild = {
description = "Prebuild NixOS closure";
serviceConfig = {
CPUQuota = "20%";
User = "oqyude";
Group = "users";
Nice = 10;
Type = "oneshot";
WorkingDirectory = "/tmp";
Environment = [
"HOME=/home/oqyude"
];
ExecStart = ''
${pkgs.nix}/bin/nix build --no-link /etc/nixos#nixosConfigurations.${config.networking.hostName}.config.system.build.toplevel
'';
};
wantedBy = [ "multi-user.target" ];
};
};
timers = {
nixos-prebuild = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "*-*-* 04:00:00";
Persistent = true;
};
};
};
};
}
-31
View File
@@ -1,31 +0,0 @@
{ inputs, ... }@flakeContext:
{
config,
pkgs,
...
}:
{
systemd.services.zapret = {
enable = true;
description = "zapret complete";
unitConfig = {
After = [ "network-online.target" ];
Wants = [ "network-online.target" ];
};
wantedBy = [ "multi-user.target" ];
path = [ "/run/current-system/sw" ];
serviceConfig = {
Type = "simple";
Restart = "on-failure";
User = "root";
WorkingDirectory = "${inputs.zapret.script-dir}";
ExecStart = "/run/current-system/sw/bin/bash ./main_script.sh -nointeractive";
ExecStop = "/run/current-system/sw/bin/bash ./stop_and_clean_nft.sh";
};
};
environment = {
systemPackages = with pkgs; [
nftables
];
};
}
-9
View File
@@ -1,9 +0,0 @@
{
lib,
pkgs,
...
}:
{
# imports = [
# ];
}
+70 -89
View File
@@ -3,6 +3,17 @@
lib,
...
}:
let
# Option factory for the xlib.dirs namespace
mkDir =
default: description:
lib.mkOption {
type = lib.types.str;
inherit default description;
};
helpers = import ../lib/xlib.nix { inherit lib; };
in
{
options = {
xlib = {
@@ -14,8 +25,8 @@
"secondary"
"server"
"vds"
"vds-new"
"wsl"
"termux"
];
default = "minimal";
description = "Type of device for this host.";
@@ -31,96 +42,66 @@
description = "Hostname...";
};
};
ssh = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable SSH server with the standard config.";
};
};
dirs = {
user-home = lib.mkOption {
type = lib.types.str;
default = "/home/${config.xlib.device.username}";
description = "User home directory.";
user-home = mkDir "/home/${config.xlib.device.username}" "User home directory.";
user-storage = mkDir "${config.xlib.dirs.user-home}/Storage" "User storage directory.";
archive-drive = mkDir "/mnt/archive" "Archive drive mount point.";
lamet-drive = mkDir "/mnt/lamet" "Lamet drive mount point.";
mobile-drive = mkDir "/mnt/mobile" "Mobile drive mount point.";
therima-drive = mkDir "/mnt/therima" "Therima drive mount point.";
vetymae-drive = mkDir "/mnt/vetymae" "Vetymae drive mount point.";
soptur-drive = mkDir "/mnt/soptur" "Soptur drive mount point.";
wsl-home = mkDir "/mnt/c/Users/${config.xlib.device.username}" "WSL home directory.";
wsl-storage = mkDir "${config.xlib.dirs.wsl-home}/Storage" "WSL storage directory.";
server-home = mkDir "/home/${config.xlib.device.username}/External" "Server home directory.";
server-credentials = mkDir "${config.xlib.dirs.server-home}/Credentials/server" "Server credentials directory.";
storage = mkDir "${config.xlib.dirs.server-home}/Storage" "General storage directory.";
calibre-library = mkDir "${config.xlib.dirs.server-home}/Books-Library" "Calibre library directory.";
music-library = mkDir "${config.xlib.dirs.user-home}/Music" "Music library directory.";
services-folder = mkDir "${config.xlib.dirs.server-home}/Services" "All services folder.";
services-mnt-folder = mkDir "/mnt/services" "All services folder.";
services-nodes-folder = mkDir "${config.xlib.dirs.services-mnt-folder}/nodes" "All nodes folder.";
postgresql-folder = mkDir "${config.xlib.dirs.services-mnt-folder}/postgresql" "PostgreSQL service folder.";
};
helpers = lib.mkOption {
type = lib.types.anything;
default = helpers;
description = "Shared helper functions (see lib/xlib.nix).";
};
services."3x-ui" = {
# Domain whose Let's Encrypt cert (at /var/lib/acme/<domain>/)
# gets mounted read-only into the 3x-ui container so the panel
# can terminate TLS itself. Set null if 3x-ui serves plain HTTP
# and TLS is terminated by an upstream nginx.
certDomain = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "pubray1.zeroq.su";
description = ''
Domain whose LE cert should be mounted into the 3x-ui
container at /root/cert/fullchain.pem and key.pem.
'';
};
user-storage = lib.mkOption {
type = lib.types.str;
default = "${config.xlib.dirs.user-home}/Storage";
description = "User storage directory.";
};
archive-drive = lib.mkOption {
type = lib.types.str;
default = "/mnt/archive";
description = "Archive drive mount point.";
};
lamet-drive = lib.mkOption {
type = lib.types.str;
default = "/mnt/lamet";
description = "Lamet drive mount point.";
};
mobile-drive = lib.mkOption {
type = lib.types.str;
default = "/mnt/mobile";
description = "Mobile drive mount point.";
};
therima-drive = lib.mkOption {
type = lib.types.str;
default = "/mnt/therima";
description = "Therima drive mount point.";
};
vetymae-drive = lib.mkOption {
type = lib.types.str;
default = "/mnt/vetymae";
description = "Vetymae drive mount point.";
};
soptur-drive = lib.mkOption {
type = lib.types.str;
default = "/mnt/soptur";
description = "Soptur drive mount point.";
};
wsl-home = lib.mkOption {
type = lib.types.str;
default = "/mnt/c/Users/${config.xlib.device.username}";
description = "WSL home directory.";
};
wsl-storage = lib.mkOption {
type = lib.types.str;
default = "${config.xlib.dirs.wsl-home}/Storage";
description = "WSL storage directory.";
};
server-home = lib.mkOption {
type = lib.types.str;
default = "/home/${config.xlib.device.username}/External";
description = "Server home directory.";
};
server-credentials = lib.mkOption {
type = lib.types.str;
default = "${config.xlib.dirs.server-home}/Credentials/server";
description = "Server credentials directory.";
};
storage = lib.mkOption {
type = lib.types.str;
default = "${config.xlib.dirs.server-home}/Storage";
description = "General storage directory.";
};
calibre-library = lib.mkOption {
type = lib.types.str;
default = "${config.xlib.dirs.server-home}/Books-Library";
description = "Calibre library directory.";
};
music-library = lib.mkOption {
type = lib.types.str;
default = "${config.xlib.dirs.user-home}/Music";
description = "Music library directory.";
};
services-folder = lib.mkOption {
type = lib.types.str;
default = "${config.xlib.dirs.server-home}/Services";
description = "All services folder.";
};
services-mnt-folder = lib.mkOption {
type = lib.types.str;
default = "/mnt/services";
description = "All services folder.";
};
postgresql-folder = lib.mkOption {
type = lib.types.str;
default = "${config.xlib.dirs.services-mnt-folder}/postgresql";
description = "PostgreSQL service folder.";
# Publish host:15380 → container:443. Only nodes that host an
# Xray REALITY inbound on container:443 need this (so nginx
# stream can forward TLS to Xray via 127.0.0.1:15380 while Xray
# itself sees incoming connections on its configured port 443).
# Set false on nodes that only run the 3x-ui panel.
reality443Forwarding = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
When true, publish host:15380 → container:443 so Xray
inside the container can serve REALITY on its real
configured port 443 (nginx stream forwards 443 → 15380).
'';
};
};
};
-32
View File
@@ -1,32 +0,0 @@
{
config,
xlib,
pkgs,
...
}:
let
user = "snity";
in
{
users = {
users = {
"${user}" = {
name = "${user}";
isNormalUser = true;
group = "users";
description = "Snity";
hashedPassword = "$y$j9T$851xwObfIp7SYzIyFtH.k1$mNofT2sxEAV50Kxgmwvqc6Kj/3B/fJoPP8qgn./siEB";
homeMode = "700";
home = "/home/${user}";
extraGroups = [
"audio"
"disk"
"gamemode"
"networkmanager"
"pipewire"
"wheel"
];
};
};
};
}
+76
View File
@@ -0,0 +1,76 @@
{
config,
inputs,
lib,
pkgs,
xlib,
...
}:
let
beetsEnv = pkgs.python314.withPackages (
ps: with ps; [
anyio
beautifulsoup4
beetcamp
beets
certifi
charset-normalizer
colorama
confuse
discogs-client
filetype
h11
httpcore
httpx
httpx-socks
idna
jellyfish
langdetect
lap
llvmlite
mediafile
mutagen
numba
numpy
oauthlib
packaging
pillow
platformdirs
pycountry
pylast
pyrate-limiter
pysocks
python-dateutil
pyyaml
requests
requests-ratelimiter
scipy
six
socksio
soupsieve
typing-extensions
unidecode
urllib3
]
);
in
{
users = {
users = {
"${xlib.device.username}" = {
packages = [
beetsEnv
pkgs.mp3gain
pkgs.imagemagick
#ffmpeg
];
};
};
};
systemd.mounts = [
(xlib.helpers.mkSystemdBind {
what = "/home/${xlib.device.username}/Music";
where = "/home/${xlib.device.username}/.config/beets";
})
];
}
-9
View File
@@ -1,9 +0,0 @@
{
lib,
...
}:
{
imports = [
../desktop
];
}
-9
View File
@@ -1,9 +0,0 @@
{
lib,
...
}:
{
imports = [
../desktop
];
}
+28
View File
@@ -0,0 +1,28 @@
{
config,
pkgs,
...
}:
{
security = {
acme = {
acceptTerms = true;
defaults = {
email = "oqyude@gmail.com";
};
# certs = {
# "home.arpa" = {
# email = "oqyude@zeroq.su";
# domain = "*.home.arpa";
# server = "https://localhost:9000/acme/acme/directory";
# listenHTTP = ":80";
# dnsProvider = null;
# };
# # "turn.home.arpa" = {
# # listenHTTP = "127.0.0.1:80";
# # group = "turnserver";
# # };
# };
};
};
}
+19
View File
@@ -0,0 +1,19 @@
{
config,
inputs,
...
}:
{
services.bentopdf = {
enable = true;
domain = "pdf.private";
nginx = {
enable = true;
# virtualHost = {
# forceSSL = true;
# enableACME = true;
# };
};
# package = pkgs-stable.bentopdf;
};
}
+62 -13
View File
@@ -1,22 +1,71 @@
{
config,
xlib,
inputs,
pkgs,
xlib,
...
}:
let
# stable = import inputs.nixpkgs-previous {
# system = "x86_64-linux";
# };
libraryDir = "${xlib.dirs.services-mnt-folder}/calibre-web-library";
sourceDir = "${xlib.dirs.services-mnt-folder}/calibre-web";
targetDir = "/var/lib/calibre-web";
in
{
services.calibre-web = {
enable = true;
group = "users";
user = "${xlib.device.username}";
options = {
calibreLibrary = "${xlib.dirs.calibre-library}";
enableBookUploading = true;
enableKepubify = true;
enableBookConversion = false;
services = {
calibre-web = {
# package = stable.calibre-web;
enable = true;
# dataDir = "${xlib.dirs.services-mnt-folder}/calibre-web";
options = {
calibreLibrary = "${libraryDir}";
enableBookUploading = true;
enableKepubify = true;
enableBookConversion = false;
};
listen.ip = "0.0.0.0";
listen.port = 8083;
openFirewall = true;
};
listen.ip = "0.0.0.0";
listen.port = 8083;
openFirewall = true;
# calibre-server = {
# enable = true;
# port = 8091;
# host = "0.0.0.0";
# openFirewall = true;
# user = "calibre-web";
# group = "calibre-web";
# libraries = [
# "/var/lib/calibre-server"
# ];
# };
};
systemd.tmpfiles.rules =
xlib.helpers.mkTmpDirs {
dir = libraryDir;
mode = "0755";
user = "calibre-web";
group = "calibre-web";
types = [
"d"
"Z"
];
}
++ xlib.helpers.mkTmpDirs {
dir = sourceDir;
mode = "0755";
user = "calibre-web";
group = "calibre-web";
types = [
"d"
"Z"
];
};
fileSystems = xlib.helpers.mkBindMount {
what = sourceDir;
where = targetDir;
};
}
+10
View File
@@ -0,0 +1,10 @@
{
config,
pkgs,
...
}:
{
services.chrony = {
enable = true;
};
}
-28
View File
@@ -1,28 +0,0 @@
{
config,
lib,
pkgs,
inputs,
xlib,
...
}:
{
# 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 -"
# ];
# environment = {
# systemPackages = with pkgs; [
# immich-cli
# ];
# };
}
+63
View File
@@ -0,0 +1,63 @@
{
config,
pkgs,
...
}:
{
services.coredns = {
enable = true;
config = ''
zeroq.su:53 {
hosts {
109.248.161.5 x.zeroq.su
192.168.1.20 calibre.zeroq.su
192.168.1.20 dns.zeroq.su
192.168.1.20 flux.zeroq.su
192.168.1.20 git.zeroq.su
192.168.1.20 glances.zeroq.su
192.168.1.20 homebox.zeroq.su
192.168.1.20 immich.zeroq.su
192.168.1.20 kuma.zeroq.su
192.168.1.20 navidrome.zeroq.su
192.168.1.20 nextcloud.zeroq.su
192.168.1.20 office.zeroq.su
192.168.1.20 pdf.zeroq.su
192.168.1.20 syncthing.zeroq.su
192.168.1.20 talk.zeroq.su
192.168.1.20 turn.zeroq.su
fallthrough
}
cache 300
log
}
home.arpa:53 {
hosts {
192.168.1.100 vetymae.home.arpa
192.168.1.20 ca.home.arpa
192.168.1.20 calibre.home.arpa
192.168.1.20 dns.home.arpa
192.168.1.20 flux.home.arpa
192.168.1.20 git.home.arpa
192.168.1.20 glances.home.arpa
192.168.1.20 home.arpa
192.168.1.20 homebox.home.arpa
192.168.1.20 immich.home.arpa
192.168.1.20 kuma.home.arpa
192.168.1.20 navidrome.home.arpa
192.168.1.20 nextcloud.home.arpa
192.168.1.20 office.home.arpa
192.168.1.20 pdf.home.arpa
192.168.1.20 sapphira.home.arpa
192.168.1.20 syncthing.home.arpa
fallthrough
}
cache 300
log
}
.:53 {
forward . 192.168.1.1 1.1.1.1
cache 300
}
'';
};
}
+53
View File
@@ -0,0 +1,53 @@
{
config,
inputs,
lib,
pkgs,
xlib,
...
}:
# let
# acme-path = "/var/lib/acme";
# in
{
services.coturn = {
enable = false;
realm = "turn.home.arpa";
# cert = "${acme-path}/turn.home.arpa/fullchain.pem";
# pkey = "${acme-path}/turn.home.arpa/key.pem";
use-auth-secret = true;
static-auth-secret-file = config.sops.secrets.turn-secret.path;
no-cli = true;
listening-port = 3478; # TURN
# tls-listening-port = 5349; # TURNS
extraConfig = ''
min-port=49160
max-port=49200
'';
};
networking.firewall = {
allowedTCPPorts = [
3478
# 5349
];
allowedUDPPorts = [
3478
];
allowedUDPPortRanges = [
{
from = 49160;
to = 49200;
}
];
};
sops.secrets = {
turn-secret = {
format = "yaml";
key = "turn-secret";
sopsFile = ./secrets/coturn.yaml;
group = "nextcloud-spreed-signaling";
owner = "turnserver";
mode = "0440";
};
};
}
+34 -6
View File
@@ -1,30 +1,58 @@
{
lib,
xlib,
...
}:
{
imports = [
../software/beets
../containers/3x-ui.nix
# ../containers/tape-rotation.nix
../pkgs/beets.nix
./acme.nix
./bentopdf.nix
./calibre-web.nix
./containers
./chrony.nix
./coredns.nix
./gitea.nix
./glances.nix
./homebox.nix
./immich.nix
./miniflux.nix
./navidrome.nix
./nextcloud.nix
./nginx.nix
./open-webui.nix
./nix-serve.nix
./onlyoffice.nix
./postgresql.nix
./power.nix
./samba.nix
./stirling-pdf.nix
./syncthing.nix
./systemd.nix
./transmission.nix
./uptime-kuma.nix
# ../containers/remnawave.nix
# ./coturn.nix
# ./mealie.nix
# ./memos.nix
# ./minecraft.nix
# ./n8n.nix
# ./netdata.nix
# ./nfs.nix
# ./node-red.nix
# ./open-webui.nix
# ./rsync.nix
# ./step-ca.nix
# ./stirling-pdf.nix
# ./transmission.nix
# ./trilium.nix
# ./zerotier.nix
];
# Server's 3x-ui is the controller panel at x.zeroq.su (nginx HTTP
# terminates TLS upstream, no SNI-routing on 443 needed here because
# there are other vhosts on the same port). Cert is still mounted in
# case 3x-ui is later reconfigured to terminate TLS itself (e.g. for
# direct node-API access); nginx doesn't have to use it.
xlib.services."3x-ui".certDomain = "x.zeroq.su";
systemd.tmpfiles.rules = [
(xlib.helpers.mkTmpfile "d" "/mnt" "0755" "root" "root")
(xlib.helpers.mkTmpfile "d" xlib.dirs.services-mnt-folder "0755" "root" "root")
];
}
+31
View File
@@ -0,0 +1,31 @@
{
config,
inputs,
lib,
pkgs,
xlib,
...
}:
{
services = {
gitea = {
enable = true;
stateDir = "${xlib.dirs.services-mnt-folder}/gitea";
appName = "ZeroQ Gitea Service";
settings = {
server = {
DOMAIN = "git.zeroq.su";
HTTP_PORT = 3000;
};
service.DISABLE_REGISTRATION = true;
};
};
};
systemd.tmpfiles.rules = xlib.helpers.mkTmpDirs {
dir = config.services.gitea.stateDir;
mode = "0755";
user = "gitea";
group = "gitea";
};
}
+15
View File
@@ -0,0 +1,15 @@
{
config,
lib,
pkgs,
...
}:
{
services = {
glances = {
enable = true;
openFirewall = true;
port = 61208;
};
};
}
+33
View File
@@ -0,0 +1,33 @@
{
config,
pkgs,
xlib,
...
}:
let
storage = xlib.helpers.mkServiceStorage {
name = "homebox";
user = "homebox";
group = "homebox";
};
in
{
services.homebox = {
enable = true;
settings = {
HBOX_WEB_HOST = "0.0.0.0";
HBOX_WEB_PORT = "7745";
HBOX_STORAGE_CONN_STRING = "file://${storage.target}";
HBOX_STORAGE_PREFIX_PATH = "data";
HBOX_DATABASE_DRIVER = "sqlite3";
HBOX_DATABASE_SQLITE_PATH = "${storage.target}/data/homebox.db?_pragma=busy_timeout=999&_pragma=journal_mode=WAL&_fk=1";
HBOX_OPTIONS_ALLOW_REGISTRATION = "true";
HBOX_OPTIONS_GITHUB_RELEASE_CHECK = "false";
HBOX_MODE = "production";
HOME = "${storage.target}";
TMPDIR = "${storage.target}/tmp";
};
};
systemd = storage.systemd;
}
+2 -20
View File
@@ -1,44 +1,26 @@
{
config,
inputs,
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 -"
(xlib.helpers.mkTmpfile "z" config.services.immich.mediaLocation "0755" "immich" "immich")
];
users.users.immich.extraGroups = [
+1 -1
View File
@@ -4,7 +4,7 @@
}:
{
services.mealie = {
enable = true;
enable = false;
listenAddress = "0.0.0.0";
port = 9000;
database.createLocally = true;
+2 -2
View File
@@ -5,7 +5,7 @@
}:
{
services.memos = {
enable = true;
enable = false;
openFirewall = true;
settings = {
MEMOS_MODE = "prod";
@@ -21,6 +21,6 @@
};
systemd.tmpfiles.rules = [
"z /mnt/services/memos 0750 memos memos -"
(xlib.helpers.mkTmpfile "z" "${xlib.dirs.services-mnt-folder}/memos" "0750" "memos" "memos")
];
}
+67
View File
@@ -0,0 +1,67 @@
{
config,
inputs,
pkgs,
xlib,
...
}:
let
storage = xlib.helpers.mkServiceStorage {
name = "minecraft";
user = "minecraft";
group = "minecraft";
mode = "770";
};
in
{
imports = [ inputs.nix-minecraft.nixosModules.minecraft-servers ];
nixpkgs.overlays = [ inputs.nix-minecraft.overlay ];
services.minecraft-servers = {
enable = true;
eula = true;
openFirewall = true;
dataDir = "/var/lib/minecraft";
servers = {
vanilla = {
enable = true;
package = pkgs.fabricServers.fabric-26_2.override {
jre_headless = pkgs.jdk25_headless;
};
jvmOpts = "-Xmx2G -Xms1G";
enableReload = true;
serverProperties = {
view-distance = 6;
simulation-distance = 4;
online-mode = false;
difficulty = 3;
gamemode = 1;
max-players = 5;
server-port = 25565;
motd = "ZeroQ сервак майна епта!";
enable-rcon = true;
"rcon.password" = "zeroq";
};
symlinks.mods = pkgs.linkFarmFromDrvs "mods" (
builtins.attrValues {
Lithium = pkgs.fetchurl {
name = "lithium-fabric-0.25.3+mc26.2.jar";
url = "https://cdn.modrinth.com/data/gvQqBUqZ/versions/f7vZ0VWU/lithium-fabric-0.25.3%2Bmc26.2.jar";
hash = "sha256-/d6S4jjoB1+JrX9wHyo9WFSviLqaZ2VxhKRAexBKxWM=";
};
FerriteCore = pkgs.fetchurl {
name = "ferritecore-9.0.0-fabric.jar";
url = "https://cdn.modrinth.com/data/uXXizFIs/versions/d5ddUdiB/ferritecore-9.0.0-fabric.jar";
hash = "sha256-ITlmxy7ZZ6zHOSvrKKhm+6MB/1a5l2wueAHC233mvyI=";
};
Krypton = pkgs.fetchurl {
name = "krypton-0.3.1.jar";
url = "https://cdn.modrinth.com/data/fQEb0iXm/versions/5WeL0Nkz/krypton-0.3.1.jar";
hash = "sha256-XqiQFWGXPSnlHnUUadUtkhAPNIq0YeEYb2cBLpNCDEg=";
};
}
);
};
};
};
systemd = storage.systemd;
}
-1
View File
@@ -12,7 +12,6 @@
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;
};
+28
View File
@@ -0,0 +1,28 @@
{
config,
lib,
pkgs,
xlib,
inputs,
...
}:
let
storage = xlib.helpers.mkServiceStorage {
name = "n8n";
user = "nobody";
group = "nogroup";
};
in
{
services.n8n = {
enable = false;
environment = {
# N8N_USER_FOLDER = lib.mkForce "${sourceDir}";
N8N_SECURE_COOKIE = "false";
N8N_PORT = 5678;
};
openFirewall = true;
};
systemd = storage.systemd;
}
+32
View File
@@ -0,0 +1,32 @@
{
config,
inputs,
lib,
pkgs,
xlib,
...
}:
let
libraryDir = "${xlib.dirs.server-home}/Music";
pointDir = "/var/lib/services/navidrome-point";
in
{
services = {
navidrome = {
enable = true;
openFirewall = true;
# environmentFile = "";
settings = {
Address = "0.0.0.0";
Port = 4533;
MusicFolder = "${pointDir}";
};
};
};
systemd.mounts = [
(xlib.helpers.mkSystemdBind {
what = libraryDir;
where = pointDir;
})
];
}
+32
View File
@@ -0,0 +1,32 @@
{
config,
inputs,
lib,
pkgs,
...
}:
{
services = {
netdata = {
enable = false;
package = pkgs.netdata.override {
withCloudUi = true;
};
config = {
web = {
"allow connections from" = "localhost *";
"default port" = "19999";
"bind to" = "0.0.0.0";
};
};
# python = {
# enable = true;
# recommendedPythonPackages = true;
# };
};
};
networking.firewall.allowedTCPPorts = [
19999
];
}
+186 -92
View File
@@ -1,34 +1,60 @@
{
config,
inputs,
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";
NEXTCLOUD_URL = "https://nextcloud.zeroq.su";
};
secrets = [ config.sops.secrets.nextcloud-whiteboard-jwt.path ];
};
nextcloud-spreed-signaling = {
enable = false;
hostName = "talk.private";
backends.nextcloud = {
urls = [
"https://nextcloud.zeroq.su"
# "https://nextcloud.home.arpa"
];
secretFile = config.sops.secrets.nextcloud-talk-secret.path;
};
settings = {
http.listen = "127.0.0.1:8080";
clients.internalsecretFile = config.sops.secrets.internal-secret.path;
sessions = {
hashkeyFile = config.sops.secrets.hashkey.path;
blockkeyFile = config.sops.secrets.blockkey.path;
};
mcu = {
type = "janus";
url = "ws://127.0.0.1:8188";
};
turn = {
secretFile = config.sops.secrets.turn-secret.path;
apikeyFile = config.sops.secrets.turn-api-key.path;
servers = [
"turn:turn.zeroq.su:3478?transport=udp"
"turn:turn.zeroq.su:3478?transport=tcp"
# "turns:turn.zeroq.su:5349?transport=tcp"
];
};
};
secrets = [ "${inputs.zeroq-credentials}/services/nextcloud/jwt-secret.txt" ];
};
nextcloud = {
enable = true;
package = pkgs.nextcloud32;
hostName = "nextcloud.local";
package = pkgs.nextcloud34;
hostName = "nextcloud.private";
database.createLocally = true;
home = "${xlib.dirs.services-mnt-folder}/nextcloud";
configureRedis = true;
https = true;
caching = {
redis = true;
memcached = true;
@@ -39,30 +65,46 @@ in
dbuser = "nextcloud";
dbname = "nextcloud";
adminuser = "oqyude";
adminpassFile = "${inputs.zeroq-credentials}/services/nextcloud/admin-pass.txt";
adminpassFile = config.sops.secrets.nextcloud-adminpass.path;
};
settings = {
log_type = "file";
trusted_domains = [
"nextcloud.zeroq.ru"
"100.64.0.0"
"192.168.1.20"
"37.128.246.126"
"localhost"
"nextcloud.home.arpa"
"nextcloud.private"
"nextcloud.zeroq.su"
"office.home.arpa"
"office.zeroq.su"
];
trusted_proxies = [
"100.64.1.0"
"109.248.161.5"
"192.168.1.20"
"37.128.246.126"
];
overwriteprotocol = "https";
overwriteprotocol = "https"; # maybe no
};
extraAppsEnable = true;
appstoreEnable = false;
notify_push = {
enable = true;
bendDomainToLocalhost = true;
nextcloudUrl = "https://nextcloud.zeroq.su";
};
# phpPackage = pkgs.php85;
extraApps = {
inherit (config.services.nextcloud.package.packages.apps) # (config.services.nextcloud.package.packages.apps)
inherit (config.services.nextcloud.package.packages.apps)
# richdocuments
# gpoddersync
# integration_paperless
# memories
# news
# nextpod
# onlyoffice
# notify_push
# phonetrack
# repod
# sociallogin
@@ -80,102 +122,154 @@ in
impersonate
mail
music
# news
notes
notify_push
onlyoffice
polls
previewgenerator
richdocuments
spreed
tables
tasks
user_oidc
user_saml
whiteboard
;
inherit (pkgs.nextcloud31Packages.apps)
# end_to_end_encryption
# maps
tasks
;
# 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";
};
# collabora-online = {
# enable = false;
# port = 9980;
# # package = master.collabora-online;
# settings = {
# server_name = "office.zeroq.su";
# 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"
# ];
# };
# };
# };
};
# fonts.packages = [ work.corefonts ];
# networking.hosts = {
# };
# networking.hosts = {
# "localhost" = [ "nextcloud-private.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.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.su";
# 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";
# };
# };
systemd.tmpfiles.rules = [
"z ${config.services.nextcloud.home} 0750 nextcloud nextcloud -"
(xlib.helpers.mkTmpfile "z" config.services.nextcloud.home "0750" "nextcloud" "nextcloud")
];
environment.systemPackages = [
pkgs.nc4nix # Packaging helper for Nextcloud apps
];
sops.secrets = {
nextcloud-adminpass = {
format = "yaml";
key = "adminpass";
sopsFile = ./secrets/nextcloud.yaml;
owner = "nextcloud";
group = "nextcloud";
mode = "0650";
};
nextcloud-whiteboard-jwt = {
format = "yaml";
key = "whiteboard-jwt";
sopsFile = ./secrets/nextcloud.yaml;
owner = "nextcloud";
group = "nextcloud";
mode = "0650";
};
nextcloud-talk-secret = {
format = "yaml";
key = "nextcloud-talk-secret";
sopsFile = ./secrets/nextcloud.yaml;
# owner = "nextcloud-spreed-signaling";
# group = "nextcloud-spreed-signaling";
mode = "0440";
};
internal-secret = {
format = "yaml";
key = "internal-secret";
sopsFile = ./secrets/nextcloud.yaml;
# owner = "nextcloud-spreed-signaling";
# group = "nextcloud-spreed-signaling";
mode = "0440";
};
hashkey = {
format = "yaml";
key = "hashkey";
sopsFile = ./secrets/nextcloud.yaml;
# owner = "nextcloud-spreed-signaling";
# group = "nextcloud-spreed-signaling";
mode = "0440";
};
blockkey = {
format = "yaml";
key = "blockkey";
sopsFile = ./secrets/nextcloud.yaml;
# owner = "nextcloud-spreed-signaling";
# group = "nextcloud-spreed-signaling";
mode = "0440";
};
turn-secret = {
format = "yaml";
key = "turn-secret";
sopsFile = ./secrets/coturn.yaml;
# group = "nextcloud-spreed-signaling";
mode = "0440";
};
turn-api-key = {
format = "yaml";
key = "turn-api-key";
sopsFile = ./secrets/coturn.yaml;
# group = "nextcloud-spreed-signaling";
mode = "0440";
};
};
}
+1 -1
View File
@@ -6,7 +6,7 @@
}:
{
systemd.tmpfiles.rules = [
"z /export 0755 nobody nogroup -"
(xlib.helpers.mkTmpfile "z" "/export" "0755" "nobody" "nogroup")
];
services.nfs = {
server = {
+204 -70
View File
@@ -5,80 +5,214 @@
xlib,
...
}:
# Standard reverse-proxy: HTTP/S termination upstream, backend on the LAN.
# x.zeroq.su is the 3x-ui controller panel — see 3x-ui.nix for the
# /subs/, /subsjs/, /clash/ routing logic.
let
server = "192.168.1.20";
mkProxy =
{
domain,
port,
addSSL ? false,
extraConfig ? "",
}:
{
name = domain;
value = {
enableACME = true;
locations."/" = {
proxyPass = "http://${server}:${toString port}";
proxyWebsockets = true;
};
}
// lib.optionalAttrs (!addSSL) { forceSSL = true; }
// lib.optionalAttrs addSSL { addSSL = true; }
// lib.optionalAttrs (extraConfig != "") { inherit extraConfig; };
};
bigUploads = "client_max_body_size 5G;";
sites = [
{
domain = "immich.zeroq.su";
port = 2283;
addSSL = true;
extraConfig = bigUploads;
}
{
domain = "kuma.zeroq.su";
port = 4001;
}
{
domain = "health.zeroq.su";
port = 19999;
}
{
domain = "git.zeroq.su";
port = 3000;
}
{
domain = "homebox.zeroq.su";
port = 7745;
}
{
domain = "flux.zeroq.su";
port = 6061;
}
{
domain = "tape-rotation.zeroq.su";
port = 5174;
}
{
domain = "navidrome.zeroq.su";
port = 4533;
addSSL = true;
}
{
domain = "calibre.zeroq.su";
port = 8083;
extraConfig = bigUploads;
}
{
domain = "nix-cache.zeroq.su";
port = 5000;
extraConfig = bigUploads;
}
{
domain = "pdf.zeroq.su";
port = 8446;
extraConfig = bigUploads;
}
];
in
{
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;
}
];
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
virtualHosts = (builtins.listToAttrs (map mkProxy sites)) // {
"nextcloud.private" = {
forceSSL = false;
enableACME = false;
listen = [
{
addr = "100.64.0.0";
port = 10000;
}
{
addr = "192.168.1.20";
port = 10000;
}
{
addr = "127.0.0.1";
port = 10000;
}
];
};
"office.zeroq.su" = {
forceSSL = true;
enableACME = true;
};
"pdf.private" = {
forceSSL = false;
enableACME = false;
listen = [
{
addr = "0.0.0.0";
port = 80;
}
{
addr = "100.64.0.0";
port = 8446;
}
{
addr = "192.168.1.20";
port = 8446;
}
{
addr = "127.0.0.1";
port = 8446;
}
];
extraConfig = bigUploads;
};
"x.zeroq.su" = {
forceSSL = true;
enableACME = true;
locations = {
"/" = {
proxyPass = "http://${server}:2049";
proxyWebsockets = true;
};
"/subs/" = {
proxyPass = "http://${server}:2096";
proxyWebsockets = true;
};
"/subsjs/" = {
proxyPass = "http://${server}:2096";
proxyWebsockets = true;
};
"/clash/" = {
proxyPass = "http://${server}:2096";
proxyWebsockets = true;
};
};
"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;
}
];
};
"zeroq.su" = {
forceSSL = true;
enableACME = true;
root = pkgs.writeTextDir "index.html" ''
<!doctype html>
<html>
<body>
<pre>What are you doing here?</pre>
</body>
</html>
'';
locations."/guest/" = {
proxyPass = "http://${server}:80";
proxyWebsockets = true;
};
# "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;
# '';
# };
};
"vetymae.opencodes.zeroq.su" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://100.86.62.4:4096";
proxyWebsockets = true;
};
};
"lamet.opencodes.zeroq.su" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://100.106.21.39:6061";
proxyWebsockets = true;
};
};
"nextcloud.zeroq.su" = {
forceSSL = true;
enableACME = true;
locations = {
"/" = {
proxyPass = "http://${server}:10000";
proxyWebsockets = true;
};
"/whiteboard" = {
proxyPass = "http://${server}:3002";
proxyWebsockets = true;
};
};
extraConfig = bigUploads;
};
};
};
networking.firewall.allowedTCPPorts = [
80
443
];
}
+25
View File
@@ -0,0 +1,25 @@
{
config,
lib,
pkgs,
...
}:
{
services = {
nix-serve = {
enable = true;
package = pkgs.nix-serve-ng;
openFirewall = true;
port = 5000;
bindAddress = "0.0.0.0";
secretKeyFile = config.sops.secrets.private-key.path;
};
};
sops.secrets = {
private-key = {
key = "private-key";
sopsFile = ./secrets/nix-serve.yaml;
mode = "0600";
};
};
}
-21
View File
@@ -1,21 +0,0 @@
{
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 -"
];
}
+45
View File
@@ -0,0 +1,45 @@
{
config,
inputs,
lib,
pkgs,
xlib,
...
}:
let
# previous = import inputs.nixpkgs-master {
# system = "x86_64-linux";
# config.allowUnfree = true;
# config.allowUnfreePredicate = true;
# };
in
{
services.onlyoffice = {
enable = true;
# package = previous.onlyoffice-documentserver;
hostname = "office.zeroq.su";
port = 8090;
allowLocalConnections = true;
wopi = true;
jwtSecretFile = config.sops.secrets.onlyoffice-jwt.path;
securityNonceFile = config.sops.secrets.onlyoffice-nonce.path;
};
sops.secrets = {
onlyoffice-nonce = {
format = "yaml";
key = "nonce";
sopsFile = ./secrets/onlyoffice.yaml;
owner = "onlyoffice";
group = "onlyoffice";
mode = "0650";
};
onlyoffice-jwt = {
format = "yaml";
key = "jwt";
sopsFile = ./secrets/onlyoffice.yaml;
owner = "onlyoffice";
group = "onlyoffice";
mode = "0650";
};
};
}
+6 -15
View File
@@ -7,8 +7,11 @@
...
}:
let
master = import inputs.nixpkgs-master {
system = "x86_64-linux";
storage = xlib.helpers.mkServiceStorage {
name = "postgresql";
user = "postgres";
group = "postgres";
mode = "0760";
};
in
{
@@ -16,21 +19,9 @@ in
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 -"
];
systemd = storage.systemd;
}
+16
View File
@@ -0,0 +1,16 @@
{
config,
lib,
pkgs,
...
}:
{
services = {
tuned = {
enable = true;
};
auto-cpufreq.enable = false;
power-profiles-daemon.enable = lib.mkForce false;
throttled.enable = false;
};
}

Some files were not shown because too many files have changed in this diff Show More