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/capabilitieson the wardrobe origin. Both internal AI capabilities should befalse. - 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.