0. Migration Overview
This migration was not a simple frontend switch.
It was a full production architecture upgrade, including:
Data Layer
EC2 local file system → S3 (gp-fileserver)
EC2 MySQL (gp_sales_prod) → ECS-hosted DB (crm-db)
Application Layer Refactoring
PHP monolith backend (main site + console + FX updater)
→ consolidated into ECS: crm-backend
Console frontend (PHP-rendered pages)
→ extracted CRUD-only interface → ECS: crm-web
Next.js main site frontend
→ new independent service ECS: gp-web
Traffic Layer
ALB + Target Groups
ACM certificate issuance
Cloudflare DNS cutover
Gradual EC2 decommission
This was a layered migration across:
Storage
Database
Backend
Frontend
Network
TLS
DNS1. Storage Migration: EC2 → S3
Objective
Decouple file storage from compute instance.
Steps
Identified static and uploaded files in EC2
Synced to S3 bucket:
S3: gp-fileserverUpdated backend file reference logic:
Replace local disk path
Store S3 object key
Tested file upload & retrieval
Key Design Principle
Storage must be stateless
Application containers should not depend on local disk
2. Database Migration: EC2 → ECS DB (crm-db)
Objective
Separate DB from legacy EC2 and prepare for containerized architecture.
Steps
Dump production DB:
mysqldump gp_sales_prod > dump.sqlImport into ECS-hosted MySQL container:
mysql -h <crm-db-host> < dump.sqlResolve collation conflicts:
utf8mb4_0900_ai_ci vs utf8mb4_general_ci
Update application DB connection configs
Lesson
DB migration issues are rarely infrastructure problems;
they are almost always:
Collation mismatch
Foreign key constraints
Charset differences
3. Backend Refactor: PHP Monolith → crm-backend
Legacy structure:
gp_sales_prod (PHP)
- Main site backend
- Admin backend
- FX updaterRefactored into:
ECS: crm-backendRefactoring Goals
Separate business logic from view layer
Remove filesystem dependency
Centralize DB access
Prepare for future Java migration
4. Admin Frontend Simplification → crm-web
Legacy admin frontend was mixed with backend.
Refactored into:
ECS: crm-webScope reduced to:
News CRUD
FX CRUD
Minimal admin UI
Key principle:
Reduce surface area before migration.
5. New Service: Next.js → ECS: gp-web
This was the most complex part.
New Service Required:
New ECS Task Definition
New ECS Service
New Target Group (IP mode)
ALB Listener configuration
ACM certificate
Cloudflare DNS update
6. Network Architecture (Final State)
User
↓
Cloudflare DNS
↓
ALB (Internet-facing)
↓
Target Group (IP mode, HTTP:3000)
↓
ECS gp-web7. Infrastructure Components Created
7.1 ALB
Scheme: Internet-facing
Listener:
HTTPS:443
ACM certificate bound
7.2 Target Group
Target type: IP (Fargate requirement)
Port: 3000
Health check: /
Success codes: 200-399
7.3 ECS
Task Definition:
Container port: 3000
Host binding: 0.0.0.0
Service:
Desired count: 1
Deployment strategy:
Minimum healthy percent = 100
Maximum percent = 200
8. Major Debugging Phases
This migration included layered debugging.
Phase 1: Timeout
Cause:
ALB Security Group missing 443
Fix:
HTTPS 443 → 0.0.0.0/0Phase 2: Certificate Mismatch
Cause:
ACM missing www SAN
Wrong cert bound to listener
Fix:
DNS validation via Cloudflare
Rebind correct ACM cert
Phase 3: 504 Gateway Timeout
Cause:
ALB could not reach ECS port 3000
Fix:
ECS SG inbound TCP 3000 from ALB-SG
Phase 4: 503 Service Unavailable
Cause:
Target draining during deployment
No healthy target
Resolution:
Wait for registration
Adjust deployment config to prevent downtime
9. Final Cutover Strategy
Grey Release Plan
Keep EC2 serving production
Deploy ECS services
Test via ALB DNS
Validate:
File access
DB consistency
Admin CRUD
Switch Cloudflare DNS to ALB
Monitor
Decommission EC2
10. Architectural Evolution
Before:
Single EC2
Filesystem + DB + PHP + FrontendAfter:
S3 (storage)
ECS crm-db (database)
ECS crm-backend (API)
ECS crm-web (admin)
ECS gp-web (frontend)
ALB
Cloudflare DNS
ACM TLS11. DevOps Maturity Achieved
This migration demonstrates capability in:
Layered infrastructure design
Zero-downtime deployment logic
Security Group modeling
Health check debugging
TLS and DNS validation
Stateful → stateless transformation
12. Most Valuable Insight
Error type maps directly to architectural layer:
Understanding this mapping reduced debugging time dramatically.