Skip to main content

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)
info

Phase 1 (Bids) is fully operational. Projects and Field services show "Coming Soon" placeholders.

Quick Start

1
Setup Environment Files
# 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

2
Start All Services
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
# ...
3
Run Database Migrations
# Bids database
docker-compose exec bids-backend npx prisma migrate dev
# Seed initial data
docker-compose exec bids-backend npx prisma db seed
4
Access Services

Open in your browser:

Service Details

PostgreSQL Containers

Three independent PostgreSQL databases for service isolation:

DatabaseContainerPortVolume
bids_dbbidmanager-bids-db5432bidmanager-bids-data
projects_dbbidmanager-projects-db5433bidmanager-projects-data
field_dbbidmanager-field-db5434bidmanager-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

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-data
  • bidmanager-projects-data
  • bidmanager-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_modules excluded from mounts
  • Faster rebuilds
  • Consistent dependencies
☁️

Uploads

Mounted to host:

  • ./services/bids/backend/uploads/

Accessible from host filesystem

warning

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
tip

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

1
Start Services
docker-compose up -d
2
Make Code Changes

Edit files in services/ directory. Hot reload will automatically apply changes.

3
View Changes

Refresh browser (frontend) or check logs (backend).

4
Database Changes
# 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

5
Stop Services
# 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:

  1. Check database is running:
docker ps | grep postgres
  1. 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
  1. Restart database:
docker-compose restart bids-db
Frontend not hot reloading

Problem: Changes to React components not reflecting

Solutions:

  1. Check Vite dev server is running:
docker logs bidmanager-bids-frontend
  1. Restart frontend:
docker-compose restart bids-frontend
  1. Clear browser cache (Ctrl+Shift+R)
Backend not restarting

Problem: Backend code changes not reflecting

Solutions:

  1. Check nodemon is watching files:
docker logs bidmanager-bids-backend | grep "restarting"
  1. Restart backend:
docker-compose restart bids-backend
  1. Rebuild if dependencies changed:
docker-compose up -d --build bids-backend
Container won't start

Problem: Container exits immediately

Solutions:

  1. View logs:
docker-compose logs bids-backend
  1. Check .env file exists:
ls services/bids/backend/.env
  1. 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

  1. Use Docker layer caching: Order Dockerfile commands from least to most frequently changed
  2. Exclude node_modules: Let Docker cache npm installs
  3. Increase Docker resources: Docker Desktop → Settings → Resources (increase CPU/memory)

Optimize Hot Reload

  1. Use .dockerignore: Exclude unnecessary files from context
  2. Minimize volumes: Only mount what's needed
  3. Use nodemon efficiently: Configure .nodemonrc to ignore specific files

Next Steps