Development Environment Setup Guide

Reference For Super Administrators System Admin
Last updated: January 26, 2026 β€’ Version: 1.0

MangoApps Workforce - Development Environment Setup (Mac)

Internal Use Only - Developer Onboarding Documentation

Welcome to the team! Follow these steps to set up your local development environment on Mac.


Prerequisites

Before you begin, install:

Requirement Download Link Notes
Docker Desktop Download Allocate 8GB+ RAM, 4+ CPU cores
Git Download For repository management
10GB+ free disk space - For Docker images and volumes

Docker Desktop Configuration

After installing Docker Desktop:

  1. Open Docker Desktop β†’ Settings β†’ Resources
  2. Set Memory to at least 8GB (16GB recommended)
  3. Set CPUs to at least 4 cores
  4. Click Apply & Restart

Step 1: Clone the Repository

git clone <repository-url>
cd shifts

Step 2: Run the Setup Script

./scripts/dev-setup.sh

This single command will automatically:

  • βœ… Create Docker volumes for data persistence
  • βœ… Configure environment files (.env, api_keys.yml)
  • βœ… Build Docker images (Rails, PostgreSQL with pgvector)
  • βœ… Start all services (Rails, PostgreSQL, MailHog, GoodJob worker)
  • βœ… Run database migrations and seeds
  • βœ… Set up nginx SSL proxy (macOS only)
  • βœ… Generate your development login token

⏱ First run takes 10-20 minutes. Subsequent runs take 2-5 minutes.

Setup Script Options

# Full setup (recommended for first time)
./scripts/dev-setup.sh

# Minimal setup (faster, use localhost:3001 directly)
./scripts/dev-setup.sh --minimal

# Skip specific steps
./scripts/dev-setup.sh --skip-nginx      # Skip nginx setup
./scripts/dev-setup.sh --skip-db-seed    # Skip database seeding
./scripts/dev-setup.sh --skip-assets     # Skip asset compilation

# Force rebuild everything
./scripts/dev-setup.sh --force

# Show help
./scripts/dev-setup.sh --help

Step 3: Access the Application

Once setup completes, open your browser:

URL Purpose
https://officechat-dev.workforce.mangoapps.com Main development app (with SSL)
http://localhost:3001 Direct access (no SSL)
http://localhost:8025 MailHog - View test emails

Step 4: Log In

Use the magic login link printed at the end of setup, OR use the quick dev login:

http://localhost:3001/dev/login/anup@officechat.com

Regenerate Login Token

# Permanent token (100 years)
docker-compose exec -e PERMANENT=true ma-shifts-ror bundle exec rails runner scripts/generate_dev_login.rb

# Standard 30-day token
docker-compose exec ma-shifts-ror bundle exec rails runner scripts/generate_dev_login.rb

Daily Commands Reference

Service Management

# Start all services
docker-compose up -d

# Stop all services
docker-compose down

# Restart a specific service
docker-compose restart ma-shifts-ror

# View running services
docker-compose ps

# View logs (follow mode)
docker-compose logs -f ma-shifts-ror

Rails Commands

# Rails console
docker-compose exec ma-shifts-ror bundle exec rails console

# Run migrations
docker-compose exec ma-shifts-ror bundle exec rails db:migrate

# Run seeds
docker-compose exec ma-shifts-ror bundle exec rails db:seed

# Run tests
docker-compose exec ma-shifts-ror bundle exec rspec

Asset Building

# Build assets locally (faster)
./esbuild.sh

# Build assets in Docker
docker-compose exec ma-shifts-ror npm run build

Nginx Management (macOS)

# Start nginx with dev config
./nginx/manage-nginx.sh dev

# Stop nginx
./nginx/manage-nginx.sh stop

# View nginx logs
./nginx/manage-nginx.sh logs-dev

# Check nginx status
./nginx/manage-nginx.sh status

Docker Services Overview

Service Container Name Port Purpose
Rails App ma-shifts-ror 3001 Main application
PostgreSQL 17 shifts-postgres 5432 Database with pgvector
GoodJob Worker ma-shifts-worker - Background jobs
MailHog shifts-mailhog 8025 (UI), 1025 (SMTP) Email testing

Environment Configuration

.env File

Environment variables for Docker Compose (created automatically):

