diff --git a/modules/containers/secrets/tape-rotation.env b/modules/containers/secrets/tape-rotation.env index 9eb8be1..09e3b8f 100644 --- a/modules/containers/secrets/tape-rotation.env +++ b/modules/containers/secrets/tape-rotation.env @@ -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 diff --git a/modules/containers/tape-rotation.nix b/modules/containers/tape-rotation.nix index 888f002..0c8266a 100644 --- a/modules/containers/tape-rotation.nix +++ b/modules/containers/tape-rotation.nix @@ -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 ''; };