Compare commits

...
3 Commits
Author SHA1 Message Date
oqyude f0947f3ce0 3x 2026-09-24 22:11:23 +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
4 changed files with 56 additions and 32 deletions
+24 -12
View File
@@ -25,8 +25,12 @@ let
# 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"
"0.0.0.0:8443:8443/tcp"
"0.0.0.0:8443:8443/udp"
"0.0.0.0:18443:18443/tcp"
"0.0.0.0:18443:18443/udp"
# "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
@@ -113,17 +117,25 @@ in
# Enable container name DNS for all Podman networks.
networking.firewall = {
allowedUDPPortRanges = [
{
from = 14380;
to = 15380;
}
# allowedUDPPortRanges = [
# {
# from = 8443;
# to = 15380;
# }
# ];
# allowedTCPPortRanges = [
# {
# from = 14380;
# to = 15380;
# }
# ];
allowedUDPPorts = [
18443
8443
];
allowedTCPPortRanges = [
{
from = 14380;
to = 15380;
}
allowedTCPPorts = [
18443
8443
];
interfaces =
let
+9 -9
View File
@@ -1,17 +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]
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:LCQ=,iv:WLAbIdlHOj3rewluMXWVzilqvDSV/AJWSCX2r1aKs20=,tag:4Epi95JuDt+hpK5SrgZ/Eg==,type:str]
SMTP_PORT=ENC[AES256_GCM,data:QnI=,iv:PQwsVoOnLmTrnpUTaQAEOX3VG2hTLm/qnZjwIOL9kac=,tag:SZxCnlr0qTxH65bZ53rvQQ==,type:str]
SMTP_USER=
SMTP_PASSWORD=
SMTP_FROM=ENC[AES256_GCM,data:ojS087+VQNecRLOgkiwDooR53SV3,iv:kGpy74EoXEDGnyo706MEJd2JY5FpJmN9Gy6+f7jOwBM=,tag:FaeLO08Prlk8cC84QFpWLw==,type:str]
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+IFgyNTUxOSBsSUtSTnJtWHo3WXZWME4r\nNU51dk1rb3NmN3lFT1BMc3E1eVBOTDJUNlZrCkJBT2w2dkpXeEgvMWhWcGVNME8w\nSDZ1ekpUTmxJV0kyb2UrRC9XUTBiUFkKLS0tIGx2MCtxcG9lYjY0dmU4Wld4eEND\neFRRNUd3Rm9iYUg2dWh5elFEaW9wZUUKCvTvSHheiciexXbNXNAI9oioTHUSvreX\nIdOHyjfBfcjgfVIMrp5HQkQCC6labOHRcYgmT4WRkXJ11uTLvgLu1Q==\n-----END AGE ENCRYPTED FILE-----\n
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-23T18:58:25Z
sops_mac=ENC[AES256_GCM,data:iLT3sVq0aV+UEztCdnbTBZraER3kXtksEOHl6AaiINTU6BHM0gTmpn5GdjbJykZDJweYdKVk6vYLB+k8JS33hWS9EoPUtme+FIGkbY6duMGpbVP/DZ5rqol1R+ihChfjmsXpnleVY6kWfnt67CH7LrP2HnsQj5njLF/3Qa4DMe8=,iv:yl8HB2E2Dm5LL1B7eLXXXTxJmEOp6HFvgIb3Ah+zVFg=,tag:iKTWq136tkMDgT4aFqGzmQ==,type:str]
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
+22 -10
View File
@@ -15,8 +15,11 @@
# 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.
# 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
@@ -41,13 +44,12 @@ in
flags = [ "--all" ];
};
dockerCompat = true;
defaultNetwork.settings.dns_enabled = true;
};
oci-containers = {
backend = "podman";
containers = {
"taperotation-backend" = {
image = "elizaroveugene/taperotation-backend:latest";
image = "docker.io/elizaroveugene/taperotation-backend:latest";
environment = {
"DATABASE_URL" = "sqlite:////data/taperotation.db";
"JWT_EXPIRE_MINUTES" = "480";
@@ -64,18 +66,22 @@ in
log-driver = "journald";
extraOptions = [
"--network=taperotation_default"
# frontend nginx proxies /api to http://backend:8001
"--network-alias=backend"
# 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 = "elizaroveugene/taperotation-frontend:latest";
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"
];
};
};
@@ -118,7 +124,13 @@ in
ExecStop = "podman network rm -f taperotation_default";
};
script = ''
podman network inspect taperotation_default || podman network create taperotation_default
# 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" ];
@@ -130,8 +142,8 @@ in
TimeoutSec = 300;
};
script = ''
podman pull elizaroveugene/taperotation-backend:latest
podman pull elizaroveugene/taperotation-frontend:latest
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
'';
};
+1 -1
View File
@@ -6,7 +6,7 @@
{
imports = [
../containers/3x-ui.nix
# ../containers/tape-rotation.nix
../containers/tape-rotation.nix
../pkgs/beets.nix
./acme.nix
./bentopdf.nix