Docker Compose Local Development
ForgeX uses Docker Compose to run all services and databases in a unified local development environment.
Architecture Overview
Docker Compose Environment (10 containers)
├── Databases (3)
│ ├── bids-db (PostgreSQL, port 5432)
│ ├── projects-db (PostgreSQL, port 5433)
│ └── field-db (PostgreSQL, port 5434)
├── Portal Service (1)
│ └── portal-frontend (Vite, port 3000)
├── Bids Service (2)
│ ├── bids-frontend (Vite, port 3001)
│ └── bids-backend (Express, port 5001)
├── Projects Service (2)
│ ├── projects-frontend (Vite, port 3002)
│ └── projects-backend (Express, port 5002)
└── Field Service (2)
├── field-frontend (Vite, port 3003)
└── field-backend (Express, port 5003)
Phase 1 (Bids) is fully operational. Projects and Field services show "Coming Soon" placeholders.
Quick Start
# Copy example files
cp services/bids/backend/.env.example services/bids/backend/.env
cp services/bids/frontend/.env.example services/bids/frontend/.env
# Edit with your Google OAuth credentials
nano services/bids/backend/.env
Environment Variables
Complete environment variable reference
docker-compose up -d
# Expected output:
# Creating bidmanager-bids-db ... done
# Creating bidmanager-projects-db ... done
# Creating bidmanager-field-db ... done
# Creating bidmanager-portal-frontend ... done
# Creating bidmanager-bids-backend ... done
# Creating bidmanager-bids-frontend ... done
# ...
# Bids database
docker-compose exec bids-backend npx prisma migrate dev
# Seed initial data
docker-compose exec bids-backend npx prisma db seed
Open in your browser:
- Portal: http://localhost:3000
- Bids: http://localhost:3001
- Bids API: http://localhost:5001/api/health
- Projects: http://localhost:3002 (Coming Soon)
- Field: http://localhost:3003 (Coming Soon)
Service Details
- Databases
- Portal
- Bids Service
- Projects Service
- Field Service
PostgreSQL Containers
Three independent PostgreSQL databases for service isolation:
| Database | Container | Port | Volume |
|---|---|---|---|
| bids_db | bidmanager-bids-db | 5432 | bidmanager-bids-data |
| projects_db | bidmanager-projects-db | 5433 | bidmanager-projects-data |
| field_db | bidmanager-field-db | 5434 | bidmanager-field-data |
Access database CLI:
# Bids database
docker exec -it bidmanager-bids-db psql -U postgres -d bids_db
# Run SQL query
docker exec bidmanager-bids-db psql -U postgres -d bids_db -c "SELECT COUNT(*) FROM \"User\";"
Database credentials (local only):
- Username:
postgres - Password:
devpassword
Portal Frontend
Container: bidmanager-portal-frontend
Tech Stack: Vite + React 18 + TypeScript
Features:
- Google OAuth authentication
- App launcher with role-based tiles
- Session management
- Redirects to subdomain services
Hot Reload: ✅ Enabled (Vite HMR)
View logs:
docker logs -f bidmanager-portal-frontend
Bids Frontend
Container: bidmanager-bids-frontend
Tech Stack: Vite + React 18 + TypeScript + Tailwind + shadcn/ui
Status: ✅ Fully operational
Hot Reload: ✅ Enabled (Vite HMR)
Bids Backend
Container: bidmanager-bids-backend
URL: http://localhost:5001/api
Tech Stack: Node.js 20 + Express + Prisma
Status: ✅ Fully operational
Hot Reload: ✅ Enabled (nodemon)
API Routes:
/api/health- Health check/api/auth/*- Authentication/api/bids/*- Bid management/api/clients/*- Client management/api/pricing/*- Pricing system/api/admin/*- Admin panel
View logs:
docker logs -f bidmanager-bids-backend
Projects Frontend
Container: bidmanager-projects-frontend
Status: ⏳ Coming Soon page
Projects Backend
Container: bidmanager-projects-backend
URL: http://localhost:5002/api
Status: ⏳ Placeholder only
Planned Features:
- Purchase order workflow
- Vendor management
- Receipt uploads
- Cost tracking
- Operations dashboard
Field Frontend
Container: bidmanager-field-frontend
Status: ⏳ Coming Soon page
Field Backend
Container: bidmanager-field-backend
URL: http://localhost:5003/api
Status: ⏳ Placeholder only
Planned Features:
- Employee management (PIN auth)
- Timesheet entry (GPS clock-in/out)
- Foreman dashboard
- Crew management
- Daily reports
Common Commands
▶️Start Services
# Start all services in background
docker-compose up -d
# Start with logs visible
docker-compose up
# Start specific service
docker-compose up -d bids-backend
⭕Stop Services
# Stop all services (data persists)
docker-compose down
# Stop and remove volumes (deletes data!)
docker-compose down -v
# Stop specific service
docker-compose stop bids-backend
📄View Logs
# All services
docker-compose logs -f
# Specific service
docker logs -f bidmanager-bids-backend
# Last 50 lines
docker logs --tail 50 bidmanager-bids-backend
🔨Rebuild Services
# Rebuild specific service
docker-compose up -d --build bids-backend
# Rebuild all services
docker-compose up -d --build
# Rebuild from scratch (no cache)
docker-compose build --no-cache
docker-compose up -d
🗄️Database Operations
# Access database CLI
docker exec -it bidmanager-bids-db psql -U postgres -d bids_db
# Run migrations
docker-compose exec bids-backend npx prisma migrate dev
# Seed database
docker-compose exec bids-backend npx prisma db seed
# Prisma Studio (opens at http://localhost:5555)
cd services/bids/backend
npx prisma studio
# Backup database
docker exec bidmanager-bids-db pg_dump -U postgres bids_db > backups/bids-backup.sql
# Restore database
docker exec -i bidmanager-bids-db psql -U postgres bids_db < backups/bids-backup.sql
🖥️Container Management
# List running containers
docker-compose ps
# Restart service
docker-compose restart bids-backend
# Execute command in container
docker-compose exec bids-backend npm install axios
# Access container shell
docker-compose exec bids-backend bash
Volume Persistence
Docker volumes ensure data persists across container restarts:
Database Data
Stored in named volumes:
bidmanager-bids-databidmanager-projects-databidmanager-field-data
Survives: Container restarts
Deleted by: docker-compose down -v
Source Code
Mounted from host machine:
./services/→ Container/app
Hot reload enabled for frontends and backends
Node Modules
Cached in volumes:
node_modulesexcluded from mounts- Faster rebuilds
- Consistent dependencies
Uploads
Mounted to host:
./services/bids/backend/uploads/
Accessible from host filesystem
docker-compose down -v deletes all database data! Always backup before using -v flag.
Environment Configuration
Each service has its own .env file:
.
├── services/
│ ├── portal/frontend/.env
│ ├── bids/
│ │ ├── frontend/.env # VITE_API_URL=http://localhost:5001/api
│ │ └── backend/.env # DATABASE_URL, SUPERTOKENS_CONNECTION_URI, etc.
│ ├── projects/
│ │ ├── frontend/.env
│ │ └── backend/.env
│ └── field/
│ ├── frontend/.env
│ └── backend/.env
Frontend env vars must start with VITE_ to be exposed to the browser.
Environment Variables
Complete environment variable reference
Network Configuration
All containers share the bidmanager_default Docker network:
bidmanager_default
├── bids-backend (can access bids-db by hostname)
├── bids-db
├── projects-backend (can access projects-db by hostname)
├── projects-db
├── field-backend (can access field-db by hostname)
├── field-db
├── supertokens
└── ... (all other containers)
Inter-service communication:
// In docker-compose, use service names as hostnames:
DATABASE_URL = "postgresql://postgres:devpassword@bids-db:5432/bids_db";
SUPERTOKENS_CONNECTION_URI = "http://supertokens:3567";
// From host machine, use localhost:
DATABASE_URL = "postgresql://postgres:devpassword@localhost:5432/bids_db";
SUPERTOKENS_CONNECTION_URI = "http://localhost:3567";
Development Workflow
docker-compose up -d
Edit files in services/ directory. Hot reload will automatically apply changes.
Refresh browser (frontend) or check logs (backend).
# Edit Prisma schema
nano services/bids/backend/prisma/schema.prisma
# Run migration
docker-compose exec bids-backend npx prisma migrate dev --name add_new_field
Database Migrations
Complete Prisma migration workflow
# Data persists in volumes
docker-compose down
Troubleshooting
Port already in use
Error: Bind for 0.0.0.0:3001 failed: port is already allocated
Solution:
# Windows: Find process using port
netstat -ano | findstr :3001
taskkill /PID <pid> /F
# Linux/Mac: Find and kill process
lsof -i :3001
kill -9 <pid>
Database connection refused
Error: Error: connect ECONNREFUSED 127.0.0.1:5432
Solutions:
- Check database is running:
docker ps | grep postgres
- Check DATABASE_URL format:
# ✅ Correct (inside Docker)
postgresql://postgres:devpassword@bids-db:5432/bids_db
# ✅ Correct (from host)
postgresql://postgres:devpassword@localhost:5432/bids_db
# ❌ Wrong
postgresql://postgres:devpassword@127.0.0.1:5432/bids_db
- Restart database:
docker-compose restart bids-db
Frontend not hot reloading
Problem: Changes to React components not reflecting
Solutions:
- Check Vite dev server is running:
docker logs bidmanager-bids-frontend
- Restart frontend:
docker-compose restart bids-frontend
- Clear browser cache (Ctrl+Shift+R)
Backend not restarting
Problem: Backend code changes not reflecting
Solutions:
- Check nodemon is watching files:
docker logs bidmanager-bids-backend | grep "restarting"
- Restart backend:
docker-compose restart bids-backend
- Rebuild if dependencies changed:
docker-compose up -d --build bids-backend
Container won't start
Problem: Container exits immediately
Solutions:
- View logs:
docker-compose logs bids-backend
- Check .env file exists:
ls services/bids/backend/.env
- Rebuild from scratch:
docker-compose down
docker-compose build --no-cache bids-backend
docker-compose up -d
Out of disk space
Problem: Docker using too much disk space
Solutions:
# Remove unused containers, networks, images
docker system prune -a
# Remove volumes (WARNING: Deletes data!)
docker volume prune
# Check disk usage
docker system df
Performance Tips
Speed Up Rebuilds
- Use Docker layer caching: Order Dockerfile commands from least to most frequently changed
- Exclude node_modules: Let Docker cache npm installs
- Increase Docker resources: Docker Desktop → Settings → Resources (increase CPU/memory)
Optimize Hot Reload
- Use .dockerignore: Exclude unnecessary files from context
- Minimize volumes: Only mount what's needed
- Use nodemon efficiently: Configure
.nodemonrcto ignore specific files