Compare commits

..
11 Commits
Author SHA1 Message Date
oqyude a71f87b772 hide ports 2026-09-25 15:38:07 +03:00
oqyude ac561815ed 3x-ui fix 2026-09-24 22:49:52 +03:00
oqyudeandSisyphus 2be5b168ac tape-rotation fix
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-24 17:21:58 +03:00
oqyude eddf44fb02 tape-rotation res 2026-09-24 15:38:24 +03:00
oqyude caeb04142d onlyoffice regress 2026-09-23 23:17:39 +03:00
oqyude 1db2b0955b nextcloud fix 2026-09-23 22:23:13 +03:00
oqyude a8ddf9b8dc changes 2026-09-23 22:16:04 +03:00
oqyude bc3566d80e nextcloud35 2026-09-23 22:14:08 +03:00
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
10 changed files with 306 additions and 117 deletions
Generated
+51 -60
View File
@@ -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,
+14 -4
View File
@@ -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";
+8 -23
View File
@@ -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
+188
View File
@@ -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";
};
}
+2 -1
View File
@@ -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
+3 -3
View File
@@ -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
+4
View File
@@ -61,6 +61,10 @@ let
domain = "flux.zeroq.su";
port = 6061;
}
{
domain = "tape-rotation.zeroq.su";
port = 5174;
}
{
domain = "navidrome.zeroq.su";
port = 4533;
+7 -7
View File
@@ -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
View File
@@ -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;
};
};
};