Categoría: Uncategorized

  • Ensayo de un SDLC en casa

    Plan completo (práctico) para llevar una pequeña aplicación PHP desde el inicio hasta producción

    A continuación tienes un plan detallado, paso a paso, pensado para ensayar en casa todo el ciclo: diseño, desarrollo, control de versiones, pruebas, integración continua, empaquetado, despliegue, monitorización y operativa en producción. Incluyo ejemplos concretos (comandos y ficheros mínimos) que podrás copiar/pegar para practicar.


    1. Definición mínima del proyecto

    Objetivo: una app PHP pequeña (por ejemplo: una “libreta de notas” con autenticación básica y API REST).

    Estructura sugerida:

    project/
    ├─ src/                # código PHP (PSR-4)
    ├─ public/             # index.php, assets
    ├─ config/             # configs (no secretos)
    ├─ tests/              # PHPUnit
    ├─ migrations/         # migraciones DB (Phinx o similar)
    ├─ docker/             # nginx/php config
    ├─ composer.json
    ├─ .env.example
    └─ README.md
    

    Tecnología mínima:

    • PHP 8.1+ (recomiendo 8.2/8.3)
    • Composer
    • MySQL/MariaDB o PostgreSQL
    • Nginx + PHP-FPM (producción)
    • PHPUnit para tests
    • Docker + Docker Compose para reproducibilidad local
    • Git para control de versiones

    2. Inicializar proyecto y herramientas de desarrollo

    Comandos iniciales:

    mkdir project && cd project
    composer init               # crea composer.json
    git init
    echo "vendor/" > .gitignore
    cp /dev/null .env.example   # variables de ejemplo: APP_ENV, DB_*
    

    Dependencias típicas:

    composer require vlucas/phpdotenv        # manejo .env
    composer require slim/slim:"^4.0"       # (o tu micro framework preferido)
    composer require doctrine/dbal          # acceso DB ligero (opcional)
    composer require illuminate/database    # ORM ligero (opcional)
    composer require symfony/console        # comandos CLI (migrations)
    composer require firebase/php-jwt       # auth JWT (opcional)
    composer require monolog/monolog        # logging
    composer require league/oauth2-server   # si quieres oauth (opcional)
    composer require robmorgan/phinx --dev # migraciones (o usar doctrine/migrations)
    composer require phpunit/phpunit --dev  # tests
    composer require phpstan/phpstan --dev  # análisis estático
    

    Configura PSR-4 en composer.json para autoload.


    3. Flujo Git y buenas prácticas

    • Rama principal: main (o master) representa producción.
    • Desarrollo: develop o ramas por feature: feature/*.
    • Pull Requests, revisiones de código y CI obligatorio antes de merge.
    • Tags semánticos: v1.0.0.

    Ejemplo flujo:

    main <- develop <- feature/nota-CRUD
    

    Añade .gitattributes y código de estilo (PHP-CS-Fixer, phpcs).


    4. Tests y calidad (local)

    Implementa:

    • Unit tests (PHPUnit).
    • Integration tests (base de datos en Docker).
    • Static analysis (PHPStan/Psalm).
    • Linter/formatter (PHP-CS-Fixer).

    Comandos típicos:

    vendor/bin/phpunit --colors=always
    vendor/bin/phpstan analyse src --level=max
    vendor/bin/php-cs-fixer fix --dry-run
    

    Incluye tests básicos que cubran endpoints principales y lógica.


    5. Contenerización para desarrollo y para producción

    Crear Dockerfile para la app y docker-compose.yml para orquestar servicio localmente.

    Ejemplo Dockerfile (PHP-FPM, minimal):

    FROM php:8.2-fpm
    
    # Instala extensiones necesarias
    RUN apt-get update && apt-get install -y \
        libzip-dev zip unzip git \
      && docker-php-ext-install pdo_mysql zip
    
    # Composer
    COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
    
    WORKDIR /app
    COPY composer.json composer.lock ./
    RUN composer install --no-dev --optimize-autoloader
    
    COPY . /app
    
    # Opcional: crear usuario no-root
    RUN useradd -m appuser && chown -R appuser:appuser /app
    USER appuser
    
    CMD ["php-fpm"]
    

    Ejemplo docker-compose.yml para desarrollo:

    version: "3.8"
    services:
      app:
        build: .
        volumes:
          - ./:/app
        environment:
          - APP_ENV=development
          - DB_HOST=db
        depends_on:
          - db
      web:
        image: nginx:stable
        ports:
          - "8080:80"
        volumes:
          - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
          - ./:/app:ro
        depends_on:
          - app
      db:
        image: mysql:8
        environment:
          MYSQL_DATABASE: app
          MYSQL_ROOT_PASSWORD: root
        ports:
          - "3306:3306"
        volumes:
          - db_data:/var/lib/mysql
    
    volumes:
      db_data:
    

    Nginx config mínimo apuntando a public/index.php.


    6. Migraciones y gestión de esquema

    Usa Phinx o Doctrine Migrations:

    • Mantén migraciones en migrations/.
    • En CI y deploy: ejecutar migraciones con flag --no-interaction.
    • Versiona migraciones con el repositorio.

    Ejemplo comando:

    vendor/bin/phinx migrate -e production
    

    Practica: crear migración, poblar datos de prueba y ejecutar rollback.


    7. Integración continua (CI)

    Configuración mínima (ejemplo GitHub Actions) con etapas:

    1. checkout
    2. instalar dependencias
    3. ejecución de linter + phpstan
    4. tests (unit + integration con DB en contenedor)
    5. build image (opcional)
    6. security scan (dependabot/composer audit)
    7. push al registry y despliegue (si procede)

    Ejemplo (workflow simplificado): .github/workflows/ci.yml

    name: CI
    
    on: [push, pull_request]
    
    jobs:
      build-test:
        runs-on: ubuntu-latest
        services:
          mysql:
            image: mysql:8
            env:
              MYSQL_DATABASE: app
              MYSQL_ROOT_PASSWORD: root
            ports: ["3306:3306"]
            options: >-
              --health-cmd="mysqladmin ping --silent"
              --health-interval=10s
              --health-timeout=5s
              --health-retries=3
        steps:
          - uses: actions/checkout@v4
          - name: Setup PHP
            uses: shivammathur/setup-php@v2
            with:
              php-version: 8.2
              extensions: mbstring, pdo_mysql
          - name: Install deps
            run: composer install --no-progress --prefer-dist
          - name: Run static analysis
            run: vendor/bin/phpstan analyse src --level=7
          - name: Run tests
            run: vendor/bin/phpunit --coverage-text
    

    Incluye secrets en el repo para despliegue (DOCKER_HUB, SSH key, API keys).


    8. Build y registro de artefactos

    Dos enfoques:

    • Imágenes Docker: Build + push a un registry (DockerHub, GitHub Container Registry).
    • Artefactos: crear tarball con versión.

    Ejemplo: docker build -t myapp:${GITHUB_SHA} . → docker push.

    CI se encarga de versionar la imagen con tag semántico y latest.


    9. Entornos: staging y producción

    Recomendación:

    • Staging: réplica de producción para pruebas end-to-end y smoke tests antes de producción. Tener la misma infra (mismos tipos de instancias/containers).
    • Production: configuraciones seguras, SSL, monitorización.

    Variables de entorno:

    • Mantén .env.example en repo. NO cometas .env real ni secretos.
    • En producción, usa gestores de secretos: Vault, AWS Secrets Manager, GCP Secret Manager o variables de entorno en el servidor/CI.

    10. Estrategias de despliegue y disponibilidad

    Opciones para practicar:

    • Despliegue en VPS (Docker Compose): SSH → pull imagen → docker-compose up -d (simple).
    • Rolling / Blue-Green: despliegue de nueva versión en paralelo, luego cambio de tráfico.
    • Zero-downtime: usando un reverse proxy (Traefik/Nginx+upstream) y healthchecks.
    • Despliegue en PaaS: Heroku/Render/Platform.sh (más sencillo para practicar).

    Practica los pasos:

    1. CI construye y publica image.
    2. SSH/CD runner en el servidor tira la nueva image.
    3. Ejecuta migraciones.
    4. Ejecuta smoke tests.
    5. Si todo ok, marcar release.

    Rollback: mantener la imagen anterior y reimplementarla si falla la versión nueva.


    11. Configuración de producción PHP

    • PHP-FPM con pm = dynamic o static según carga.
    • Opciones: OPCache enabled, realpath_cache_size, memory_limit, max_execution_time ajustados.
    • Logs: separar logs de acceso/error, enviar a central (syslog / log driver / ELK).
    • Timezone, locale en php.ini.

    12. Seguridad y prácticas operativas

    • HTTPS (Let’s Encrypt + Certbot o automatizado por reverse proxy).
    • Firewall mínimo (ufw) y cierre de puertos innecesarios.
    • Gestionar dependencias: composer audit o dependabot.
    • Secrets off-repo.
    • Rate limiting, CSRF tokens, validación de inputs y escaping.
    • Backups automáticos de la base de datos (fecha, retención).
    • Auditoría de logs y rotación (logrotate).

    13. Monitorización, logging y alertas

    • Logs: Monolog a ficheros y/o envío a un servicio (Papertrail, Loggly) o ELK stack.
    • Métricas: Prometheus + exporters (o servicios SaaS).
    • Health checks: endpoint /health que compruebe DB y dependencias.
    • Uptime/Alertas: UptimeRobot o Pingdom.
    • Alertas por correo/Slack/Telegram ante errores críticos y subida de latencia.

    14. Observabilidad y diagnósticos

    • Correlación de request-id (añadir header X-Request-ID).
    • Traceo: integrar OpenTelemetry (opcional) y enviar traces a Jaeger/Zipkin.
    • Perf profiling: xdebug/Blackfire en staging, no en producción.

    15. Respaldo y recuperación (DR)

    • Plan de backups DB diario, con retención.
    • Pruebas periódicas de restore (restore drill) en entorno de staging.
    • Documentar runbook para incidents: cómo revertir, cómo regenerar certificados, cómo restaurar DB.

    16. Checklist para tu sesión práctica en casa

    1. Crear repo y estructura básica.
    2. Implementar un endpoint mínimo y tests unitarios.
    3. Crear Dockerfile + docker-compose y levantar localmente.
    4. Configurar GitHub Actions CI para ejecutar tests y static analysis.
    5. Build y push de imagen a registry local (DockerHub/GHCR).
    6. Montar un servidor VPS (puede ser una VM local) y desplegar con Docker Compose.
    7. Ejecutar migraciones desde CI o manualmente en el servidor.
    8. Configurar nginx/Let’s Encrypt y habilitar HTTPS.
    9. Configurar logs y una herramienta de monitorización simple (UptimeRobot).
    10. Simular rollback: desplegar versión con bug y revertir a versión anterior.
    11. Hacer una “incidente” de prueba: borrar datos y restaurar desde backup.

    17. Ejemplos prácticos rápidos (copiar/pegar)

    Comando para levantar entorno local:

    docker-compose up --build
    # luego visitar http://localhost:8080
    

    Comando para migraciones (ejemplo Phinx):

    vendor/bin/phinx create CreateNotesTable
    vendor/bin/phinx migrate -e development
    vendor/bin/phinx rollback -t 0
    

    Build y push (local):

    docker build -t myuser/myapp:1.0.0 .
    docker push myuser/myapp:1.0.0
    

    Despliegue simple por SSH (script):

    ssh user@server 'docker pull myuser/myapp:1.0.0 && docker-compose -f /srv/myapp/docker-compose.prod.yml up -d'
    

    18. Métricas de éxito y KPIs para tus pruebas

    • Tiempo de despliegue (build → producción).
    • Porcentaje de tests cubiertos por CI.
    • Tiempo medio de respuesta (p99, p95).
    • Disponibilidad (uptime %).
    • Tiempo medio de resolución frente a un fallo.

    19. Siguientes pasos

    Puedo generar ahora mismo (en esta misma respuesta) archivos de ejemplo listos para copiar:

    • Dockerfile completo (producción/dev).
    • docker-compose.yml (dev) y docker-compose.prod.yml.
    • nginx config.
    • phinx migration template.
    • .github/workflows/ci.yml completo.
    • Un Makefile con comandos útiles (make up, make test, make build).