Files
2026-10-10 15:58:44 +02:00

6.8 KiB

Wardrowbe on Orion

Wardrowbe is served through the existing Caddy instance. The capability owns container images, routing, runtime secret templates and startup ordering. Image references and settings live in default.nix; endpoints live in the shared service facts.

Internal AI is disabled. Upload clothes and enter tags manually; automatic tagging and AI outfit generation are unavailable. Local rotation and background removal remain available. No AI provider key or notification provider is configured.

Tinyauth provides a cookie-based password gateway. After authenticating there, Wardrowbe's development login accepts an email/name to select a profile. Use a consistent email for each person. This is for a trusted household: gateway users can select one another's profiles. It is not verified individual identity.

Provision before building or activating Orion

Add these top-level keys with sops edit modules/secrets/secrets.yaml, using the existing system-secret recipients. The keys are deliberately not provisioned by the configuration change; Orion's SOPS build checks require them to exist.

Key Value
wardrowbe-postgres-password A new 64-character hexadecimal password
wardrowbe-secret-key A separate new 64-character hexadecimal signing secret
wardrowbe-nextauth-secret A separate new 64-character hexadecimal session secret
wardrowbe-auth-users A single-line kiri:bcrypt-hash string

Generate each of the first three separately with openssl rand -hex 32. If OpenSSL is unavailable, use nix run --quiet nixpkgs#openssl -- rand -hex 32. Keep values inside the encrypted document; do not paste them into Nix or chat. Hexadecimal database passwords work directly in the application's connection URL.

On a workstation with Podman, create the gateway user interactively:

podman run --rm -it ghcr.io/tinyauthapp/tinyauth:v5.2.0@sha256:220aa235c76393a73fece831d7ba967b8698d3907fd8e3c4c952f699c7b142a5 user create --interactive

Choose username kiri and your password, and answer No to Docker formatting. Put the emitted username:hash string in wardrowbe-auth-users as a quoted YAML scalar. Additional gateway accounts can be added as a comma-separated list on the same line. If Podman is unavailable, prefix its arguments with nix run --quiet nixpkgs#podman -- instead of podman. This command only creates a hash; gateway sessions persist separately on Orion.

Create DNS records for wardrobe.jelles.net and wardrobe-auth.jelles.net pointing at Orion. Publish an AAAA record only if Orion has working public IPv6. Existing Caddy firewall access supplies HTTP/HTTPS and automatic certificates.

The private container network reserves 10.89.30.0/24, with gateway 10.89.30.1. It must not overlap Orion's routes. If changing it, update both the network declaration and Tinyauth's trusted-proxy address before first activation.

Add new source files to Git before using a Git-backed flake. From this repository, activate explicitly:

nixos-rebuild switch --quiet --target-host orion --sudo --flake .#orion

The initial activation downloads container images, including the image-processing model. Allow time and disk space for those downloads. Containers start on boot; PostgreSQL and Redis become healthy before the backend runs alembic upgrade head. The frontend and workers wait for the backend's health check. A failed migration prevents the API from starting. Each container has a 15-minute startup deadline.

Operation

Run these commands on Orion. Container names and unit names correspond directly to the declarations in default.nix:

sudo systemctl status podman-wardrowbe-backend.service
sudo journalctl -u podman-wardrowbe-backend.service -n 80 --no-pager
sudo podman ps --filter name=wardrowbe
sudo podman volume ls --filter name=wardrowbe

Persistent named volumes contain PostgreSQL, Redis's append-only queue, uploaded images and Tinyauth's SQLite sessions. They are root-owned Podman state under /var/lib/containers/storage/volumes, outside Nix. Container recreation and system rollback preserve these volumes; do not remove them or prune volumes. The network is also retained when services stop.

Only Caddy serves public traffic. Frontend, backend and gateway host ports bind to localhost; database and queue ports remain inside the container network. Every Wardrowbe route, including API and signed image URLs, passes through the gateway. The gateway's own login endpoint is public. Gateway cookies are secure, HTTP-only and scoped to jelles.net to support redirects between the two subdomains.

SOPS renders root-only mode-0400 environment files at activation. Changes to their contents restart the consuming containers. Rotating session secrets signs users out. Changing POSTGRES_PASSWORD alone does not change an existing database role's password: coordinate the database password change with the encrypted value.

Upgrade and recovery

Review upstream release notes and migrations, then update the image tags and manifest digests together. Upgrade backend and frontend to the same release; workers use the backend image. Image updates happen through explicit configuration activation, with no automatic image updater. Review resource requirements before enabling AI later.

If startup fails, inspect the failing container unit's journal. After correcting the cause, start the affected units and any dependents whose startup was blocked. To restart the complete application in dependency order:

sudo systemctl restart podman-wardrowbe-postgres.service podman-wardrowbe-redis.service podman-wardrowbe-backend.service podman-wardrowbe-worker.service podman-wardrowbe-image-worker.service podman-wardrowbe-frontend.service podman-wardrowbe-auth.service

Reverting a NixOS generation restores configuration and image references, not database schema changes. Do not assume an older application can use a migrated database; follow upstream recovery guidance. No backup system is added here.

Manual acceptance after activation

  • Open the wardrobe in a private browser window. It should require the gateway password; unauthenticated API and image requests should also be blocked.
  • Authenticate, select a Wardrowbe profile, complete onboarding and upload a photo. Add tags manually and confirm the photo renders; try a rotation.
  • With the gateway session active, open /api/v1/capabilities on the wardrobe origin. Both internal AI capabilities should be false.
  • Restart the application and confirm the profile, photo and tags remain present.
  • Check that both public hostnames have valid HTTPS certificates and that the existing Orion web services still work.

No tests, builds, activation or browser acceptance checks were performed while preparing this capability.