mirror of
https://github.com/oqyude/nixos.git
synced 2026-10-07 20:47:14 +03:00
Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a71f87b772 | ||
|
|
ac561815ed | ||
|
|
2be5b168ac | ||
|
|
eddf44fb02 | ||
|
|
caeb04142d | ||
|
|
1db2b0955b | ||
|
|
a8ddf9b8dc | ||
|
|
bc3566d80e | ||
|
|
0fdf6c965c | ||
|
|
5bccf7586d | ||
|
|
2912581b99 |
Generated
+51
-60
@@ -33,11 +33,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1781152676,
|
"lastModified": 1789770686,
|
||||||
"narHash": "sha256-RxWs5ND31KzTG7wvMM+PMfUjyNpmIEr999lqNARaM5o=",
|
"narHash": "sha256-uZkBR7yHdIKUFB5SZdfgh1qkGfI3XmYmI/lTiquxbck=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "disko",
|
"repo": "disko",
|
||||||
"rev": "ff8702b4de27f72b4c78573dfb89ec74e36abdf1",
|
"rev": "725ea35e410ad83be4931d1bff7e090eacaf3563",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -63,10 +63,7 @@
|
|||||||
},
|
},
|
||||||
"flake-parts": {
|
"flake-parts": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs-lib": [
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
"justray",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1788450739,
|
"lastModified": 1788450739,
|
||||||
@@ -109,11 +106,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1789482455,
|
"lastModified": 1790128814,
|
||||||
"narHash": "sha256-pD3qVlQ4mUCFoTWrYtxecpSitQMsgJvJIN0FUIDZoEU=",
|
"narHash": "sha256-6Gm9q+wW3E4Ey4F6wEbJAwaMsEK6hvCYfTW7yY64ZfA=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "efa3ccb4c3cc90d832eab232976379058fa75aa3",
|
"rev": "0b2f1129177f70c5f0f5d88bb53c49ca47d0bfc0",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -124,17 +121,19 @@
|
|||||||
},
|
},
|
||||||
"justray": {
|
"justray": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-parts": "flake-parts",
|
"flake-parts": [
|
||||||
|
"flake-parts"
|
||||||
|
],
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1789450388,
|
"lastModified": 1790165840,
|
||||||
"narHash": "sha256-30EGO2CUKyJ6VOJF9Zw3B5myrXRjjEmFXpkJOWC3KHI=",
|
"narHash": "sha256-nQ3uCXiUGTLD/UtuChc2XlStYg9a33PYrkDitmmqxW8=",
|
||||||
"owner": "luynrs",
|
"owner": "luynrs",
|
||||||
"repo": "justray",
|
"repo": "justray",
|
||||||
"rev": "cbe71cb1e71c9f29f7384e9039af4eca9af8ab3a",
|
"rev": "4073f3fb223613e4d780dafad6f93b5c266061a2",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -198,11 +197,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1789446796,
|
"lastModified": 1790137578,
|
||||||
"narHash": "sha256-dsgZ/cC/ZcbvAM4ZZK2USpS5e34AVo0OlBkuBvzJufQ=",
|
"narHash": "sha256-luzO2Bo/RxUHqTPxBttSB1QVzM9Y5s+Iwpip6SjWdWo=",
|
||||||
"owner": "Infinidoge",
|
"owner": "Infinidoge",
|
||||||
"repo": "nix-minecraft",
|
"repo": "nix-minecraft",
|
||||||
"rev": "9552774a584b6fb0e3981f8b73372d65f36e68cf",
|
"rev": "2e6a1d1ceb4da6b6ffb3980bc7993b3d057cd4db",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -256,14 +255,16 @@
|
|||||||
},
|
},
|
||||||
"nixos-hardware": {
|
"nixos-hardware": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1789417814,
|
"lastModified": 1789978172,
|
||||||
"narHash": "sha256-xV9fcqtH6jJLVBF3ocqBBwZkPKEke+BujhEwT4Ye9Tc=",
|
"narHash": "sha256-FIRXajv1pPZ+l6On6ekkmcQ6le0Zi0ncRUoR3nB0vKA=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixos-hardware",
|
"repo": "nixos-hardware",
|
||||||
"rev": "d40fd26f323c898b0c195d41aa5efadd85f57832",
|
"rev": "9ebcb7766700d7e006d9505247bd7ce0426f4232",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -299,15 +300,18 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1767892417,
|
"lastModified": 1790046670,
|
||||||
"narHash": "sha256-8bW3q88CEg2u4hSP66Vf4lpbLonHz7hqDNBMcCY7E9U=",
|
"narHash": "sha256-MYiI+CzL0tuWgRPjGsKCDHqYs2T3OzMlMQWOYWG0qso=",
|
||||||
"rev": "3497aa5c9457a9d88d71fa93a4a8368816fbeeba",
|
"owner": "NixOS",
|
||||||
"type": "tarball",
|
"repo": "nixpkgs",
|
||||||
"url": "https://releases.nixos.org/nixos/unstable/nixos-26.05pre924538.3497aa5c9457/nixexprs.tar.xz"
|
"rev": "6774f7bc253789b113a4f39285dc0fa100abeacc",
|
||||||
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"type": "tarball",
|
"owner": "NixOS",
|
||||||
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs-docs": {
|
"nixpkgs-docs": {
|
||||||
@@ -342,19 +346,18 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs-lib": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1789286504,
|
"lastModified": 1788057806,
|
||||||
"narHash": "sha256-eiEK7cKZORNEvX0GeF3RtNEF/JXhgf2RqSp3230q13E=",
|
"narHash": "sha256-DTQSMxzDWmT0zhguthvegnVkn7CFqGCv4IHCzk5ZUpM=",
|
||||||
"owner": "NixOS",
|
"owner": "nix-community",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs.lib",
|
||||||
"rev": "ef34387ddd751e1ab8857adf4676492d32eb24ec",
|
"rev": "596e2e3940e09b2abbeb03f75fa1828c57fcd72c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "NixOS",
|
"owner": "nix-community",
|
||||||
"ref": "nixos-unstable",
|
"repo": "nixpkgs.lib",
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -429,11 +432,11 @@
|
|||||||
"zapret": "zapret"
|
"zapret": "zapret"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1789400583,
|
"lastModified": 1790130850,
|
||||||
"narHash": "sha256-X7gKuUiIJOZQghNl2n7yO+XqHF0nayvrx+sXjJCFMxQ=",
|
"narHash": "sha256-k7c+KGZmNLP0ZB9jnKKJUXUTvEJC8A6kHQmZlcN8kNQ=",
|
||||||
"owner": "FUFSoB",
|
"owner": "FUFSoB",
|
||||||
"repo": "proxy-suite-flake",
|
"repo": "proxy-suite-flake",
|
||||||
"rev": "8ed4ab9a8d4650e43585e10ce51f5ffa790c4a54",
|
"rev": "8f65fa9c255e9350fb09f3d3cc9054034918bf49",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -447,6 +450,7 @@
|
|||||||
"deploy-rs": "deploy-rs",
|
"deploy-rs": "deploy-rs",
|
||||||
"disko": "disko",
|
"disko": "disko",
|
||||||
"flake-compat": "flake-compat",
|
"flake-compat": "flake-compat",
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
"grub2-themes": "grub2-themes",
|
"grub2-themes": "grub2-themes",
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
"justray": "justray",
|
"justray": "justray",
|
||||||
@@ -455,7 +459,7 @@
|
|||||||
"nix-systems": "nix-systems",
|
"nix-systems": "nix-systems",
|
||||||
"nixos-hardware": "nixos-hardware",
|
"nixos-hardware": "nixos-hardware",
|
||||||
"nixos-wsl": "nixos-wsl",
|
"nixos-wsl": "nixos-wsl",
|
||||||
"nixpkgs": "nixpkgs_2",
|
"nixpkgs": "nixpkgs",
|
||||||
"plasma-manager": "plasma-manager",
|
"plasma-manager": "plasma-manager",
|
||||||
"proxy-suite": "proxy-suite",
|
"proxy-suite": "proxy-suite",
|
||||||
"sops-nix": "sops-nix",
|
"sops-nix": "sops-nix",
|
||||||
@@ -486,11 +490,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1788914643,
|
"lastModified": 1789890976,
|
||||||
"narHash": "sha256-4GuMPW90JSxXWDPUB9M+1m7fYbe3H0apOd86/zBQ2Kw=",
|
"narHash": "sha256-GKwH3zpy7tartuJMG0Rv/xUsdetG1QLmTVv8UKgJLmA=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "sops-nix",
|
"repo": "sops-nix",
|
||||||
"rev": "13616fff713a9f94055c66f15687ebdc17a335df",
|
"rev": "7214124c20c1542c90deb54af50e2f53ae02711f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -499,24 +503,11 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"systems": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1681028828,
|
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"utils": {
|
"utils": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": "systems"
|
"systems": [
|
||||||
|
"nix-systems"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1731533236,
|
"lastModified": 1731533236,
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
|
|
||||||
# nixpkgs
|
# nixpkgs
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
# nixpkgs-last-unstable.url = "github:NixOS/nixpkgs/6b4955211758ba47fac850c040a27f23b9b4008f";
|
# nixpkgs-master.url = "github:NixOS/nixpkgs/master";
|
||||||
|
# nixpkgs-last-unstable.url = "github:NixOS/nixpkgs/3497aa5c9457a9d88d71fa93a4a8368816fbeeba";
|
||||||
# nixpkgs-fingerprint.url = "github:NixOS/nixpkgs/nixos-24.11";
|
# nixpkgs-fingerprint.url = "github:NixOS/nixpkgs/nixos-24.11";
|
||||||
|
|
||||||
# nix-community
|
# nix-community
|
||||||
@@ -36,16 +37,25 @@
|
|||||||
url = "github:luynrs/justray";
|
url = "github:luynrs/justray";
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.follows = "nixpkgs";
|
nixpkgs.follows = "nixpkgs";
|
||||||
|
flake-parts.follows = "flake-parts";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
utils.url = "github:numtide/flake-utils";
|
utils = {
|
||||||
|
url = "github:numtide/flake-utils";
|
||||||
|
# flake-utils тянет systems (nix-systems/default) сам -> наследуем корневой, чтобы не плодить дубль-узел в flake.lock
|
||||||
|
inputs.systems.follows = "nix-systems";
|
||||||
|
};
|
||||||
flake-compat.url = "github:edolstra/flake-compat";
|
flake-compat.url = "github:edolstra/flake-compat";
|
||||||
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
|
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||||
|
nixos-hardware = {
|
||||||
|
url = "github:NixOS/nixos-hardware/master";
|
||||||
|
# без follows nixos-hardware лочит свой собственный nixpkgs (две копии в lock/store)
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
nix-systems.url = "github:nix-systems/default";
|
nix-systems.url = "github:nix-systems/default";
|
||||||
# nixos-facter-modules.url = "github:numtide/nixos-facter-modules";
|
# nixos-facter-modules.url = "github:numtide/nixos-facter-modules";
|
||||||
# flake-utils.url = "github:numtide/flake-utils";
|
# flake-utils.url = "github:numtide/flake-utils";
|
||||||
# flake-parts.url = "github:hercules-ci/flake-parts";
|
|
||||||
# noctalia = {
|
# noctalia = {
|
||||||
# url = "github:noctalia-dev/noctalia-shell";
|
# url = "github:noctalia-dev/noctalia-shell";
|
||||||
# inputs.nixpkgs.follows = "nixpkgs";
|
# inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
|||||||
@@ -20,18 +20,15 @@ let
|
|||||||
"key.pem"
|
"key.pem"
|
||||||
];
|
];
|
||||||
basePorts = [
|
basePorts = [
|
||||||
# 2049/tcp — 3x-ui web panel
|
# Local-only upstreams for the 3x-ui panel and subscription endpoint.
|
||||||
# 2096/tcp — subscription endpoint
|
# The direct Xray inbound remains publicly reachable on 8443.
|
||||||
# 14380-15379/tcp+udp — Xray inbounds (matches firewall open range)
|
"127.0.0.1:2049:2049/tcp"
|
||||||
"0.0.0.0:2049:2049/tcp"
|
"127.0.0.1:2096:2096/tcp"
|
||||||
"0.0.0.0:2096:2096/tcp"
|
"0.0.0.0:8443:8443/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,
|
# VDS-only: nginx stream forwards host:443 → 127.0.0.1:15380 →
|
||||||
# so Xray inside the container sees its REALITY inbound on its real
|
# container:443, so Xray sees its REALITY inbound on port 443.
|
||||||
# configured port 443.
|
realityPorts = lib.optional xlib.services."3x-ui".reality443Forwarding "127.0.0.1:15380:443/tcp";
|
||||||
realityPorts = lib.optional xlib.services."3x-ui".reality443Forwarding "0.0.0.0:15380:443/tcp";
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
virtualisation = {
|
virtualisation = {
|
||||||
@@ -113,18 +110,6 @@ in
|
|||||||
|
|
||||||
# Enable container name DNS for all Podman networks.
|
# Enable container name DNS for all Podman networks.
|
||||||
networking.firewall = {
|
networking.firewall = {
|
||||||
allowedUDPPortRanges = [
|
|
||||||
{
|
|
||||||
from = 14380;
|
|
||||||
to = 15380;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
allowedTCPPortRanges = [
|
|
||||||
{
|
|
||||||
from = 14380;
|
|
||||||
to = 15380;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
interfaces =
|
interfaces =
|
||||||
let
|
let
|
||||||
matchAll = if !config.networking.nftables.enable then "podman+" else "podman*";
|
matchAll = if !config.networking.nftables.enable then "podman+" else "podman*";
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
JWT_SECRET=ENC[AES256_GCM,data:+ut+3v4KrckbDT5m85JhQd8x2ayF55Uy5FiEw8qTJoBgz7Zz+HprhxPB09RDd6CX11SrcsDcf6vW3wOE7IdeQA==,iv:c3GqspoQH2+2NQvsqip3bs4XW1PWSZtK+l7HzE83Qj8=,tag:hDqFgPa8gYLqPeA0svGWfw==,type:str]
|
||||||
|
ADMIN_PASSWORD=ENC[AES256_GCM,data:UxcSEO7opTme9DR4XM3/FQ==,iv:nSpFt7rVp0K+hAc3aAoorw5XDMNK0V+zeBw4GHwTsOs=,tag:fQ1u/WtlVfEhc7fZnLnboQ==,type:str]
|
||||||
|
APP_URL=ENC[AES256_GCM,data:OJAv0C1DHYbFltgXmcSG/s97Lf3qJovkcEsPA9Xr,iv:Fw9Mh/+dYgah+/OWPBtRRXkO42KXWvKIuylyXfcaRK8=,tag:a6A8xS9aRyjvEfZvSxgMuQ==,type:str]
|
||||||
|
CORS_ORIGINS=ENC[AES256_GCM,data:z4MvIbQcvk+aUaME/llV7rWaDtCFYIT0nVGtlD8j,iv:oAL5NcWOfez+vVbKoibUIOagePROKW+4QV81sK+Cets=,tag:+QftIwvmTADEFMEz+ZCh4A==,type:str]
|
||||||
|
SMTP_HOST=
|
||||||
|
SMTP_PORT=ENC[AES256_GCM,data:QnI=,iv:PQwsVoOnLmTrnpUTaQAEOX3VG2hTLm/qnZjwIOL9kac=,tag:SZxCnlr0qTxH65bZ53rvQQ==,type:str]
|
||||||
|
SMTP_USER=
|
||||||
|
SMTP_PASSWORD=
|
||||||
|
SMTP_FROM=ENC[AES256_GCM,data:TaHhXO7WVUzywpUxTr5l+IG7QfXY,iv:gLqOSZBBzC9v/BT+r+ENLjApTmLsra2jDbenJLHn4AY=,tag:HCmGtfnVIjDktQpTtUbc9A==,type:str]
|
||||||
|
NOTIFY_EMAIL=
|
||||||
|
TAPE_LABEL_REGEX=
|
||||||
|
sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnb283UjRSRU1SYjBxZWlz\nOWw2cXM2TTU2QmdWUG5nUU9vWVZhUDZoelJRCi9McmV0Q05hNVpXSllsbUYwdkEw\nTnU3OWRCcFhrQzg4blhuRFJjdDVkUFkKLS0tIEt4Nzc2ZWtOL1VQQzVObzZWYURu\nWFUwVWp5OUhDME0xVlBRS3psdVBSd0EKsy77QR7CveXQdKlo+JeNSaNpnUh//AoP\nV+hbUSIj05Ws20rr9uk8uTDnjnc91r2vxGWxznXf6M9putZfARBdfQ==\n-----END AGE ENCRYPTED FILE-----\n
|
||||||
|
sops_age__list_0__map_recipient=age13l2gtk0nzr484zprp7e0pkrt0ne0j4asyn2pjmlaw73nte7t7d8q4sqtxm
|
||||||
|
sops_lastmodified=2026-09-24T13:11:03Z
|
||||||
|
sops_mac=ENC[AES256_GCM,data:xJO2u9jQM8XiVYekVvwN+iv3megGpf80F1ANib9Kro/kgvTQUZU14jmku8OjfRtjrFsM9b/cBr+ml0Z+MSknmwtR4D3mfRIa0yFfqmS/VZJs8SrH2+c/a8kYGhDNcWgAbx+u/tZB8q0QrQsbDYmN8yvsNwWi2ixMLKlv2thPIbA=,iv:CEgU5499Gr0gD+M5iSYJ315r7RU9RWKKapXywVCQivo=,tag:9YTO7K/zsINSOXfR6PaG8A==,type:str]
|
||||||
|
sops_unencrypted_suffix=_unencrypted
|
||||||
|
sops_version=3.13.3
|
||||||
@@ -0,0 +1,188 @@
|
|||||||
|
{
|
||||||
|
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 a static IP on the shared network and the
|
||||||
|
# frontend maps "backend" → that IP via --add-host, because this host's
|
||||||
|
# CoreDNS service owns port 53 on every interface: the podman network DNS
|
||||||
|
# plugin (aardvark-dns) cannot bind on the network gateway, so a network
|
||||||
|
# with dns_enabled would refuse to attach containers.
|
||||||
|
#
|
||||||
|
# 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;
|
||||||
|
};
|
||||||
|
oci-containers = {
|
||||||
|
backend = "podman";
|
||||||
|
containers = {
|
||||||
|
"taperotation-backend" = {
|
||||||
|
image = "docker.io/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"
|
||||||
|
# Static IP the frontend reaches "backend" at (see --add-host
|
||||||
|
# in the frontend container; network DNS is disabled).
|
||||||
|
"--ip=10.89.0.10"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"taperotation-frontend" = {
|
||||||
|
image = "docker.io/elizaroveugene/taperotation-frontend:latest";
|
||||||
|
ports = [
|
||||||
|
"0.0.0.0:5174:80/tcp"
|
||||||
|
];
|
||||||
|
log-driver = "journald";
|
||||||
|
extraOptions = [
|
||||||
|
"--network=taperotation_default"
|
||||||
|
# Baked-in nginx upstream is http://backend:8001; resolve it via
|
||||||
|
# /etc/hosts since the network has no DNS plugin.
|
||||||
|
"--add-host=backend:10.89.0.10"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# 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 = ''
|
||||||
|
# Always (re)create the stack network: the host's CoreDNS owns :53
|
||||||
|
# on every interface, so the network DNS plugin (aardvark-dns)
|
||||||
|
# can't bind on the gateway → --disable-dns. --subnet backs the
|
||||||
|
# backend's static IP. Recreate-on-start also self-heals after a
|
||||||
|
# `podman system prune` removed the (temporarily unused) network.
|
||||||
|
podman network rm -f taperotation_default >/dev/null 2>&1 || true
|
||||||
|
podman network create --disable-dns --subnet=10.89.0.0/24 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 docker.io/elizaroveugene/taperotation-backend:latest
|
||||||
|
podman pull docker.io/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";
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
../containers/3x-ui.nix
|
../containers/3x-ui.nix
|
||||||
|
../containers/tape-rotation.nix
|
||||||
../pkgs/beets.nix
|
../pkgs/beets.nix
|
||||||
./acme.nix
|
./acme.nix
|
||||||
./bentopdf.nix
|
./bentopdf.nix
|
||||||
@@ -16,7 +17,6 @@
|
|||||||
./glances.nix
|
./glances.nix
|
||||||
./homebox.nix
|
./homebox.nix
|
||||||
./immich.nix
|
./immich.nix
|
||||||
# ./minecraft.nix
|
|
||||||
./miniflux.nix
|
./miniflux.nix
|
||||||
./navidrome.nix
|
./navidrome.nix
|
||||||
./nextcloud.nix
|
./nextcloud.nix
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
# ./coturn.nix
|
# ./coturn.nix
|
||||||
# ./mealie.nix
|
# ./mealie.nix
|
||||||
# ./memos.nix
|
# ./memos.nix
|
||||||
|
# ./minecraft.nix
|
||||||
# ./n8n.nix
|
# ./n8n.nix
|
||||||
# ./netdata.nix
|
# ./netdata.nix
|
||||||
# ./nfs.nix
|
# ./nfs.nix
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
};
|
};
|
||||||
nextcloud = {
|
nextcloud = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.nextcloud34;
|
package = pkgs.nextcloud35;
|
||||||
hostName = "nextcloud.private";
|
hostName = "nextcloud.private";
|
||||||
database.createLocally = true;
|
database.createLocally = true;
|
||||||
home = "${xlib.dirs.services-mnt-folder}/nextcloud";
|
home = "${xlib.dirs.services-mnt-folder}/nextcloud";
|
||||||
@@ -123,9 +123,9 @@
|
|||||||
mail
|
mail
|
||||||
music
|
music
|
||||||
notes
|
notes
|
||||||
onlyoffice
|
# onlyoffice
|
||||||
polls
|
polls
|
||||||
previewgenerator
|
# previewgenerator
|
||||||
spreed
|
spreed
|
||||||
tables
|
tables
|
||||||
tasks
|
tasks
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ let
|
|||||||
domain = "flux.zeroq.su";
|
domain = "flux.zeroq.su";
|
||||||
port = 6061;
|
port = 6061;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
domain = "tape-rotation.zeroq.su";
|
||||||
|
port = 5174;
|
||||||
|
}
|
||||||
{
|
{
|
||||||
domain = "navidrome.zeroq.su";
|
domain = "navidrome.zeroq.su";
|
||||||
port = 4533;
|
port = 4533;
|
||||||
|
|||||||
@@ -6,13 +6,13 @@
|
|||||||
xlib,
|
xlib,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
# let
|
||||||
# previous = import inputs.nixpkgs-master {
|
# previous = import inputs.nixpkgs-master {
|
||||||
# system = "x86_64-linux";
|
# system = "x86_64-linux";
|
||||||
# config.allowUnfree = true;
|
# config.allowUnfree = true;
|
||||||
# config.allowUnfreePredicate = true;
|
# config.allowUnfreePredicate = true;
|
||||||
# };
|
# };
|
||||||
in
|
# in
|
||||||
{
|
{
|
||||||
services.onlyoffice = {
|
services.onlyoffice = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|||||||
+12
-19
@@ -19,7 +19,7 @@ in
|
|||||||
unitConfig.RequiresMountsFor = [ ];
|
unitConfig.RequiresMountsFor = [ ];
|
||||||
after = [ "network-online.target" ];
|
after = [ "network-online.target" ];
|
||||||
wants = [ "network-online.target" ];
|
wants = [ "network-online.target" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
# Только по таймеру: НЕ блокируем boot и активацию nixos-rebuild.
|
||||||
script = ''
|
script = ''
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
@@ -29,31 +29,21 @@ in
|
|||||||
SSH_CMD="$SSH \
|
SSH_CMD="$SSH \
|
||||||
-o BatchMode=yes \
|
-o BatchMode=yes \
|
||||||
-o ConnectTimeout=5 \
|
-o ConnectTimeout=5 \
|
||||||
|
-o ServerAliveInterval=5 \
|
||||||
|
-o ServerAliveCountMax=3 \
|
||||||
-o StrictHostKeyChecking=no"
|
-o StrictHostKeyChecking=no"
|
||||||
|
|
||||||
echo "Waiting for server..."
|
|
||||||
|
|
||||||
for i in $(seq 1 60); do
|
|
||||||
echo "Attempt $i"
|
|
||||||
|
|
||||||
if $SSH_CMD ${serverAddress} true >/dev/null 2>&1; then
|
|
||||||
echo "Server available"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
|
|
||||||
sleep 5
|
|
||||||
done
|
|
||||||
|
|
||||||
# final check
|
|
||||||
$SSH_CMD ${serverAddress} true >/dev/null 2>&1
|
|
||||||
|
|
||||||
mkdir -p "${nodeDir}"
|
mkdir -p "${nodeDir}"
|
||||||
|
|
||||||
|
# best-effort: сервер недоступен -> выходим сразу, никаких циклов ожидания
|
||||||
|
if ! $SSH_CMD ${serverAddress} true >/dev/null 2>&1; then
|
||||||
|
echo "Server ${serverAddress} unreachable, skipping sync"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ! -d "${nodeDir}" ] || [ -z "$(ls -A "${nodeDir}")" ]; then
|
if [ ! -d "${nodeDir}" ] || [ -z "$(ls -A "${nodeDir}")" ]; then
|
||||||
echo "Pull <- ${serverAddress}"
|
echo "Pull <- ${serverAddress}"
|
||||||
|
|
||||||
mkdir -p "${nodeDir}"
|
|
||||||
|
|
||||||
$RSYNC \
|
$RSYNC \
|
||||||
-e "$SSH_CMD" \
|
-e "$SSH_CMD" \
|
||||||
-a \
|
-a \
|
||||||
@@ -77,6 +67,9 @@ in
|
|||||||
Nice = 10;
|
Nice = 10;
|
||||||
CPUQuota = "5%";
|
CPUQuota = "5%";
|
||||||
IOSchedulingClass = "idle";
|
IOSchedulingClass = "idle";
|
||||||
|
# страховка от зависшего rsync/ssh; легитимная большая синхронизация
|
||||||
|
# укладывается в это окно (на фоне idle-приоритета)
|
||||||
|
TimeoutStartSec = 600;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user