RAILS_ENV=development
POSTGRES_HOST=shifts-postgres
POSTGRES_USER=postgres
POSTGRES_PASSWORD=Shifts21Mango!
POSTGRES_DB=shifts_development

src/config/api_keys.yml

API keys for external services. Edit this file to add your actual keys:

development:
  openai:
    api_key: your_openai_api_key_here   # Required for AI features
  merge:
    api_key: your_merge_api_key_here     # Required for integrations

Troubleshooting

Docker Issues

Container won’t start:

# Check logs for errors
docker-compose logs ma-shifts-ror

# Restart with fresh build
docker-compose down
docker-compose up --build -d

Out of disk space:

# Clean up Docker resources
docker system prune -a --volumes

Port already in use:

# Find what's using the port
lsof -i :3001
lsof -i :5432

# Kill the process
kill -9 <PID>

Database Issues

Database connection refused:

# Ensure PostgreSQL is running
docker-compose up -d shifts-postgres

# Wait for it to be ready
docker-compose exec shifts-postgres pg_isready -U postgres

Migrations pending:

docker-compose exec ma-shifts-ror bundle exec rails db:migrate

Nginx Issues (macOS)

Certificate not trusted (browser shows β€œnot secure”):

# Trust the certificate
sudo security add-trusted-cert -d -r trustRoot \
    -k /Library/Keychains/System.keychain \
    src/config/ssl/site.crt

Port 443 in use:

# Find what's using port 443
sudo lsof -i :443

# Stop nginx
./nginx/manage-nginx.sh stop

DNS not resolving:

# Check hosts file
grep workforce /etc/hosts

# Flush DNS cache (macOS)
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

Asset Issues

Assets not loading:

# Rebuild assets
./esbuild.sh

# Or in Docker
docker-compose exec ma-shifts-ror npm run build

Need to rebuild everything:

./scripts/dev-setup.sh --force

Architecture Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                              Browser                                      β”‚
β”‚                                 β”‚                                         β”‚
β”‚                          HTTPS (443)                                      β”‚
β”‚                                 β–Ό                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚  β”‚                    Nginx (Host - macOS only)                         β”‚β”‚
β”‚  β”‚  β€’ SSL Termination (*.workforce.mangoapps.com)                       β”‚β”‚
β”‚  β”‚  β€’ Security headers, WebSocket support                               β”‚β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β”‚                                 β”‚                                         β”‚
β”‚                          HTTP (3001)                                      β”‚
β”‚                                 β–Ό                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚  β”‚                    Docker Network (ma-network)                       β”‚β”‚
β”‚  β”‚                                                                       β”‚β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚β”‚
β”‚  β”‚  β”‚   Rails App     β”‚  β”‚   PostgreSQL    β”‚  β”‚    MailHog      β”‚      β”‚β”‚
β”‚  β”‚  β”‚   (Puma)        β”‚  β”‚   with pgvector β”‚  β”‚   (Email UI)    β”‚      β”‚β”‚
β”‚  β”‚  β”‚   Port 3001     β”‚  β”‚   Port 5432     β”‚  β”‚   Port 8025     β”‚      β”‚β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚β”‚
β”‚  β”‚           β”‚                    β–²                                      β”‚β”‚
β”‚  β”‚           β”‚         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                          β”‚β”‚
β”‚  β”‚           β”‚         β”‚                     β”‚                          β”‚β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”‚                          β”‚β”‚
β”‚  β”‚  β”‚     GoodJob Worker          β”‚β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                          β”‚β”‚
β”‚  β”‚  β”‚   (Background Jobs)         β”‚                                      β”‚β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                      β”‚β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Documentation

Document Location Purpose
Setup Guide scripts/DEV_SETUP_GUIDE.md Detailed setup instructions
Getting Started docs/getting-started/README.md Onboarding overview
Patterns docs/patterns/ Implementation patterns
Development Guidelines src/docs/DEVELOPMENT_GUIDELINES.md Coding standards
Business Scoping src/docs/BUSINESS_SCOPING_STANDARDS.md Security-critical patterns
View Standards src/docs/MUST_READ_BEFORE_CREATING_VIEWS.md Required for view development

Getting Help

  • Documentation: Browse /docs/ directory
  • Technical Docs: Browse /src/docs/ directory
  • Patterns: See /docs/patterns/ for implementation patterns
  • Reach out to the team if you run into any issues!