mirror of
https://github.com/oqyude/nixos.git
synced 2026-10-07 20:47:14 +03:00
Compare commits
11
Commits
72b4bdfbd8
...
a71f87b772
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a71f87b772 | ||
|
|
ac561815ed | ||
|
|
2be5b168ac | ||
|
|
eddf44fb02 | ||
|
|
caeb04142d | ||
|
|
1db2b0955b | ||
|
|
a8ddf9b8dc | ||
|
|
bc3566d80e | ||
|
|
0fdf6c965c | ||
|
|
5bccf7586d | ||
|
|
2912581b99 |
Generated
+51
-60
@@ -33,11 +33,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1781152676,
|
||||
"narHash": "sha256-RxWs5ND31KzTG7wvMM+PMfUjyNpmIEr999lqNARaM5o=",
|
||||
"lastModified": 1789770686,
|
||||
"narHash": "sha256-uZkBR7yHdIKUFB5SZdfgh1qkGfI3XmYmI/lTiquxbck=",
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"rev": "ff8702b4de27f72b4c78573dfb89ec74e36abdf1",
|
||||
"rev": "725ea35e410ad83be4931d1bff7e090eacaf3563",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -63,10 +63,7 @@
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"justray",
|
||||
"nixpkgs"
|
||||
]
|
||||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1788450739,
|
||||
@@ -109,11 +106,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1789482455,
|
||||
"narHash": "sha256-pD3qVlQ4mUCFoTWrYtxecpSitQMsgJvJIN0FUIDZoEU=",
|
||||
"lastModified": 1790128814,
|
||||
"narHash": "sha256-6Gm9q+wW3E4Ey4F6wEbJAwaMsEK6hvCYfTW7yY64ZfA=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "efa3ccb4c3cc90d832eab232976379058fa75aa3",
|
||||
"rev": "0b2f1129177f70c5f0f5d88bb53c49ca47d0bfc0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -124,17 +121,19 @@
|
||||
},
|
||||
"justray": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts",
|
||||
"flake-parts": [
|
||||
"flake-parts"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1789450388,
|
||||
"narHash": "sha256-30EGO2CUKyJ6VOJF9Zw3B5myrXRjjEmFXpkJOWC3KHI=",
|
||||
"lastModified": 1790165840,
|
||||
"narHash": "sha256-nQ3uCXiUGTLD/UtuChc2XlStYg9a33PYrkDitmmqxW8=",
|
||||
"owner": "luynrs",
|
||||
"repo": "justray",
|
||||
"rev": "cbe71cb1e71c9f29f7384e9039af4eca9af8ab3a",
|
||||
"rev": "4073f3fb223613e4d780dafad6f93b5c266061a2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -198,11 +197,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1789446796,
|
||||
"narHash": "sha256-dsgZ/cC/ZcbvAM4ZZK2USpS5e34AVo0OlBkuBvzJufQ=",
|
||||
"lastModified": 1790137578,
|
||||
"narHash": "sha256-luzO2Bo/RxUHqTPxBttSB1QVzM9Y5s+Iwpip6SjWdWo=",
|
||||
"owner": "Infinidoge",
|
||||
"repo": "nix-minecraft",
|
||||
"rev": "9552774a584b6fb0e3981f8b73372d65f36e68cf",
|
||||
"rev": "2e6a1d1ceb4da6b6ffb3980bc7993b3d057cd4db",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -256,14 +255,16 @@
|
||||
},
|
||||
"nixos-hardware": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1789417814,
|
||||
"narHash": "sha256-xV9fcqtH6jJLVBF3ocqBBwZkPKEke+BujhEwT4Ye9Tc=",
|
||||
"lastModified": 1789978172,
|
||||
"narHash": "sha256-FIRXajv1pPZ+l6On6ekkmcQ6le0Zi0ncRUoR3nB0vKA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixos-hardware",
|
||||
"rev": "d40fd26f323c898b0c195d41aa5efadd85f57832",
|
||||
"rev": "9ebcb7766700d7e006d9505247bd7ce0426f4232",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -299,15 +300,18 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1767892417,
|
||||
"narHash": "sha256-8bW3q88CEg2u4hSP66Vf4lpbLonHz7hqDNBMcCY7E9U=",
|
||||
"rev": "3497aa5c9457a9d88d71fa93a4a8368816fbeeba",
|
||||
"type": "tarball",
|
||||
"url": "https://releases.nixos.org/nixos/unstable/nixos-26.05pre924538.3497aa5c9457/nixexprs.tar.xz"
|
||||
"lastModified": 1790046670,
|
||||
"narHash": "sha256-MYiI+CzL0tuWgRPjGsKCDHqYs2T3OzMlMQWOYWG0qso=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "6774f7bc253789b113a4f39285dc0fa100abeacc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-docs": {
|
||||
@@ -342,19 +346,18 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"lastModified": 1789286504,
|
||||
"narHash": "sha256-eiEK7cKZORNEvX0GeF3RtNEF/JXhgf2RqSp3230q13E=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ef34387ddd751e1ab8857adf4676492d32eb24ec",
|
||||
"lastModified": 1788057806,
|
||||
"narHash": "sha256-DTQSMxzDWmT0zhguthvegnVkn7CFqGCv4IHCzk5ZUpM=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"rev": "596e2e3940e09b2abbeb03f75fa1828c57fcd72c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
@@ -429,11 +432,11 @@
|
||||
"zapret": "zapret"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1789400583,
|
||||
"narHash": "sha256-X7gKuUiIJOZQghNl2n7yO+XqHF0nayvrx+sXjJCFMxQ=",
|
||||
"lastModified": 1790130850,
|
||||
"narHash": "sha256-k7c+KGZmNLP0ZB9jnKKJUXUTvEJC8A6kHQmZlcN8kNQ=",
|
||||
"owner": "FUFSoB",
|
||||
"repo": "proxy-suite-flake",
|
||||
"rev": "8ed4ab9a8d4650e43585e10ce51f5ffa790c4a54",
|
||||
"rev": "8f65fa9c255e9350fb09f3d3cc9054034918bf49",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -447,6 +450,7 @@
|
||||
"deploy-rs": "deploy-rs",
|
||||
"disko": "disko",
|
||||
"flake-compat": "flake-compat",
|
||||
"flake-parts": "flake-parts",
|
||||
"grub2-themes": "grub2-themes",
|
||||
"home-manager": "home-manager",
|
||||
"justray": "justray",
|
||||
@@ -455,7 +459,7 @@
|
||||
"nix-systems": "nix-systems",
|
||||
"nixos-hardware": "nixos-hardware",
|
||||
"nixos-wsl": "nixos-wsl",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"plasma-manager": "plasma-manager",
|
||||
"proxy-suite": "proxy-suite",
|
||||
"sops-nix": "sops-nix",
|
||||
@@ -486,11 +490,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1788914643,
|
||||
"narHash": "sha256-4GuMPW90JSxXWDPUB9M+1m7fYbe3H0apOd86/zBQ2Kw=",
|
||||
"lastModified": 1789890976,
|
||||
"narHash": "sha256-GKwH3zpy7tartuJMG0Rv/xUsdetG1QLmTVv8UKgJLmA=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "13616fff713a9f94055c66f15687ebdc17a335df",
|
||||
"rev": "7214124c20c1542c90deb54af50e2f53ae02711f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -499,24 +503,11 @@
|
||||
"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": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
"systems": [
|
||||
"nix-systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
# nixpkgs
|
||||
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";
|
||||
|
||||
# nix-community
|
||||
@@ -36,16 +37,25 @@
|
||||
url = "github:luynrs/justray";
|
||||
inputs = {
|
||||
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";
|
||||
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";
|
||||
# nixos-facter-modules.url = "github:numtide/nixos-facter-modules";
|
||||
# flake-utils.url = "github:numtide/flake-utils";
|
||||
# flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
# noctalia = {
|
||||
# url = "github:noctalia-dev/noctalia-shell";
|
||||
# inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
@@ -20,18 +20,15 @@ let
|
||||
"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"
|
||||
# Local-only upstreams for the 3x-ui panel and subscription endpoint.
|
||||
# The direct Xray inbound remains publicly reachable on 8443.
|
||||
"127.0.0.1:2049:2049/tcp"
|
||||
"127.0.0.1:2096:2096/tcp"
|
||||
"0.0.0.0:8443:8443/tcp"
|
||||
];
|
||||
# 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";
|
||||
# VDS-only: nginx stream forwards host:443 → 127.0.0.1:15380 →
|
||||
# container:443, so Xray sees its REALITY inbound on port 443.
|
||||
realityPorts = lib.optional xlib.services."3x-ui".reality443Forwarding "127.0.0.1:15380:443/tcp";
|
||||
in
|
||||
{
|
||||
virtualisation = {
|
||||
@@ -113,18 +110,6 @@ in
|
||||
|
||||
# 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*";
|
||||
|
||||
@@ -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 = [
|
||||
../containers/3x-ui.nix
|
||||
../containers/tape-rotation.nix
|
||||
../pkgs/beets.nix
|
||||
./acme.nix
|
||||
./bentopdf.nix
|
||||
@@ -16,7 +17,6 @@
|
||||
./glances.nix
|
||||
./homebox.nix
|
||||
./immich.nix
|
||||
# ./minecraft.nix
|
||||
./miniflux.nix
|
||||
./navidrome.nix
|
||||
./nextcloud.nix
|
||||
@@ -33,6 +33,7 @@
|
||||
# ./coturn.nix
|
||||
# ./mealie.nix
|
||||
# ./memos.nix
|
||||
# ./minecraft.nix
|
||||
# ./n8n.nix
|
||||
# ./netdata.nix
|
||||
# ./nfs.nix
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
};
|
||||
nextcloud = {
|
||||
enable = true;
|
||||
package = pkgs.nextcloud34;
|
||||
package = pkgs.nextcloud35;
|
||||
hostName = "nextcloud.private";
|
||||
database.createLocally = true;
|
||||
home = "${xlib.dirs.services-mnt-folder}/nextcloud";
|
||||
@@ -123,9 +123,9 @@
|
||||
mail
|
||||
music
|
||||
notes
|
||||
onlyoffice
|
||||
# onlyoffice
|
||||
polls
|
||||
previewgenerator
|
||||
# previewgenerator
|
||||
spreed
|
||||
tables
|
||||
tasks
|
||||
|
||||
@@ -61,6 +61,10 @@ let
|
||||
domain = "flux.zeroq.su";
|
||||
port = 6061;
|
||||
}
|
||||
{
|
||||
domain = "tape-rotation.zeroq.su";
|
||||
port = 5174;
|
||||
}
|
||||
{
|
||||
domain = "navidrome.zeroq.su";
|
||||
port = 4533;
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
xlib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
# previous = import inputs.nixpkgs-master {
|
||||
# system = "x86_64-linux";
|
||||
# config.allowUnfree = true;
|
||||
# config.allowUnfreePredicate = true;
|
||||
# };
|
||||
in
|
||||
# let
|
||||
# previous = import inputs.nixpkgs-master {
|
||||
# system = "x86_64-linux";
|
||||
# config.allowUnfree = true;
|
||||
# config.allowUnfreePredicate = true;
|
||||
# };
|
||||
# in
|
||||
{
|
||||
services.onlyoffice = {
|
||||
enable = true;
|
||||
|
||||
+12
-19
@@ -19,7 +19,7 @@ in
|
||||
unitConfig.RequiresMountsFor = [ ];
|
||||
after = [ "network-online.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
# Только по таймеру: НЕ блокируем boot и активацию nixos-rebuild.
|
||||
script = ''
|
||||
set -euo pipefail
|
||||
|
||||
@@ -29,31 +29,21 @@ in
|
||||
SSH_CMD="$SSH \
|
||||
-o BatchMode=yes \
|
||||
-o ConnectTimeout=5 \
|
||||
-o ServerAliveInterval=5 \
|
||||
-o ServerAliveCountMax=3 \
|
||||
-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}"
|
||||
|
||||
# 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
|
||||
echo "Pull <- ${serverAddress}"
|
||||
|
||||
mkdir -p "${nodeDir}"
|
||||
|
||||
$RSYNC \
|
||||
-e "$SSH_CMD" \
|
||||
-a \
|
||||
@@ -77,6 +67,9 @@ in
|
||||
Nice = 10;
|
||||
CPUQuota = "5%";
|
||||
IOSchedulingClass = "idle";
|
||||
# страховка от зависшего rsync/ssh; легитимная большая синхронизация
|
||||
# укладывается в это окно (на фоне idle-приоритета)
|
||||
TimeoutStartSec = 600;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user