Docker Development Environment
This document explains how to use the Docker setup for Rainfall-Learning development.
Quick Start
Option 1: Build and Start (Recommended)
# Build all containers
npm run docker:build
# Start services
npm run docker:start
Option 2: Rebuild and Start (if you have changes)
# Rebuild everything from scratch
npm run docker:rebuild
Services
The Docker Development setup includes three main services:
1. Database (PostgreSQL)
- Port:
localhost:5432 - Database:
rainfall_dev - Credentials:
postgres/postgres - Health Check: Automatically waits for database to be ready
2. Backend (Node.js API)
- Port:
localhost:3000 - Features:
- Automatic dependency installation
- Prisma client generation
- Database schema reset and migration
- Hot reloading for development
- Independent: Handles all setup automatically
3. Frontend (React/Vite)
- Port:
localhost:5173 - Features:
- Automatic dependency installation
- Shared package building
- Hot reloading for development
- Connected to backend API
Container Independence
Each container is designed to be completely independent:
Database Container
- Self-contained: Includes all PostgreSQL dependencies
- Persistent storage: Data persists between container restarts
- Health monitoring: Uses
pg_isreadyto verify database readiness - Robust checks: 10 retries with 5s intervals, 10s start period
Backend Container
- Autonomous initialization:
- Installs its own dependencies
- Generates Prisma client during build
- Waits for database health check before starting
- Resets database schema on startup
- Applies migrations automatically
- Robust database connection: Retries until database is ready
- No manual intervention required: Everything happens automatically
Frontend Container
- Independent startup: Can start without backend (though API calls will fail)
- Self-contained: Installs its own dependencies
- Hot reloading: Changes reflect immediately
- Shared package building: Automatically builds shared dependencies
Available Commands
# Build all containers
npm run docker:build
# Start services in background
npm run docker:start
# Stop all services
npm run docker:stop
# View logs
npm run docker:logs
# Restart services
npm run docker:restart
# Clean up (removes volumes too)
npm run docker:clean
# Rebuild everything from scratch
npm run docker:rebuild
Health Checks & Reliability
Database Health Monitoring
pg_isready: Verifies PostgreSQL is accepting connections- Smart retries: 10 attempts with 5-second intervals
- Start period: 10-second grace period for initial startup
- Dependency management: Backend waits for healthy database
Backend Connection Logic
- No arbitrary sleeps: Uses actual database connectivity tests
- Retry mechanism: Continuously attempts connection until successful
- Graceful handling: Clear logging of connection attempts
- Fail-fast: Immediate feedback if database is unreachable
Database Management
Schema Changes
The backend container automatically handles schema changes:
- Uses
prisma migrate reset --forceon startup - Resets database to clean state
- Applies all migrations automatically
- Regenerates Prisma client during build
Adding Migrations (Production)
For production, you should use proper migrations:
# Inside backend container
docker-compose exec backend npx prisma migrate dev --name your_migration_name
Database Reset
To reset the database:
npm run docker:restart
Development Workflow
- Start development:
npm run docker:start - Make changes: Edit files in
packages/backendorpackages/frontend - See changes: Hot reloading will automatically reflect changes
- Run tests:
npm run test(runs inside Docker containers) - Database changes: Edit
packages/backend/prisma/schema.prisma, restart backend container - Stop development:
npm run docker:stop
Testing in Docker
Test Execution
All tests run inside Docker containers for consistency:
# Run all tests (backend + frontend)
npm run test
# Run specific test suites
npm run test:backend # Backend tests only
npm run test:frontend # Frontend tests only
npm run test:shared # Shared package tests
# Run tests with coverage
npm run test:coverage
# Watch mode for development
npm run test:watch
Test Environment
- Backend Tests: Run inside backend container with database access
- Frontend Tests: Run inside frontend container with jsdom environment
- Shared Imports: All
@rainfall/sharedimports work correctly - Database: Automatically set up when Docker starts
Test Configuration
- Backend: Uses
packages/backend/vitest.config.tswith Node.js environment - Frontend: Uses
packages/frontend/vitest.config.tswith jsdom environment - Path Mapping: TypeScript paths configured for shared package imports
- Test Location:
- Frontend tests:
packages/frontend/tests/ - Backend tests:
packages/backend/tests/
- Frontend tests:
- Test Setup: Frontend uses
packages/frontend/src/test-setup.tsfor jest-dom matchers
Troubleshooting
Container Won't Start
- Check logs:
npm run docker:logs - Ensure Docker is running
- Check if ports are available (5432, 3000, 5173)
- Try rebuilding:
npm run docker:rebuild
Database Connection Issues
- Wait for database health check to pass
- Check environment variables in docker-compose.yml
- Restart containers:
npm run docker:restart
Build Issues
- Clean everything:
npm run docker:clean - Rebuild from scratch:
npm run docker:rebuild - Check Dockerfile syntax and paths
Frontend Can't Connect to Backend
- Ensure backend is running (check logs)
- Verify
VITE_API_URLin environment - Check network connectivity between containers
Environment Variables
The setup uses environment variables defined in docker-compose.yml:
DATABASE_URL: PostgreSQL connection stringNODE_ENV: Development environmentVITE_API_URL: Frontend API URL
Architecture Benefits
- Independent containers: Each service can run independently
- Automatic setup: No manual intervention required
- Consistent environment: Same setup across all developers
- Easy deployment: Can be easily adapted for production