Files
looking-monorepo/.devcontainer/README.md
2025-12-28 13:52:25 -03:00

765 lines
19 KiB
Markdown

# Looking - DevContainer Configuration
> **VS Code Development Container setup for the Looking monorepo**
This directory contains the complete Docker-based development environment configuration for the Looking project. The DevContainer provides a consistent, isolated development environment with all necessary tools and dependencies pre-installed.
---
## 📋 Table of Contents
- [Overview](#overview)
- [What's Included](#whats-included)
- [Architecture](#architecture)
- [Services](#services)
- [Port Mappings](#port-mappings)
- [Volume Mounts](#volume-mounts)
- [Installation Process](#installation-process)
- [VS Code Integration](#vs-code-integration)
- [Environment Variables](#environment-variables)
- [Troubleshooting](#troubleshooting)
---
## 🎯 Overview
The DevContainer setup provides:
- **Consistent Environment**: Same Node 14, Python 2.7, and build tools across all developers
- **Isolated Dependencies**: No conflicts with your local system packages
- **Auto-Configuration**: Automatic dependency installation and VS Code extensions
- **Multi-Service Stack**: Frontend, backend, database, and admin UI all running together
- **Volume Optimization**: Fast performance with node_modules isolation
**Technologies**: Docker Compose, VS Code Remote - Containers, Node 14, MongoDB 4.4
---
## 📦 What's Included
### Base Container
**Image**: Custom Dockerfile based on `node:14-bullseye`
**System Packages**:
- Git (version control)
- curl & wget (HTTP clients)
- vim (text editor)
- **Python 2.7** (required for legacy node-sass)
- build-essential (C++ compiler for native modules)
**Global NPM Packages**:
- `@ionic/cli` - Ionic framework CLI
- `@angular/cli` - Angular CLI (though project uses ionic-app-scripts)
- `nodemon` - Auto-restart development server
- `concurrently` - Run multiple commands in parallel
- `eslint` - JavaScript linting
- `prettier` - Code formatting
### VS Code Extensions (Auto-Installed)
| Extension | Purpose |
| -------------------------------------- | --------------------------- |
| **ms-vscode.vscode-json** | JSON language support |
| **bradlc.vscode-tailwindcss** | Tailwind CSS IntelliSense |
| **esbenp.prettier-vscode** | Code formatting |
| **dbaeumer.vscode-eslint** | JavaScript linting |
| **ms-vscode.vscode-typescript-next** | TypeScript support |
| **formulahendry.auto-rename-tag** | HTML/XML tag rename |
| **christian-kohler.path-intellisense** | Autocomplete file paths |
| **mongodb.mongodb-vscode** | MongoDB database management |
### Editor Settings (Auto-Configured)
- **Format on Save**: Enabled
- **Default Formatter**: Prettier
- **ESLint Auto-Fix**: Runs on save
- **Emmet**: Enabled for JavaScript (React/JSX)
---
## 🏗️ Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ DevContainer Stack │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ App Container (node:14-bullseye) │ │
│ │ - VS Code Remote Server │ │
│ │ - Node.js 14.x + npm │ │
│ │ - Python 2.7 (for node-sass) │ │
│ │ - Ionic/Angular Dev Server (port 8100) │ │
│ │ - Express API Server (port 3069) │ │
│ │ - Development tools (nodemon, eslint, prettier) │ │
│ └──────────────────────────────────────────────────────┘ │
│ ↓↑ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ MongoDB 4.4 (mongo:4.4) │ │
│ │ - Database: urge │ │
│ │ - Port: 27017 │ │
│ │ - Credentials: admin/password │ │
│ │ - Health Check: ping command every 30s │ │
│ │ - Seed Data: /docker-entrypoint-initdb.d │ │
│ └──────────────────────────────────────────────────────┘ │
│ ↓↑ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Mongo Express (mongo-express:latest) │ │
│ │ - Web-based MongoDB admin UI │ │
│ │ - Port: 8081 │ │
│ │ - Login: admin/password │ │
│ │ - Browse collections, run queries │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ Network: dev-network (bridge driver) │
└─────────────────────────────────────────────────────────────┘
↓ ↓ ↓
Port 8100 Port 3069 Port 27017
(Frontend Dev) (Backend API) (MongoDB)
```
---
## 🔌 Services
### 1. App Service (Development Container)
**File**: [docker-compose.yml](docker-compose.yml)
**Configuration**:
```yaml
service: app
build:
context: ..
dockerfile: .devcontainer/Dockerfile
command: sleep infinity
volumes:
- ../..:/workspaces:cached
- /workspaces/PfosiLooking-monorepo/app/node_modules
- /workspaces/PfosiLooking-monorepo/backend/node_modules
depends_on:
mongo:
condition: service_healthy
```
**Purpose**:
- Main development container where you write code
- Runs VS Code Remote Server
- Hosts Ionic dev server (port 8100) and Express API (port 3069)
- Waits for MongoDB health check before starting
**Command**: `sleep infinity` keeps container running indefinitely
**Node Modules Isolation**:
- Anonymous volumes for `app/node_modules` and `backend/node_modules`
- Prevents host filesystem performance issues (especially on Mac/Windows)
- Each workspace has its own isolated dependencies
---
### 2. MongoDB Service
**Configuration**:
```yaml
service: mongo
image: mongo:4.4
environment:
- MONGO_INITDB_DATABASE=urge
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=password
ports:
- "27017:27017"
volumes:
- mongo_data:/data/db
- ../backend/data:/docker-entrypoint-initdb.d:ro
healthcheck:
test: echo 'db.runCommand("ping").ok' | mongo localhost:27017/urge --quiet
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
```
**Purpose**:
- NoSQL database for profiles, users, and messages
- Persistent storage via `mongo_data` volume
- Auto-loads seed data from `backend/data/` on first run
**Credentials**:
- **Admin User**: `admin`
- **Admin Password**: `password`
- **Database**: `urge`
**Health Check**:
- Runs every 30 seconds
- Pings database to verify it's responsive
- App container waits for healthy status before starting
**Seed Data**:
- Files in `backend/data/` are mounted to `/docker-entrypoint-initdb.d`
- MongoDB automatically executes `.js` and `.sh` files in that directory
- Used for initial database population (if scripts exist)
---
### 3. Mongo Express Service
**Configuration**:
```yaml
service: mongo-express
image: mongo-express:latest
environment:
- ME_CONFIG_MONGODB_SERVER=mongo
- ME_CONFIG_MONGODB_PORT=27017
- ME_CONFIG_MONGODB_ADMINUSERNAME=admin
- ME_CONFIG_MONGODB_ADMINPASSWORD=password
- ME_CONFIG_BASICAUTH_USERNAME=admin
- ME_CONFIG_BASICAUTH_PASSWORD=password
ports:
- "8081:8081"
depends_on:
- mongo
```
**Purpose**:
- Web-based database administration tool
- View/edit collections without command-line mongo shell
- Useful for debugging data issues
**Access**: http://localhost:8081
- **Login**: admin / password
**Features**:
- Browse collections visually
- Run MongoDB queries
- Create/edit/delete documents
- View indexes and stats
---
## 🔌 Port Mappings
| Port | Service | Purpose | Access |
| --------- | ---------------- | -------------------- | ------------------------- |
| **8100** | Ionic Dev Server | Frontend application | http://localhost:8100 |
| **3069** | Express API | Backend REST API | http://localhost:3069 |
| **27017** | MongoDB | Database server | mongodb://localhost:27017 |
| **8081** | Mongo Express | Database admin UI | http://localhost:8081 |
### Port Forwarding Configuration
**File**: [devcontainer.json](devcontainer.json)
```json
"forwardPorts": [8100, 3069, 27017, 8081],
"portsAttributes": {
"8100": {
"label": "Frontend (Ionic)",
"onAutoForward": "notify"
},
"3069": {
"label": "Backend API",
"onAutoForward": "notify"
},
"27017": {
"label": "MongoDB",
"onAutoForward": "silent"
},
"8081": {
"label": "Mongo Express",
"onAutoForward": "notify"
}
}
```
**Notifications**:
- **notify**: VS Code shows notification when port is forwarded
- **silent**: No notification (database port)
---
## 💾 Volume Mounts
### Workspace Volume
```yaml
volumes:
- ../..:/workspaces:cached
```
**Purpose**:
- Mounts parent directory (entire monorepo) into container
- `:cached` flag optimizes for read-heavy operations
- Enables live code changes to reflect immediately
**Path Inside Container**: `/workspaces/PfosiLooking-monorepo/`
---
### Node Modules Isolation
```yaml
volumes:
- /workspaces/PfosiLooking-monorepo/app/node_modules
- /workspaces/PfosiLooking-monorepo/backend/node_modules
```
**Purpose**:
- Creates anonymous Docker volumes for node_modules directories
- Isolates dependencies from host filesystem
- **Solves performance issues** on Mac/Windows (Docker Desktop)
**Why?**:
- node_modules can have 100,000+ files
- Host filesystem sync is slow for that many files
- Volume isolation provides native container filesystem performance
---
### MongoDB Data Volume
```yaml
volumes: mongo_data:/data/db
```
**Purpose**:
- Persistent storage for MongoDB data
- Survives container restarts
- Named volume managed by Docker
**Location**: Docker volume `mongo_data` (not visible in project directory)
---
### Seed Data Volume
```yaml
volumes:
- ../backend/data:/docker-entrypoint-initdb.d:ro
```
**Purpose**:
- Mounts seed data directory into MongoDB initialization location
- `:ro` = read-only (MongoDB can't modify host files)
- Scripts run automatically on first database creation
---
## 🔄 Installation Process
### Automatic Setup (postCreateCommand)
**File**: [postCreateCommand.sh](postCreateCommand.sh)
The script runs automatically after the container is created:
```bash
#!/bin/bash
set -e # Exit on any error
# 1. Install root dependencies
npm install
# 2. Install backend dependencies
cd backend && npm install
# 3. Install app dependencies with legacy support
cd app && npm install --legacy-peer-deps
```
**Execution Time**: 5-10 minutes (first time only)
**What Happens**:
1. **Root workspace** (`package.json`):
- Installs `concurrently`, `npm-run-all`
- Enables `npm run dev:all` script
2. **Backend** (`backend/package.json`):
- Installs Express, Mongoose, JWT, etc.
- Standard npm install (no special flags)
3. **Frontend** (`app/package.json`):
- Installs Ionic 3, Angular 5, TypeScript 2.4
- **Uses `--legacy-peer-deps`** flag
- Required for old Ionic 3 packages with npm 7+
- Falls back to `--force` if legacy deps fail
**Progress Visibility**:
- VS Code shows "Running postCreateCommand" notification
- View detailed output: Terminal → "postCreateCommand" tab
---
### Manual Installation
If automatic setup fails:
```bash
# 1. Open VS Code terminal inside DevContainer
# Terminal → New Terminal (or Ctrl + `)
# 2. Install dependencies manually
npm install
cd backend && npm install && cd ..
cd app && npm install --legacy-peer-deps && cd ..
# 3. Verify installation
npm run dev:all
```
---
## 🎨 VS Code Integration
### DevContainer Configuration
**File**: [devcontainer.json](devcontainer.json)
**Key Settings**:
```json
{
"name": "PfosiLooking Full Stack",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspaces/PfosiLooking-monorepo",
"shutdownAction": "stopCompose"
}
```
**Shutdown Behavior**:
- `"stopCompose"` - Stops all services when closing VS Code
- Preserves data in volumes (MongoDB data, node_modules)
- Fast restart on next open (no rebuild needed)
---
### Features
**Auto-Installed**:
```json
{
"ghcr.io/devcontainers/features/node:1": {
"version": "14"
},
"ghcr.io/devcontainers/features/git:1": {},
"ghcr.io/devcontainers/features/github-cli:1": {}
}
```
**Provides**:
- Node.js 14.x (managed version)
- Git (latest stable)
- GitHub CLI (`gh` command)
---
### Post-Start Message
```json
"postStartCommand": "echo 'DevContainer ready! Run npm run dev:all to start development.'"
```
Displays helpful message after container starts.
---
## 🔐 Environment Variables
### Development Environment File
**File**: [dev.env](dev.env)
**Contains** (example values):
```bash
NODE_ENV=development
MONGODB_URI=mongodb://mongo:27017/urge
REACT_APP_API_URL=http://localhost:3069
PORT=3069
IONIC_PORT=8100
JWT_SECRET=dev-secret-change-in-production
```
**Usage**:
```yaml
env_file:
- dev.env
```
⚠️ **Security Note**:
- `dev.env` may contain secrets
- DO NOT commit real credentials
- Use `dev.env.example` for templates
- Add `dev.env` to `.gitignore`
---
### Inline Environment Variables
**In docker-compose.yml**:
```yaml
environment:
- NODE_ENV=development
- MONGODB_URI=mongodb://mongo:27017/urge
- PORT=3069
```
These override values from `dev.env` if both are present.
---
## 🔧 Troubleshooting
### Container Won't Start
**Problem**: DevContainer fails to start or build
**Solutions**:
1. **Rebuild without cache**:
```
F1 → "Dev Containers: Rebuild Container Without Cache"
```
2. **Check Docker Desktop is running**:
```bash
docker ps
```
3. **Free up disk space**:
```bash
docker system prune -a
```
4. **View build logs**:
```
F1 → "Dev Containers: Show Container Log"
```
---
### Python 2.7 Errors
**Problem**: `node-sass` or `node-gyp` errors about Python
**Check Python symlinks**:
```bash
# Inside container
which python
python --version # Should show Python 2.7.x
```
**Dockerfile installs**:
```dockerfile
RUN apt-get install -y python2.7 python2.7-dev \
&& ln -sf /usr/bin/python2.7 /usr/bin/python
```
**Why?**: node-sass (used by Ionic 3) requires Python 2.7 to build native modules.
---
### MongoDB Connection Failed
**Problem**: Backend can't connect to MongoDB
**1. Check MongoDB is healthy**:
```bash
docker ps
# Look for "healthy" status on mongo container
```
**2. Test connection manually**:
```bash
docker exec -it <mongo-container-id> mongo --eval "db.runCommand('ping')"
```
**3. Verify connection string**:
```bash
echo $MONGODB_URI
# Should be: mongodb://mongo:27017/urge
```
**4. Wait for health check**:
- Health check runs every 30s
- Container may need 40s start period
- App service waits for `service_healthy` condition
---
### Port Already in Use
**Problem**: Port 8100, 3069, or 27017 already in use on host
**Find conflicting process**:
```bash
# Mac/Linux
lsof -i :8100
lsof -i :3069
lsof -i :27017
# Kill process
kill -9 <PID>
```
**Or change ports** in [docker-compose.yml](docker-compose.yml):
```yaml
ports:
- "8101:8100" # Changed from 8100
```
---
### Node Modules Issues
**Problem**: Module not found, peer dependency warnings, or version conflicts
**Solution 1 - Reinstall**:
```bash
# Remove all node_modules
rm -rf node_modules app/node_modules backend/node_modules
# Reinstall
npm run install:all
```
**Solution 2 - Clear volume**:
```bash
# Exit container, then from host
docker-compose -f .devcontainer/docker-compose.yml down -v
# This deletes ALL volumes including node_modules and MongoDB data
# Rebuild container
F1 → "Dev Containers: Rebuild Container"
```
---
### Slow Performance
**Problem**: File watching or compilation is slow
**Causes**:
- Docker Desktop on Mac/Windows has filesystem sync overhead
- Large node_modules directories
**Solutions**:
1. **Verify node_modules isolation**:
```yaml
# These volumes should exist in docker-compose.yml
- /workspaces/PfosiLooking-monorepo/app/node_modules
- /workspaces/PfosiLooking-monorepo/backend/node_modules
```
2. **Increase Docker resources**:
- Docker Desktop → Settings → Resources
- Increase CPU: 4+ cores
- Increase Memory: 8+ GB
3. **Use `:cached` mount flag** (already configured):
```yaml
- ../..:/workspaces:cached
```
---
### Database Permissions
**Problem**: Can't write to MongoDB or access Mongo Express
**Check credentials**:
```yaml
# MongoDB
MONGO_INITDB_ROOT_USERNAME=admin
MONGO_INITDB_ROOT_PASSWORD=password
# Mongo Express
ME_CONFIG_MONGODB_ADMINUSERNAME=admin
ME_CONFIG_MONGODB_ADMINPASSWORD=password
ME_CONFIG_BASICAUTH_USERNAME=admin
ME_CONFIG_BASICAUTH_PASSWORD=password
```
**Access Mongo Express**:
- URL: http://localhost:8081
- Login: admin / password (HTTP Basic Auth)
---
### VS Code Extensions Not Installing
**Problem**: Extensions listed in devcontainer.json don't install
**Manual install**:
```
F1 → "Extensions: Install Extensions"
Search for extension ID (e.g., "esbenp.prettier-vscode")
```
**Rebuild to retry auto-install**:
```
F1 → "Dev Containers: Rebuild Container"
```
---
## 📚 Related Documentation
- **[Root README](../README.md)** - Project overview and quick start
- **[Backend README](../backend/README.md)** - API server setup
- **[Frontend README](../app/README.md)** - Ionic app setup
- **[Deployment Guide](../DEPLOYMENT.md)** - Production deployment
---
**Need Help?** Check the [root troubleshooting section](../README.md#troubleshooting) for additional solutions.