# Quick Start Guide Get Flyer Crawler running in 5 minutes. --- ## Prerequisites Checklist Before starting, verify you have: - [ ] **Windows 10/11** with WSL 2 enabled - [ ] **Podman Desktop** installed ([download](https://podman-desktop.io/)) - [ ] **Node.js 20+** installed - [ ] **Git** for cloning the repository **Verify Prerequisites**: ```bash # Check Podman podman --version # Expected: podman version 4.x or higher # Check Node.js node --version # Expected: v20.x or higher # Check WSL wsl --list --verbose # Expected: Shows WSL 2 distro ``` --- ## Quick Setup (5 Steps) ### Step 1: Start Containers (1 minute) ```bash # Start PostgreSQL and Redis podman start flyer-crawler-postgres flyer-crawler-redis # If containers don't exist yet, create them: podman run -d --name flyer-crawler-postgres \ -e POSTGRES_USER=postgres \ -e POSTGRES_PASSWORD=postgres \ -e POSTGRES_DB=flyer_crawler_dev \ -p 5432:5432 \ docker.io/postgis/postgis:15-3.3 podman run -d --name flyer-crawler-redis \ -p 6379:6379 \ docker.io/library/redis:alpine ``` **Expected Output**: ```text # Container IDs displayed, no errors ``` ### Step 2: Initialize Database (2 minutes) ```bash # Wait for PostgreSQL to be ready podman exec flyer-crawler-postgres pg_isready -U postgres # Expected: localhost:5432 - accepting connections # Install extensions podman exec flyer-crawler-postgres psql -U postgres -d flyer_crawler_dev \ -c "CREATE EXTENSION IF NOT EXISTS postgis; CREATE EXTENSION IF NOT EXISTS pg_trgm; CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";" # Apply schema podman exec -i flyer-crawler-postgres psql -U postgres -d flyer_crawler_dev < sql/master_schema_rollup.sql ``` **Expected Output**: ```text CREATE EXTENSION CREATE EXTENSION CREATE EXTENSION CREATE TABLE ... (many tables created) ``` ### Step 3: Configure Environment (1 minute) Create `.env.local` in the project root: ```bash # Database DB_HOST=localhost DB_USER=postgres DB_PASSWORD=postgres DB_NAME=flyer_crawler_dev DB_PORT=5432 # Redis REDIS_URL=redis://localhost:6379 # Application NODE_ENV=development PORT=3001 FRONTEND_URL=http://localhost:5173 # Secrets (generate your own - see command below) JWT_SECRET=your-dev-jwt-secret-at-least-32-chars-long SESSION_SECRET=your-dev-session-secret-at-least-32-chars-long # AI Services (get your own keys) GEMINI_API_KEY=your-google-gemini-api-key GOOGLE_MAPS_API_KEY=your-google-maps-api-key ``` **Generate Secure Secrets**: ```bash node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" ``` ### Step 4: Install and Run (1 minute) ```bash # Install dependencies (first time only) npm install # Start development server npm run dev ``` **Expected Output**: ```text > flyer-crawler@x.x.x dev > concurrently ... [API] Server listening on port 3001 [Vite] VITE ready at http://localhost:5173 ``` ### Step 5: Verify Installation | Check | URL/Command | Expected Result | | ----------- | ------------------------------ | ----------------------------------- | | Frontend | `http://localhost:5173` | Flyer Crawler app loads | | Backend API | `http://localhost:3001/health` | `{ "status": "ok", ... }` | | Database | `podman exec ... psql -c ...` | `SELECT version()` returns Postgres | | Containers | `podman ps` | Shows postgres and redis running | --- ## Full Dev Container (Recommended) For a production-like environment with NGINX, Bugsink error tracking, and PM2 process management: ### Starting the Dev Container ```bash # Start all services podman-compose -f compose.dev.yml up -d # View logs podman-compose -f compose.dev.yml logs -f ``` ### Access Points | Service | URL | Notes | | ----------- | ------------------------ | ---------------------------- | | Frontend | `https://localhost` | NGINX proxy to Vite | | Backend API | `http://localhost:3001` | Express server | | Bugsink | `https://localhost:8443` | Error tracking (admin/admin) | | PostgreSQL | `localhost:5432` | Database | | Redis | `localhost:6379` | Cache | **SSL Certificate Setup (Recommended)**: To eliminate browser security warnings, install the mkcert CA certificate: ```bash # Windows: Double-click certs/mkcert-ca.crt and install to Trusted Root CAs # See certs/README.md for detailed instructions per platform ``` ### PM2 Commands ```bash # View process status podman exec -it flyer-crawler-dev pm2 status # View logs (all processes) podman exec -it flyer-crawler-dev pm2 logs # Restart all processes podman exec -it flyer-crawler-dev pm2 restart all # Restart specific process podman exec -it flyer-crawler-dev pm2 restart flyer-crawler-api-dev ``` ### Dev Container Processes | Process | Description | Port | | -------------------------- | ------------------------ | ---- | | `flyer-crawler-api-dev` | API server (tsx watch) | 3001 | | `flyer-crawler-worker-dev` | Background job worker | - | | `flyer-crawler-vite-dev` | Vite frontend dev server | 5173 | --- ## Verification Commands Run these to confirm everything is working: ```bash # Check containers are running podman ps # Expected: flyer-crawler-postgres and flyer-crawler-redis both running # Test database connection podman exec flyer-crawler-postgres psql -U postgres -d flyer_crawler_dev -c "SELECT version();" # Expected: PostgreSQL 15.x with PostGIS # Run tests (in dev container) podman exec -it flyer-crawler-dev npm run test:unit # Expected: All tests pass # Run type check podman exec -it flyer-crawler-dev npm run type-check # Expected: No type errors ``` --- ## Common Issues and Solutions ### "Unable to connect to Podman socket" **Cause**: Podman machine not running **Solution**: ```bash podman machine start ``` ### "Connection refused" to PostgreSQL **Cause**: PostgreSQL still initializing **Solution**: ```bash # Wait for PostgreSQL to be ready podman exec flyer-crawler-postgres pg_isready -U postgres # Retry after "accepting connections" message ``` ### Port 5432 or 6379 already in use **Cause**: Another service using the port **Solution**: ```bash # Option 1: Stop conflicting service # Option 2: Use different host port podman run -d --name flyer-crawler-postgres -p 5433:5432 ... # Then update DB_PORT=5433 in .env.local ``` ### "JWT_SECRET must be at least 32 characters" **Cause**: Secret too short in .env.local **Solution**: Generate a longer secret: ```bash node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" ``` ### Tests fail with "TZ environment variable" errors **Cause**: Timezone setting interfering with Node.js async hooks **Solution**: Tests must run in dev container (not Windows host): ```bash # CORRECT - run in container podman exec -it flyer-crawler-dev npm test # INCORRECT - do not run on Windows host npm test ``` --- ## Next Steps | Goal | Document | | ----------------------- | ----------------------------------------------------- | | Understand the codebase | [Architecture Overview](../architecture/OVERVIEW.md) | | Configure environment | [Environment Variables](ENVIRONMENT.md) | | Set up MCP tools | [MCP Configuration](../tools/MCP-CONFIGURATION.md) | | Learn testing | [Testing Guide](../development/TESTING.md) | | Understand DB schema | [Database Documentation](../architecture/DATABASE.md) | | Read ADRs | [ADR Index](../adr/index.md) | | Full installation guide | [Installation Guide](INSTALL.md) | --- ## Daily Development Workflow ```bash # 1. Start containers podman start flyer-crawler-postgres flyer-crawler-redis # 2. Start dev server npm run dev # 3. Make changes and test npm test # 4. Type check before commit npm run type-check # 5. Commit changes git commit ``` **For dev container users**: ```bash # 1. Start dev container podman-compose -f compose.dev.yml up -d # 2. View logs podman exec -it flyer-crawler-dev pm2 logs # 3. Run tests podman exec -it flyer-crawler-dev npm test # 4. Stop when done podman-compose -f compose.dev.yml down ``` --- Last updated: January 2026