A web-based simulation game where you manage a vault full of dwellers, balancing their needs and resources to keep the vault thriving. Built with modern Python tooling.
- Pydantic + PydanticAI β the validation layer and the AI agent runtime behind chat, dwellers, and visual attributes.
- astral.sh toolchain β uv for projects and dependencies, ruff for lint and format, ty for type checking.
- VoidZero toolchain β Vite+ (
vp: Vite, Vitest, Oxfmt) with Oxlint and Rolldown on the Oxc parser.
See docs/ROADMAP.md for recent updates and upcoming features.
Keywords: fallout shelter, vault management, simulation game, python, fastapi, vue, typescript, postgresql, redis
Backend: FastAPI Β· SQLModel Β· PostgreSQL 18 Β· Redis Β· PydanticAI Frontend: Vue 3.5 Β· TypeScript Β· Vite Β· Pinia Β· TailwindCSS v4 Β· Vitest Tooling: uv Β· ruff Β· Rolldown Β· Oxlint Β· Docker/Podman
Required:
- Python 3.12+ (3.13 recommended)
- Node.js 22 LTS
- Docker Compose (v2 - use
docker compose, notdocker-compose)
Installation:
- uv (Python package manager):
- macOS/Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh - Windows:
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
- macOS/Linux:
- pnpm (via Corepack):
corepack enable && corepack use pnpm@11.9.0
Recommended setup: Run infrastructure in Docker; run backend + frontend locally for hot reload.
Open the repository in Zed and run these project tasks in order from
task: spawn: Fallout: Run Podman infrastructure, Fallout: Run backend server, and Fallout: Run frontend server. Each opens its own terminal, like
separate PyCharm run configurations. The backend task applies migrations before
starting FastAPI. Run Fallout: Stop Podman infrastructure to stop the
containers.
# 1. Clone and setup environment
git clone https://github.com/ElderEvil/falloutProject && cd falloutProject
cp .env.example .env # Edit with your settings (keep localhost hostnames)
# 2. Start infrastructure services (PostgreSQL, Redis, Mailpit for local dev email)
docker compose -f docker-compose.infra.yml up -d
# 3. Setup and run backend (http://localhost:8000)
cd backend
cp ../.env .env
uv sync --dev
uv run alembic upgrade head
uv run fastapi dev main.py
# 4. Setup and run frontend (http://localhost:5173)
# β οΈ IMPORTANT: Backend API must be accessible at http://localhost:8000
cd ../frontend
pnpm install
pnpm run devVerify everything works:
# Backend health check
curl -sf http://localhost:8000/healthcheck
# Frontend (open in browser)
# Windows (PowerShell): Start-Process http://localhost:5173
# Mac: open http://localhost:5173
# Linux: xdg-open http://localhost:5173Optional: Ollama for Local AI (Hybrid Mode)
# Install Ollama: https://ollama.ai/download
# Pull a model (run once):
ollama pull llama2
# Ollama runs as service after install (http://localhost:11434)
# Update .env: AI_PROVIDER=ollamaPlatform Notes:
- Windows: Use PowerShell, Git Bash, or WSL2. Commands work identically.
- Mac/Linux: All commands work as-is in Terminal.
- First run: Backend will create database schema automatically via migrations
Run everything in containers (no local Node/Python needed):
# 1. Clone and setup environment
git clone https://github.com/ElderEvil/falloutProject && cd falloutProject
cp .env.example .env # Edit SECRET_KEY, passwords, API keys as needed
# 2. Start all services (environment overrides handled automatically)
docker compose up -d
# 3. Wait for services to be ready (30-60 seconds)
docker compose logs -f fastapi # Watch startup (Ctrl+C to exit)Access:
- Frontend: http://localhost:3000
- Backend API: http://localhost:8000/docs (Swagger UI)
- Mailpit (local dev email only; no real emails): http://localhost:8025. For production real email (verification, password reset), see the Mailcow-on-Hetzner setup in docs/DEPLOYMENT.md.
Notes:
- No need to edit hostnames in
.env- Docker Compose automatically overrides them - First build takes 5-10 minutes (downloads images + builds backend/frontend)
- Subsequent starts are fast (~30 seconds)
cd backend
uv sync --dev && prek install
uv run pytest app/tests/ # Run tests
uv run ruff check . && uv run ruff format . # Lint & format
uv run alembic upgrade head # MigrationsTimestamp convention: store and compare timestamps as naive UTC (datetime.utcnow()), with the DB connection pinned to UTC.
AI prompt updates: Prompt instructions are immutable versions. From backend/, create and activate a replacement with
uv run fo-cli version-prompt <name> --template-file <path>; do not edit Prompt rows directly.
cd frontend
pnpm install
pnpm test # Run tests
pnpm run lint # Lint
pnpm run build # Build for productionSee docs/frontend/README.md and docs/frontend/STYLEGUIDE.md for details.
# Hybrid development (infra only)
docker compose -f docker-compose.infra.yml up -d
# Full stack (all services)
docker compose up -d
# Access frontend: http://localhost:3000
# Access backend: http://localhost:8000
# Local dev with hot reload
docker compose -f docker-compose.local.yml up -dPre-built images (automated by CI/CD, org from the DOCKER_USERNAME secret):
- Backend:
$DOCKER_USERNAME/fo-shelter-be:latest - Frontend:
$DOCKER_USERNAME/fo-shelter-fe:latest
See docs/DEPLOYMENT.md for complete deployment guide.
A backup script is provided at scripts/backup-db.sh:
# Set environment variables (or use .env file)
export POSTGRES_DB=fallout_db
export POSTGRES_USER=postgres
export POSTGRES_PASSWORD=your_password
export POSTGRES_SERVER=localhost
# Run backup
./scripts/backup-db.sh
# Backups are stored in: /mnt/dead-pool/backups/fallout/
# - Timestamped filenames (fallout_YYYYMMDD_HHMMSS.sql.gz)
# - Automatic compression
# - 14-day retention (old backups auto-deleted)# Using pg_dump directly
docker exec -t fallout-postgres pg_dump -U postgres fallout_db > backup.sql
# Or with compression
docker exec -t fallout-postgres pg_dump -U postgres fallout_db | gzip > backup.sql.gz# Stop the application
docker compose stop fastapi
# Restore from backup (uncompressed)
gunzip backup.sql.gz # if compressed
docker exec -i fallout-postgres psql -U postgres -d fallout_db < backup.sql
# Or restore to a fresh database
docker exec -i fallout-postgres psql -U postgres -c "DROP DATABASE fallout_db; CREATE DATABASE fallout_db;"
docker exec -i fallout-postgres psql -U postgres -d fallout_db < backup.sql
# Restart application
docker compose start fastapiEnvironment files:
.env.example- Template with localhost hostnames (for hybrid development).env- Your local copy (create from.env.example).env.local- Used bydocker-compose.local.yml(dev with volume mounts)backend/.env- Backend runtime requires this (copy from root.env)
Configuration strategy:
- Hybrid mode: Use
.envwith localhost hostnames (as-is from.env.example) - Full Docker mode: Use
.envas-is - Docker Compose auto-overrides hostnames - Do NOT manually edit hostnames for Docker - compose files handle it
Key variables:
- Required:
SECRET_KEY- Change in production (useopenssl rand -hex 32)POSTGRES_PASSWORD- Database passwordFIRST_SUPERUSER_PASSWORD- Admin account password
- Optional:
PYDANTIC_AI_GATEWAY_API_KEY- Recommended for chat and Pydantic AI agent calls; it routes toAI_PROVIDERandAI_MODELPYDANTIC_AI_GATEWAY_ROUTE- Optional custom Gateway provider or routing-group identifierPYDANTIC_AI_GATEWAY_BASE_URL- Regional Gateway proxy URL, such ashttps://gateway-eu.pydantic.dev/proxyAI_PROVIDER-openai(default),anthropic, orollama(local/free)OPENAI_API_KEY- Required for OpenAI image generation, TTS, and transcription; also enables legacy direct chat when no Gateway key is set- Database:
POSTGRES_SERVER,POSTGRES_DB,POSTGRES_USER - Redis:
REDIS_HOST,REDIS_PORT
AI Setup Notes:
- Ollama (Free): Install locally; Compose does not run Ollama. Use
OLLAMA_BASE_URL=http://host.containers.internal:11434/v1for a Podman container, orhttp://localhost:11434/v1when the backend runs natively. - Gateway + OpenAI (recommended): Set
PYDANTIC_AI_GATEWAY_API_KEY,AI_PROVIDER=openai, andAI_MODELfor chat/agent calls. SetPYDANTIC_AI_GATEWAY_ROUTEwhen using a custom Gateway provider or routing group. RetainOPENAI_API_KEYfor image and audio features. See Pydantic AI Gateway Setup for the complete local and Hetzner procedure. - Direct OpenAI (legacy): Set
AI_PROVIDER=openaiandOPENAI_API_KEY; this remains supported for media features. - No AI: App works without AI (conversations/chat features disabled)
"Connection refused" errors in Docker:
# Check all services are running
docker compose ps
# View logs for specific service
docker compose logs fastapi
docker compose logs db
# Restart services
docker compose restartPort already in use:
# Check what's using port 8000 (backend)
# Linux/Mac: lsof -i :8000
# Windows: netstat -ano | findstr :8000
# Stop conflicting service or change port in docker-compose.ymlBackend can't connect to database (hybrid mode):
# Verify infrastructure is running
docker compose -f docker-compose.infra.yml ps
# Check .env has localhost (not 'db')
grep POSTGRES_SERVER .env # Should show: POSTGRES_SERVER=localhostFrontend can't generate types:
# Ensure backend is running and accessible
curl http://localhost:8000/docs
# If backend is in Docker, ensure port 8000 is exposed
docker compose ps fastapi # Should show 0.0.0.0:8000->8000/tcpAI features not working:
- Check
AI_PROVIDERin.envmatches your setup - For Gateway: verify
PYDANTIC_AI_GATEWAY_API_KEYis set and that the selectedAI_PROVIDER/AI_MODELis enabled in Gateway - For direct OpenAI media features: verify
OPENAI_API_KEYis set correctly - For Ollama: Ensure the local service is running (
ollama serve) - App works without AI - conversation features will be disabled
- docs/ROADMAP.md - Changelog and upcoming features
- docs/DEPLOYMENT.md - Deployment guide
- docs/frontend/README.md - Frontend architecture
- docs/frontend/STYLEGUIDE.md - Design system
MIT License - See LICENSE file for details.
Built by ElderEvil Β· Inspired by Fallout Shelter (Bethesda)