Fecha: Diciembre 2025 Objetivo: Documentar dependencias y requisitos para migrar repositorios de GitLab a GitHub y configurar ambiente de desarrollo local.
MPAY es una plataforma BNPL (Buy Now Pay Later) compuesta por 5 microservicios con arquitectura event-driven. Actualmente los repositorios estan en GitLab con CI/CD configurado usando templates compartidos.
| Servicio | Tecnologia | Puerto | Funcion |
|---|---|---|---|
| api-laravel | PHP 8.2 / Laravel 10 | 8051 | API principal, logica de negocio |
| back-office | PHP 8.2 / Laravel 10 + Nova + Vue 3 | 80 | Panel de administracion |
| database-laravel | Laravel Package | - | Migraciones y esquema DB compartido |
| documents-ocr | Python 3.13 / FastAPI | 8000 | OCR con Google Gemini AI |
| onboarding | Next.js 14 / React 18 | 3000 | App de solicitud de credito |
Ubicacion actual: elaniin/mercandu-pay/n1co/gitlab-configs
Los 4 servicios principales dependen de templates compartidos:
# Templates usados por api-laravel y back-office
- '/templates/php/Setup.gitlab-ci.yml' # Instalacion de dependencias PHP
- '/templates/php/Scan.gitlab-ci.yml' # Analisis estatico de codigo
- '/templates/php/Test-pest.gitlab-ci.yml' # Tests con Pest
- '/templates/php/Test.gitlab-ci.yml' # Tests con PHPUnit
- '/templates/Security.gitlab-ci.yml' # Escaneo de seguridad
- '/templates/Build.gitlab-ci.yml' # Build de Docker
- '/templates/Deploy.gitlab-ci.yml' # Deploy a Kubernetes
# Templates usados por onboarding y documents-ocr
- '/templates/Custom-Build.gitlab-ci.yml' # Build personalizado
- '/templates/Deploy.gitlab-ci.yml' # Deploy a KubernetesACCION REQUERIDA:
- Migrar repositorio
gitlab-configsa GitHub - Convertir templates de GitLab CI a GitHub Actions
Registry actual: registry.gitlab.com/elaniin/mercandu-pay/n1co/
Imagenes usadas en CI:
gitlab-ci-images:8.2.1-php-fpm(PHP para CI)
ACCION REQUERIDA:
- Migrar imagenes a GitHub Container Registry (ghcr.io)
- O usar Docker Hub / AWS ECR
Ubicacion: git@gitlab.com:elaniin/mercandu-pay/n1co/database-laravel.git
Usado como dependencia Composer en:
- api-laravel
- back-office
// composer.json
"repositories": [
{
"type": "vcs",
"url": "git@gitlab.com:elaniin/mercandu-pay/n1co/database-laravel.git"
}
]ACCION REQUERIDA:
- Migrar repositorio a GitHub
- Actualizar URL en composer.json de ambos proyectos
- Configurar GitHub token para acceso privado
| Variable | Uso | Servicio |
|---|---|---|
GITLAB_TOKEN |
Acceso a paquetes privados Composer | api-laravel, back-office |
NOVA_USERNAME |
Credenciales Laravel Nova | back-office |
NOVA_LICENSE_KEY |
Licencia Laravel Nova (paga) | back-office |
# Base de datos
DB_CONNECTION=mysql
DB_HOST=
DB_PORT=3306
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=
# Servidor
SERVER_PORT=8051
SERVER_HOST=0.0.0.0
APP_KEY= # Clave de encriptacion Laravel
# Cache/Queue
REDIS_HOST=
REDIS_PORT=6379
QUEUE_CONNECTION=redis # Produccion
# SMS (Tigo)
TIGO_DOMAIN=
TIGO_REMITENTE=
TIGO_USERNAME=
TIGO_PASSWORD=
# AWS S3
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
# URLs internas
DASHBOARD_URL=
PAYMENT_URL=# Todo lo anterior de api-laravel, mas:
# Conexion a API core
APP_CORE_URL=http://localhost:8051
# Laravel Nova
NOVA_LICENSE_KEY=
NOVA_STORAGE_DISK=
# Keycloak SSO
KEYCLOAK_CLIENT_ID=
KEYCLOAK_CLIENT_SECRET=
KEYCLOAK_REDIRECT_URI=
KEYCLOAK_BASE_URL=
KEYCLOAK_REALM=
KEYCLOAK_CACHE_TOKEN=
KEYCLOAK_PUBLIC_KEY_NAME=keycloak-public.key# Build-time variables (prefijo NEXT_PUBLIC_)
NEXT_PUBLIC_CORE_URL=
NEXT_PUBLIC_WEB_URL=
NEXT_PUBLIC_PUBLIC_URL=
NEXT_PUBLIC_API_URL=
NEXT_PUBLIC_PAY_WEB=
NEXT_PUBLIC_AVAILABLE_COUNTRIES=SV,HN
NEXT_PUBLIC_APP_DOMAIN=
NEXT_PUBLIC_MIXPANEL_TOKEN=
NEXT_PUBLIC_PRODUCT_ID=
NEXT_PUBLIC_PRODUCT_NAME=# Google Cloud
PROJECT_ID=
LOCATION=us-central1
BUCKET_NAME=
GOOGLE_APPLICATION_CREDENTIALS=/path/to/sa.jsonLos deployments requieren secretos montados como volumenes:
# api-laravel deployment
volumes:
- name: keycloak-public-key
secret:
secretName: dev-keycloak-public-key
- name: oauth-private-key
secret:
secretName: dev-oauth-private-key
- name: oauth-public-key
secret:
secretName: dev-oauth-public-keySecretos K8s requeridos:
{env}-keycloak-public-key- Llave publica de Keycloak{env}-oauth-private-key- Llave privada OAuth (Passport){env}-oauth-public-key- Llave publica OAuth{env}-pay-api-laravel-config- ConfigMap con variables de entorno{env}-pay-back-office-config- ConfigMap para back-office
| Servicio | Proposito | Proveedor |
|---|---|---|
| MySQL 8.0 | Base de datos | AWS RDS / DigitalOcean |
| Redis | Cache y colas | AWS ElastiCache / DO Redis |
| Kubernetes | Orquestacion | AWS EKS / DigitalOcean K8s |
| Container Registry | Imagenes Docker | GitLab Registry -> GitHub/AWS ECR |
| Servicio | Proposito | Configuracion |
|---|---|---|
| Keycloak | OAuth 2.0 / SSO | Self-hosted o Keycloak Cloud |
| Equifax | Buro de credito | API con credenciales |
| Tigo | SMS El Salvador | API con credenciales |
| Twilio | SMS alternativo | API con credenciales |
| AWS S3 | Almacenamiento documentos | Access key + Secret |
| Google Cloud | OCR con Gemini AI | Service Account JSON |
| Mixpanel | Analytics | Token publico |
| Sentry | Error tracking | DSN |
setup -> sca -> test -> build -> security -> deploy
- setup: Instalar dependencias (Composer/npm)
- sca: Static Code Analysis (linting)
- test: Unit tests (Pest/PHPUnit/Jest)
- build: Docker build + push a registry
- security: Escaneo de vulnerabilidades
- deploy: Deploy a Kubernetes
| Branch | Ambiente | Dominio |
|---|---|---|
develop, feature/* |
development | *.mdu.dev |
staging |
staging | *.mdu.stg |
main |
production | *.mercandu.com |
| Servicio | Desarrollo | Produccion |
|---|---|---|
| api-laravel | backend.pay.mdu.dev |
backend.pay.mercandu.com |
| back-office | dashboard.pay.mdu.dev |
dashboard.pay.mercandu.com |
| onboarding | onboarding.pay.mdu.dev |
onboarding.pay.mercandu.com |
| documents-ocr | documents-ocr-api.mdu.dev |
documents-ocr-api.mercandu.com |
Composer dependencies principales:
{
"php": "^8.2",
"laravel/framework": "^10.0",
"laravel/octane": "^1.3", // Servidor Swoole
"laravel/horizon": "^5.10", // Job queues
"laravel/passport": "^11.0", // OAuth2
"firebase/php-jwt": "^6.3",
"mercandu-pay/database-laravel": "dev-develop", // Paquete privado
"sentry/sentry-laravel": "^3.1",
"twilio/sdk": "^6.43",
"spatie/laravel-permission": "^5.5",
"maatwebsite/excel": "^3.1",
"spatie/laravel-google-cloud-storage": "^2.3"
}Extensiones PHP requeridas:
- redis, openswoole
- intl, gd, pdo_mysql, mysqli
- zip, gmp, pcntl, bcmath
Composer adicionales:
{
"laravel/nova": "~4.0", // Panel admin (licencia paga)
"socialiteproviders/keycloak": "^5.2"
}npm dependencies:
- Vue 3, Inertia.js, TailwindCSS
- Vite para build de assets
Nova Components personalizados:
nova-components/
├── PermissionPicker/
├── Picker/
├── DecisionRuleField/
└── ConditionalBuilder/
{
"next": "14.2.4",
"react": "^18",
"tailwindcss": "^3.4.1",
"react-hook-form": "^7.52.1",
"zod": "^3.23.8",
"mixpanel-browser": "^2.55.0",
"framer-motion": "^11.2.13",
"@radix-ui/react-*": "varios"
}fastapi
uvicorn
google-cloud-storage
google-genai
python-magic
python-multipart
- Docker & Docker Compose
- PHP 8.2 + Composer 2.7 (opcional, para CLI)
- Node.js 16+ y npm
- Python 3.13
- MySQL 8.0 o Docker container
- Redis o Docker container
git clone git@github.com:org/mpay.git
cd mpay# Opcion A: Usar docker-compose de api-laravel
cd api-laravel
docker-compose up -d mysql redis
# Opcion B: Docker standalone
docker run -d --name mysql -p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=password \
-e MYSQL_DATABASE=laravel \
mysql:8.0
docker run -d --name redis -p 6379:6379 redis:alpinecd api-laravel
# Copiar .env
cp .env.example .env
# Configurar acceso a paquete privado
composer config gitlab-token.gitlab.com YOUR_TOKEN
# O para GitHub:
composer config github-oauth.github.com YOUR_GITHUB_TOKEN
# Instalar dependencias
composer install
# Generar key y migrar
php artisan key:generate
php artisan vendor:publish --tag=mercandu-pay-database
php artisan migrate
# Iniciar servidor (development)
php artisan serve --port=8051
# O con Octane (produccion-like)
php artisan octane:start --port=8051cd back-office
cp .env.example .env
# Credenciales Nova
composer config http-basic.nova.laravel.com "$NOVA_USERNAME" "$NOVA_LICENSE_KEY"
composer config gitlab-token.gitlab.com YOUR_TOKEN
composer install
npm install
npm run dev # Compilar assets
php artisan key:generate
php artisan vendor:publish --tag=mercandu-pay-database
php artisan migrate
php artisan serve --port=8050cd onboarding
# Crear .env.local con variables NEXT_PUBLIC_*
npm install
npm run dev # Puerto 3000cd documents-ocr
python -m venv venv
source venv/bin/activate # Linux/Mac
pip install -r requirements.txt
# Configurar credenciales Google Cloud
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/sa.json
export PROJECT_ID=your-project
export BUCKET_NAME=your-bucket
python main.py # Puerto 8000| Tarea | Complejidad | Responsable |
|---|---|---|
| Crear organizacion/repos en GitHub | Baja | DevOps |
Migrar repositorio gitlab-configs |
Media | DevOps |
Migrar repositorio database-laravel |
Baja | DevOps |
| Crear GitHub Actions equivalentes a templates | Alta | DevOps |
| Configurar GitHub Container Registry | Baja | DevOps |
| Configurar secretos en GitHub | Baja | DevOps |
| Servicio | Complejidad | Notas |
|---|---|---|
| documents-ocr | Baja | Sin dependencias GitLab especiales |
| onboarding | Baja | Solo variables de build |
| api-laravel | Media | Dependencia de database-laravel |
| back-office | Alta | Nova license + Keycloak + database-laravel |
| Tarea | Complejidad | Detalle |
|---|---|---|
| Crear workflows de GitHub Actions | Alta | 4 servicios x 3 ambientes |
| Configurar deploy a K8s desde GitHub | Media | Secrets de kubeconfig |
| Testing de pipelines en desarrollo | Media | |
| Cutover a produccion | Alta | Coordinacion con equipo |
GitLab CI actual (.gitlab-ci.yml):
image: registry.gitlab.com/elaniin/mercandu-pay/n1co/gitlab-ci-images:8.2.1-php-fpm
stages:
- setup
- test
- build
- deploy
include:
- project: elaniin/mercandu-pay/n1co/gitlab-configs
file: '/templates/php/Setup.gitlab-ci.yml'GitHub Actions equivalente (.github/workflows/ci.yml):
name: CI/CD
on:
push:
branches: [main, develop, 'feature/**']
pull_request:
branches: [main, develop]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
setup:
runs-on: ubuntu-latest
container:
image: php:8.2-fpm
steps:
- uses: actions/checkout@v4
- name: Install Composer
run: curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
- name: Configure Composer
run: |
composer config github-oauth.github.com ${{ secrets.COMPOSER_GITHUB_TOKEN }}
- name: Install dependencies
run: composer install --no-dev --optimize-autoloader
- uses: actions/cache@v4
with:
path: vendor
key: vendor-${{ hashFiles('composer.lock') }}
test:
needs: setup
runs-on: ubuntu-latest
services:
mysql:
image: mysql:8.0
env:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: testing
ports:
- 3306:3306
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: vendor
key: vendor-${{ hashFiles('composer.lock') }}
- name: Run tests
run: vendor/bin/pest
build:
needs: test
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
build-args: |
GITHUB_TOKEN=${{ secrets.COMPOSER_GITHUB_TOKEN }}
DATABASE_PROJECT_BRANCH=develop
deploy-dev:
needs: build
if: github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest
environment: development
steps:
- name: Deploy to K8s
uses: azure/k8s-deploy@v4
with:
manifests: .k8s/dev/
images: ghcr.io/${{ github.repository }}:${{ github.sha }}| Actividad | Horas Estimadas | Equipo |
|---|---|---|
| Crear estructura en GitHub | 4h | DevOps |
| Migrar repositorios (5) | 2h | DevOps |
| Convertir 6 templates CI a Actions | 24h | DevOps |
| Crear workflows por servicio (4) | 16h | DevOps |
| Configurar secretos/variables | 4h | DevOps |
| Migrar Container Registry | 4h | DevOps |
| Actualizar referencias en codigo | 8h | Dev |
| Testing de pipelines (dev) | 16h | DevOps + Dev |
| Testing de pipelines (stg/prd) | 8h | DevOps |
| Documentacion | 8h | DevOps + Dev |
| TOTAL | 94h (~12 dias) |
| Servicio | Complejidad | Razon |
|---|---|---|
| documents-ocr | Baja | Python simple, sin dependencias privadas |
| onboarding | Baja | Next.js estandar, solo env vars |
| api-laravel | Media | Paquete privado, Kubernetes config |
| back-office | Alta | Nova license, Keycloak, paquete privado, Vue build |
| Riesgo | Impacto | Mitigacion |
|---|---|---|
| Licencia Nova expira durante migracion | Alto | Verificar renovacion antes de migrar |
| Secrets perdidos o mal configurados | Alto | Documentar todos los secrets, backup |
| Downtime durante cutover | Medio | Hacer cutover en horario de baja carga |
| Falla en deploy a K8s desde GitHub | Medio | Mantener GitLab funcional como fallback |
| Dependencias no resueltas en GitHub | Alto | Probar build local antes de migrar CI |
- Crear organizacion en GitHub
- Crear todos los repositorios vacios
- Configurar GitHub Container Registry
- Obtener/renovar licencia Laravel Nova
- Documentar todos los secretos actuales
- Exportar variables de CI/CD de GitLab
- Push de codigo a GitHub (todos los repos)
- Migrar database-laravel primero
- Actualizar composer.json con nueva URL
- Crear GitHub Actions workflows
- Configurar secrets en GitHub
- Build y test en desarrollo
- Verificar deploys a development
- Verificar deploys a staging
- Cutover de produccion
- Deshabilitar pipelines de GitLab
- Actualizar documentacion interna
- Archivar repositorios en GitLab
- Fineract API: https://fineract.apache.org/docs/current/
- Laravel Nova: https://nova.laravel.com/docs
- Next.js: https://nextjs.org/docs
- GitHub Actions: https://docs.github.com/en/actions
MPAY_DOCUMENTATION.md- Documentacion general del sistemaapi-laravel/.k8s/- Manifiestos Kubernetes*/Dockerfile- Configuracion de contenedores*/.gitlab-ci.yml- Pipelines actuales (referencia)
Documento generado automaticamente - Diciembre 2025