|
All checks were successful
build-and-push / images (push) Successful in 16s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|---|---|---|
| .forgejo/workflows | ||
| .github | ||
| backend | ||
| docs/superpowers | ||
| frontend | ||
| k8s | ||
| nginx | ||
| screenshots | ||
| .env.example | ||
| .git-blame-ignore-revs | ||
| .gitignore | ||
| .pre-commit-config.yaml | ||
| .release-please-manifest.json | ||
| Caddyfile.dev | ||
| CHANGELOG.md | ||
| CONTRIBUTING.md | ||
| docker-compose.dev.yml | ||
| docker-compose.oidc-test.yml | ||
| docker-compose.prod.yml | ||
| docker-compose.yml | ||
| LICENSE | ||
| LOCAL-CHANGES.md | ||
| README.md | ||
| release-please-config.json | ||
| SECURITY.md | ||
⚙️ F.A.S.C. self-hosted fork
A lightly-patched fork of
Anyesh/wardrowberunning 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
- Push to
main→ Forgejo Actions runs.forgejo/workflows/build.yml.- It builds the backend and frontend images and pushes them to the Forgejo container registry (e.g.
your-forgejo-host/you/wardrobe-backend:latest).- 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 aninsecure-registriesentry on the Docker host. Schema changes don't auto-migrate on startup — see the wiki's Setup page for runningalembic upgrade headafter a deploy.Make it yours — personalization
- In
.forgejo/workflows/build.yml, swap the registry hostyour-forgejo-host:3300and owneryour-usernamefor your own Forgejo host + username.- Add a repo Actions secret
REGISTRY_TOKEN= a Forgejo token withwrite:packagescope.- Point the app at your AI + SSO with the
WARDROWBE_AI_andWARDROWBE_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
Put your wardrobe in rows. Snap. Organize. Wear.
Features • Quick Start • Deployment • Architecture • Contributing
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 |
|---|---|
![]() |
![]() |
Wash Tracking & Outfit Suggestions
| Wash Tracking | Suggestions |
|---|---|
![]() |
![]() |
History & Analytics
| History Calendar | Analytics |
|---|---|
![]() |
![]() |
Pairings
| Pairing View | 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
- Frontend: http://localhost:3000
- API Docs: http://localhost:8000/docs
- Login: Click "Login" - uses dev credentials by default (no password needed)
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.
Using Ollama (Recommended for Self-Hosting)
Free, runs locally, no API key needed, works offline
-
Install Ollama
-
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 -
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
- Get API key from https://platform.openai.com/api-keys
- 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_PASSWORDin.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:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
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:
- Check existing GitHub Issues
- Search Discussions
- 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
- Output of
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
Star History
Support
If you find wardrowbe useful, consider supporting its development:
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!







