Fork of Anyesh/wardrowbe with local-Ollama + OIDC mods
Find a file
xenarathon 4466b1a45c
All checks were successful
build-and-push / images (push) Successful in 16s
docs(readme): document fork features — calendar+sharing, styler+buy-advisor, richer tagging
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 10:39:08 -04:00
.forgejo/workflows ci: parameterize registry host/owner (vars.REGISTRY_HOST + github.repository_owner) to remove hardcoded LAN address 2026-06-20 11:05:01 -04:00
.github Merge upstream/main (wardrowbe 1.4.0) into F.A.S.C. fork 2026-07-04 11:25:51 -04:00
backend Merge feat/styler-tagging into main (B1 + Styler features) 2026-07-05 08:03:35 -04:00
docs/superpowers Merge feat/styler-tagging into main (B1 + Styler features) 2026-07-05 08:03:35 -04:00
frontend Merge feat/styler-tagging into main (B1 + Styler features) 2026-07-05 08:03:35 -04:00
k8s feat: make internal AI optional and add capabilities endpoint (#113) 2026-07-01 09:48:21 +10:00
nginx Bug/fix nextjs rewrite proxy timeouts (#65) 2026-04-29 18:48:21 +10:00
screenshots Update screenshots and reorganize README gallery 2026-02-11 18:57:05 +11:00
.env.example fix: add weather location fallbacks (#75) 2026-07-01 10:17:26 +10:00
.git-blame-ignore-revs chore: add git-blame-ignore-revs for formatting commits 2026-01-31 10:51:44 +11:00
.gitignore chore: gitignore backend test venv + throwaway test runner 2026-07-04 12:54:03 -04:00
.pre-commit-config.yaml chore: Add pre-commit hooks for lint/format enforcement 2026-01-22 19:23:16 +11:00
.release-please-manifest.json chore(main): release wardrowbe 1.4.0 2026-07-01 00:17:39 +00:00
Caddyfile.dev new(release): Initial opensource release 2026-01-20 21:12:50 +11:00
CHANGELOG.md chore(main): release wardrowbe 1.4.0 2026-07-01 00:17:39 +00:00
CONTRIBUTING.md new(release): Initial opensource release 2026-01-20 21:12:50 +11:00
docker-compose.dev.yml ci: publish Docker images to GHCR on main and releases (#83) 2026-06-12 11:22:47 +10:00
docker-compose.oidc-test.yml Fix/OIDC issues (#116) 2026-06-26 16:39:07 +10:00
docker-compose.prod.yml feat: make internal AI optional and add capabilities endpoint (#113) 2026-07-01 09:48:21 +10:00
docker-compose.yml feat: make internal AI optional and add capabilities endpoint (#113) 2026-07-01 09:48:21 +10:00
LICENSE chore(release): Add example screens 2026-01-20 21:21:26 +11:00
LOCAL-CHANGES.md docs: LOCAL-CHANGES.md — keep/drop guide for upstream syncs 2026-06-20 11:18:57 -04:00
README.md docs(readme): document fork features — calendar+sharing, styler+buy-advisor, richer tagging 2026-07-05 10:39:08 -04:00
release-please-config.json Release v1.2.0: Wash tracking, multi-image support, family outfit ratings, wear stats, and improved filtering 2026-02-06 19:07:09 +11:00
SECURITY.md new(release): Initial opensource release 2026-01-20 21:12:50 +11:00

⚙️ F.A.S.C. self-hosted fork

A lightly-patched fork of Anyesh/wardrowbe running on the F.A.S.C. homelab. It is built straight from this Forgejo repo by Forgejo Actions and deployed with DockHand — no images are built by hand.

What's different from upstream

  • Bigger clothing taxonomy — added intimates/loungewear + activewear types (bra, underwear, lingerie, pajamas, swimwear, leggings, joggers, tracksuit…) so a whole drawer stops being tagged unknown, plus a cascading category → type → subtype picker (e.g. Intimates → bra → push-up) so items are precise, not just bucketed.
  • Sharper AI input — the vision pre-processor's downscale ceiling was raised 512px → 1024px, so patterns and fabric detail survive to the model.
  • Local, private AI — vision tagging points at a self-hosted Ollama (OpenAI-compatible), and login is gated by Authentik SSO. Both are set via env vars.
  • Richer AI tagging — the tagger now also extracts cut attributes (neckline, rise, silhouette, sleeve length) that feed the styler below, with a nightly worker that backfills them onto older items.
  • Outfit Calendar + household sharing — plan outfits ahead on a week/month calendar, log what you actually wore (feeds wear stats), get an evening "what did you wear?" nudge with silent auto-confirm of planned days, and "don't repeat within N days" warnings. Households can share one closet: each item has an owner and a private toggle, with a Mine/Everyone filter to switch views.
  • Body-Type Styler + Buy-Advisor — a style profile computed from your measurements (body shape, vertical line, frame) plus an AI-drafted colour season and Kibbe lean that you review and confirm — all local AI, and body photos never leave your server. It scores your daily outfit suggestions for what flatters your shape and palette (down-ranked, never hidden) and powers a standalone styling guide. The Buy-Advisor does gap analysis on your closet to suggest what to buy (in flattering cuts/colours) with retailer search links, plus a paste-a-product-URL size finder that checks a listing's size chart against your measurements (bra/intimate sizing follows the r/ABraThatFits method).

See the project wiki for setup instructions and how-to-use guides for the calendar, sharing, styler, and buy-advisor.

How the build/deploy pipeline works
  1. Push to mainForgejo Actions runs .forgejo/workflows/build.yml.
  2. It builds the backend and frontend images and pushes them to the Forgejo container registry (e.g. your-forgejo-host/you/wardrobe-backend:latest).
  3. DockHand redeploys the stack, pulling those tags.

The CI runner mounts the host Docker socket so jobs can run docker build; the registry is reached over the LAN and whitelisted as an insecure-registries entry on the Docker host. Schema changes don't auto-migrate on startup — see the wiki's Setup page for running alembic upgrade head after a deploy.

Make it yours — personalization
  • In .forgejo/workflows/build.yml, swap the registry host your-forgejo-host:3300 and owner your-username for your own Forgejo host + username.
  • Add a repo Actions secret REGISTRY_TOKEN = a Forgejo token with write:package scope.
  • Point the app at your AI + SSO with the WARDROWBE_AI_ and WARDROWBE_OIDC_ env vars (see the Quick Start below).
  • Plain-HTTP LAN registry? Add it to the Docker daemon's insecure-registries, or front it with TLS.
  • Fill in your own measurements before running the Style Profile wizard — the shape/frame math and bra-size finder are only as good as what you enter.

Fork changes — the F.A.S.C. taxonomy/AI tweaks, the outfit calendar + household sharing, and the body-type styler + buy-advisor — were built with the help of Claude (Anthropic, Opus 4.8).


wardrowbe

wardrowbe

Put your wardrobe in rows. Snap. Organize. Wear.

Built with Claude Code Next.js FastAPI TypeScript Python

FeaturesQuick StartDeploymentArchitectureContributing

Buy Me A Coffee

Google Play - Coming Soon   App Store

Self-hosted wardrobe management with AI-powered outfit recommendations. Take photos of your clothes, let AI tag them, and get daily outfit suggestions based on weather and occasion.

Features

  • Photo-based wardrobe - Upload photos, AI extracts clothing details automatically
  • Smart recommendations - Outfits matched to weather, occasion, and your preferences
  • Scheduled notifications - Daily outfit suggestions via ntfy/Mattermost/email
  • Family support - Manage wardrobes for household members
  • Wear tracking - History, ratings, and outfit feedback
  • Analytics - See what you wear, what you don't, color distribution
  • Fully self-hosted - Your data stays on your hardware
  • Works with any AI - OpenAI, Ollama, LocalAI, or any OpenAI-compatible API

Screenshots

Wardrobe & Item Details

Grid View Item Details & AI Analysis
Wardrobe Item Details

Wash Tracking & Outfit Suggestions

Wash Tracking Suggestions
Wash Tracking Suggest

History & Analytics

History Calendar Analytics
History Analytics

Pairings

Pairing View Pairing Modal
Pairing Pairing Modal

Quick Start

Prerequisites

  • Docker and Docker Compose installed
  • At least 4GB of RAM available
  • An AI service (Ollama recommended for free local AI, or OpenAI API key)

Setup

Step 1: Install Ollama (if using local AI)

Option A: Using Ollama (Recommended - Free, runs locally)

# Install Ollama from https://ollama.ai
# Then pull required models:
ollama pull gemma3        # Multimodel LLM (for image analysis and outfit recommendations)

# Verify it's running:
curl http://localhost:11434/api/tags

Option B: Using OpenAI (Paid API)

Get your API key from https://platform.openai.com/api-keys

Step 2: Clone and Configure

# Clone the repository
git clone https://github.com/yourusername/wardrowbe.git
cd wardrowbe

# Copy environment template
cp .env.example .env

# IMPORTANT: Edit .env and configure AI settings
# For Ollama (default in .env.example):
#   AI_BASE_URL=http://host.docker.internal:11434/v1
#   AI_VISION_MODEL=gemma3:latest
#   AI_TEXT_MODEL=gemma3:latest
#
# For OpenAI, uncomment and set:
#   AI_BASE_URL=https://api.openai.com/v1
#   AI_API_KEY=sk-your-api-key-here
#   AI_VISION_MODEL=gpt-4o
#   AI_TEXT_MODEL=gpt-4o

# Optional: Generate secure secrets for production
# SECRET_KEY=$(openssl rand -hex 32)
# NEXTAUTH_SECRET=$(openssl rand -hex 32)

Step 3: Start Services

docker-compose.yml pulls pre-built multi-arch images (linux/amd64 and linux/arm64, so Raspberry Pi and other ARM hosts work) from GitHub Container Registry. No local build tooling is required on the host.

# Pull the latest published images, then start all containers
docker compose pull
docker compose up -d

# Wait for services to be healthy (30 seconds)
docker compose ps

# Run database migrations (REQUIRED)
docker compose exec backend alembic upgrade head

# Verify everything is working
curl http://localhost:8000/api/v1/health
# Should return: {"status":"healthy"}

To build the images from source instead of pulling them, use the development stack below (docker-compose.dev.yml), which builds locally and enables hot reload.

Step 4: Access the App

Development Mode

For hot reloading during development (auto-rebuilds on code changes):

# Start in dev mode
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d

# Run migrations (first time only)
docker compose exec backend alembic upgrade head

# View logs
docker compose logs -f frontend backend

AI Configuration

Wardrowbe works with any OpenAI-compatible API. You need two types of models:

  • Vision model: Analyzes clothing images to extract colors, patterns, styles
  • Text model: Generates outfit recommendations and descriptions

Running without internal AI

Internal AI is optional. Set AI_INTERNAL_ENABLED=false to run the backend with no internal AI provider at all — it boots and serves without AI_BASE_URL, AI_API_KEY, or model names configured, and defers tagging/suggestions/pairings to an external agent. You can also disable a single capability with AI_VISION_ENABLED=false (auto-tagging) or AI_TEXT_ENABLED=false (suggestions/pairings); unset switches inherit the master. The effective state is reported at GET /api/v1/capabilities. Defaults keep internal AI on, so existing deployments are unaffected.

Free, runs locally, no API key needed, works offline

  1. Install Ollama

  2. Pull models:

    ollama pull gemma3:latest  # multimodel LLM (3.4GB) - analyze images and generates recommendations
    
    # Alternative text models you can use:
    # ollama pull llama3:latest     # Good all-around model
    # ollama pull qwen2.5:latest    # Fast and efficient
    # ollama pull mistral:latest    # Great for creative text
    
  3. Configure in .env:

    AI_BASE_URL=http://host.docker.internal:11434/v1
    AI_API_KEY=not-needed
    AI_VISION_MODEL=gemma3:latest
    AI_TEXT_MODEL=gemma3:latest
    

Note: Use host.docker.internal instead of localhost so Docker containers can reach your host's Ollama.

Using OpenAI

Paid API, requires internet connection

  1. Get API key from https://platform.openai.com/api-keys
  2. Configure in .env:
    AI_BASE_URL=https://api.openai.com/v1
    AI_API_KEY=sk-your-api-key-here
    AI_VISION_MODEL=gpt-4o
    AI_TEXT_MODEL=gpt-4o
    

Using LocalAI

Self-hosted OpenAI alternative

AI_BASE_URL=http://localai:8080/v1
AI_API_KEY=not-needed
AI_VISION_MODEL=gpt-4-vision-preview
AI_TEXT_MODEL=gpt-3.5-turbo

Using Multimodal Models

Some models can handle both vision and text (like qwen2-vl, llama3.2-vision):

AI_VISION_MODEL=llama3.2-vision:11b
AI_TEXT_MODEL=llama3.2-vision:11b  # Same model for both tasks

Architecture

┌─────────────────────────────────────────────────────────────┐
│                        Frontend                              │
│                   (Next.js + React Query)                    │
└─────────────────────────┬───────────────────────────────────┘
                          │
┌─────────────────────────▼───────────────────────────────────┐
│                        Backend                               │
│                   (FastAPI + SQLAlchemy)                     │
└──────────┬──────────────┬──────────────────┬────────────────┘
           │              │                  │
    ┌──────▼──────┐ ┌─────▼─────┐    ┌──────▼──────┐
    │  PostgreSQL │ │   Redis   │    │  AI Service │
    │  (Database) │ │ (Job Queue)│   │ (OpenAI/etc)│
    └─────────────┘ └─────┬─────┘    └─────────────┘
                          │
               ┌──────────▼──────────┐
               │   Background Worker │
               │    (arq - AI Jobs)  │
               └─────────────────────┘

Tech Stack

Layer Technology
Frontend Next.js 14, TypeScript, TanStack Query, Tailwind CSS, shadcn/ui
Backend FastAPI, SQLAlchemy (async), Pydantic, Python 3.11+
Database PostgreSQL 15
Cache/Queue Redis 7
Background Jobs arq
Authentication NextAuth.js (supports OIDC, dev credentials)
AI Any OpenAI-compatible API

Deployment

Docker Compose (Production)

See docker-compose.prod.yml for production configuration. Like the default stack, it pulls pre-built images from GHCR rather than building on the host.

docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d
docker compose exec backend alembic upgrade head

Images are tagged backend-latest / frontend-latest, and each release also publishes backend-<version> / frontend-<version> (e.g. backend-1.3.0). To pin a deployment to a specific release, replace the -latest tags in the compose file with the version, e.g. ghcr.io/anyesh/wardrowbe:backend-1.3.0.

Kubernetes

See the k8s/ directory for Kubernetes manifests including:

  • PostgreSQL and Redis with persistent storage
  • Backend API and worker deployments
  • Next.js frontend
  • Ingress with TLS
  • Network policies

Configuration

Environment Variables

Variable Description Required
DATABASE_URL PostgreSQL connection string Yes
SECRET_KEY Backend secret for JWT Yes
NEXTAUTH_SECRET NextAuth session encryption Yes
AI_BASE_URL AI service URL Yes
AI_API_KEY AI API key (if required) Depends
OIDC_ISSUER_URL OIDC provider URL (enables SSO login) No
OIDC_CLIENT_ID OIDC client ID If OIDC
OIDC_CLIENT_SECRET OIDC client secret If OIDC
OIDC_SKIP_SSL_VERIFY Skip TLS verification for OIDC provider (self-signed certs) No
LOCAL_DNS Custom DNS server for container name resolution (e.g. local OIDC host) No
SMTP_HOST SMTP server for email notifications No
SMTP_PORT SMTP port (default: 587) No
SMTP_USER SMTP username No
SMTP_PASSWORD SMTP password No
BG_REMOVAL_PROVIDER Background removal backend: rembg or http (default: rembg) No
BG_REMOVAL_MODEL rembg model name (default: u2net) No
BG_REMOVAL_URL URL for HTTP bg removal provider If http
BG_REMOVAL_API_KEY API key for HTTP bg removal provider No
NEXT_PUBLIC_ENABLE_IP_LOCATION_FALLBACK Enable IP-based approximate location when browser geolocation is denied/unavailable. Off by default (sends the user's IP to a third party). Set to true to enable No
NEXT_PUBLIC_NETWORK_LOCATION_URL Override the IP geolocation provider (default: https://ipapi.co/json/). Only used when the fallback above is enabled No

See .env.example for all options.

Location Detection (Privacy Note)

The Settings page can fill in your coordinates from the browser's Geolocation API. If that is denied or unavailable, an optional fallback can approximate your location from your IP address via a third-party service (ipapi.co by default). This fallback is disabled by default because it sends the user's IP to an external provider; enable it with NEXT_PUBLIC_ENABLE_IP_LOCATION_FALLBACK=true and optionally point NEXT_PUBLIC_NETWORK_LOCATION_URL at a provider you trust. These are build-time frontend variables, so set them before building the frontend image. Geocoding a location name you type yourself still uses OpenStreetMap Nominatim regardless of this setting.

Background Removal (Optional)

Remove image backgrounds from wardrobe items. Two backends supported:

rembg (local, default):

pip install rembg[cpu]  # add to your image, or install manually

No config needed — works out of the box. Change model with BG_REMOVAL_MODEL (default: u2net, options: isnet-general-use, silueta, u2netp).

HTTP provider (e.g. withoutbg):

BG_REMOVAL_PROVIDER=http
BG_REMOVAL_URL=http://withoutbg:5000
BG_REMOVAL_API_KEY=          # optional

If neither is configured, the remove-background button returns a 501 with setup instructions.

Authentication

  • Development Mode (default): Simple email/name login, no setup required
  • OIDC Mode: Any OIDC provider (PocketID, Authentik, Keycloak, Auth0, etc.)

To enable OIDC, set OIDC_ISSUER_URL, OIDC_CLIENT_ID, and OIDC_CLIENT_SECRET in your .env. If your OIDC provider uses a self-signed certificate, set OIDC_SKIP_SSL_VERIFY=true. If your OIDC provider runs on a hostname that Docker containers can't resolve (e.g. a local DNS name), set LOCAL_DNS to your DNS server IP, or set OIDC_HOST and OIDC_HOST_IP to inject the hostname directly into the container's /etc/hosts.

When registering the app in your OIDC provider, use this as the callback/redirect URI:

{NEXTAUTH_URL}/api/auth/callback/oidc

For example, if NEXTAUTH_URL=http://localhost:8080, the callback URL is:

http://localhost:8080/api/auth/callback/oidc

Notifications

  • ntfy.sh: Free push notifications
  • Email: SMTP-based (set SMTP_HOST, SMTP_USER, SMTP_PASSWORD in .env)

Weather

Uses Open-Meteo - free, no API key needed.

Development

Backend

# Run tests (requires running containers)
docker compose exec backend python -m pytest tests/ -v --tb=short

# Run a specific test file
docker compose exec backend python -m pytest tests/test_notification_workers.py -v

# Lint
pip install ruff
ruff check --fix backend/app/ && ruff format backend/app/

Frontend

cd frontend
npm install

# Run dev server
npm run dev

# Run tests
npm test

# Build
npm run build

API Documentation

Available when running:

Troubleshooting

Build Fails with TypeScript Errors

# Check for type errors
cd frontend
npm install
npx tsc --noEmit

# If you see errors, please report them as a bug

Frontend Shows "500 Internal Server Error" or Won't Load

# 1. Check all services are healthy
docker compose ps

# 2. Check backend is responding
curl http://localhost:8000/api/v1/health

# 3. Verify migrations ran successfully
docker compose exec backend alembic current

# 4. Check logs for errors
docker compose logs backend frontend --tail=50

# 5. If migrations failed, run them manually
docker compose exec backend alembic upgrade head

AI Features Not Working / Images Not Being Analyzed

# For Ollama users:
# 1. Verify Ollama is running and accessible
curl http://localhost:11434/api/tags
# Should show your installed models

# 2. Check you have the vision model
ollama list | grep gemma

# 3. Verify .env has correct configuration
cat .env | grep AI_

# 4. Check worker logs for AI errors
docker compose logs worker --tail=50

# For OpenAI users:
# 1. Verify API key is valid
curl https://api.openai.com/v1/models \
  -H "Authorization: Bearer $AI_API_KEY"

# 2. Check you have credits remaining in your account

Development Mode Fails to Start

# 1. Ensure you're using the dev compose file
docker compose -f docker-compose.yml -f docker-compose.dev.yml down
docker compose -f docker-compose.yml -f docker-compose.dev.yml build frontend
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d

# 2. Check frontend logs
docker compose logs frontend -f

# Alternative: Run frontend locally for development
cd frontend
npm install
npm run dev
# Then access at http://localhost:3000

Port Already in Use

# Check what's using the ports
sudo lsof -i :3000  # Frontend
sudo lsof -i :8000  # Backend
sudo lsof -i :5432  # PostgreSQL
sudo lsof -i :6379  # Redis

# Stop conflicting services or change ports in .env

Database Migration Errors

# Check current migration version
docker compose exec backend alembic current

# View migration history
docker compose exec backend alembic history

# If migrations are corrupted, reset (WARNING: Deletes all data!)
docker compose down -v
docker compose up -d
sleep 10
docker compose exec backend alembic upgrade head

Container Keeps Restarting

# Check container logs
docker compose logs <service-name> --tail=100

# Common issues:
# - Database not ready: Wait 30 seconds and retry
# - Out of memory: Increase Docker memory limit
# - Permission errors: Check file permissions on volumes

Performance Issues / Slow Response

# Check resource usage
docker stats

# If backend is slow:
# 1. Check PostgreSQL performance
docker compose exec postgres psql -U wardrobe -c "SELECT * FROM pg_stat_activity;"

# 2. Check Redis connection
docker compose exec redis redis-cli ping

# If AI analysis is slow:
# - For Ollama: Use smaller quantized models
# - For OpenAI: Check your rate limits

Getting Help

If you're still stuck:

  1. Check existing GitHub Issues
  2. Search Discussions
  3. Create a new issue with:
    • Output of docker compose ps
    • Relevant logs from docker compose logs
    • Your .env configuration (redact secrets!)
    • Steps to reproduce the problem

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

Star History

Star History Chart

Support

If you find wardrowbe useful, consider supporting its development:

Buy Me A Coffee

License

This project is licensed under the MIT License - see the LICENSE file for details.

Requirements

  • Docker & Docker Compose
  • ~4GB RAM (with local Ollama models)
  • Storage for clothing photos

Works great on a Raspberry Pi 5!