🎨 Sysprovider Code
Sysprovider LogoWiki
🇪🇸Hosting español para ecommerce

Automatización de despliegue CI/CD para WordPress

Actualizado el 13 de junio de 2026

Introducción a la Automatización de Despliegue CI/CD para WordPress

El desarrollo de WordPress moderno ha evolucionado más allá del simple FTP y el plugin de actualización manual. Hoy, los equipos de desarrollo y los SysAdmins buscan implementar prácticas de Integración Continua y Despliegue Continuo (CI/CD) para garantizar que cada cambio en el código pase por pruebas automatizadas, construcción de assets y despliegues predecibles. Automatizar el pipeline de WordPress no solo acelera el time-to-market, sino que elimina el error humano y asegura la consistencia entre entornos (desarrollo, staging, producción).

En este artículo, exploraremos cómo construir un pipeline CI/CD completo para WordPress utilizando GitHub Actions, Docker, y WP-CLI. Cubriremos desde la estructura del repositorio hasta el despliegue en producción, pasando por estrategias de testing y gestión de secretos. Si eres un DevOps que trabaja con WordPress, este artículo es tu guía definitiva.

Fundamentos del Pipeline CI/CD para WordPress

Antes de escribir código, debemos entender los componentes clave de un pipeline CI/CD WordPress:

  1. Control de Versiones: Git (GitHub, GitLab, Bitbucket).
  2. Integración Continua (CI): Ejecución automática de pruebas y linters cada vez que se hace push o pull request.
  3. Construcción (Build): Compilación de assets (CSS/JS), generación de archivos optimizados y preparación del artefacto.
  4. Despliegue Continuo (CD): Publicación automática en el entorno de staging o producción.
  5. Infraestructura como Código: Uso de contenedores Docker para entornos reproducibles.

[INFO] Un pipeline CI/CD exitoso para WordPress requiere separar el código del tema/plugin de los archivos de WordPress core, que deben gestionarse mediante Composer o contenedores.

Estructura de repositorio recomendada

Para que el pipeline funcione sin fricciones, organiza tu repositorio de la siguiente manera:

/
├── .github/
│   └── workflows/
│       └── deploy.yml          # Pipeline principal
├── web/
│   ├── wp-content/
│   │   ├── themes/
│   │   │   └── mi-tema/        # Tema personalizado
│   │   ├── plugins/
│   │   │   └── mi-plugin/      # Plugin personalizado
│   │   └── uploads/            # Sincronizado con S3/DO Spaces
│   ├── wp-config.php           # Configuración con variables de entorno
│   └── index.php               # Front controller
├── docker/
│   ├── Dockerfile              # Imagen personalizada para WP
│   └── docker-compose.yml      # Entorno local
├── scripts/
│   ├── deploy.sh               # Script de despliegue
│   └── test.sh                 # Script de pruebas
├── composer.json               # Dependencias PHP
├── package.json                # Assets JS/CSS
└── .env.example                # Variables de entorno de ejemplo

GitHub Actions: El Corazón del Pipeline

GitHub Actions es la plataforma de CI/CD nativa de GitHub. Nos permite definir flujos de trabajo (workflows) que se ejecutan en respuesta a eventos como push, pull_request o release.

Workflow básico de CI/CD WordPress

Crea el archivo .github/workflows/deploy.yml con el siguiente contenido:

name: CI/CD WordPress Pipeline

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  # Job 1: Pruebas y linting
  test:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:8.0
        env:
          MYSQL_ROOT_PASSWORD: rootpassword
          MYSQL_DATABASE: wordpress_test
        ports:
          - 3306:3306
        options: --health-cmd="mysqladmin ping" --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'
          tools: composer, wp-cli

      - name: Install dependencies
        run: composer install --no-progress --prefer-dist

      - name: Run PHPCS (WordPress Coding Standards)
        run: |
          vendor/bin/phpcs --standard=WordPress web/wp-content/themes/mi-tema/

      - name: Run unit tests (PHPUnit)
        run: |
          cd web/wp-content/themes/mi-tema
          composer install
          vendor/bin/phpunit

  # Job 2: Build y construcción de assets
  build:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install npm dependencies
        run: npm ci

      - name: Build assets (CSS/JS)
        run: npm run build

      - name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: build-assets
          path: web/wp-content/themes/mi-tema/dist/

  # Job 3: Despliegue en producción
  deploy:
    needs: build
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Download build artifacts
        uses: actions/download-artifact@v4
        with:
          name: build-assets
          path: web/wp-content/themes/mi-tema/dist/

      - name: Deploy via rsync
        env:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
          REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
          REMOTE_USER: ${{ secrets.REMOTE_USER }}
          REMOTE_PATH: ${{ secrets.REMOTE_PATH }}
        run: |
          mkdir -p ~/.ssh
          echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          rsync -avz --delete --exclude='.git*' --exclude='node_modules' --exclude='tests' \
            web/ $REMOTE_USER@$REMOTE_HOST:$REMOTE_PATH

      - name: Run WP-CLI post-deploy commands
        env:
          WP_CLI_URL: ${{ secrets.WP_CLI_URL }}
          WP_CLI_USER: ${{ secrets.WP_CLI_USER }}
          WP_CLI_PASS: ${{ secrets.WP_CLI_PASS }}
        run: |
          ssh $REMOTE_USER@$REMOTE_HOST "cd $REMOTE_PATH && \
            wp cache flush --allow-root && \
            wp rewrite flush --allow-root && \
            wp transient delete --all --allow-root"

[TIP] Usa secrets en GitHub para almacenar credenciales sensibles como claves SSH, contraseñas de base de datos y API keys. Nunca las incluyas en el código.

Docker WordPress: Entornos Reproducibles

Docker es esencial para garantizar que el pipeline CI/CD se ejecute en un entorno idéntico al de producción. En lugar de instalar WordPress manualmente, usamos una imagen Docker con todas las dependencias.

Dockerfile personalizado para WordPress

# Usamos la imagen oficial de WordPress con PHP 8.2
FROM wordpress:6.7-php8.2-apache

# Instalamos herramientas adicionales para CI/CD
RUN apt-get update && apt-get install -y \
    git \
    unzip \
    subversion \
    && rm -rf /var/lib/apt/lists/*

# Instalamos WP-CLI
RUN curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar \
    && chmod +x wp-cli.phar \
    && mv wp-cli.phar /usr/local/bin/wp

# Copiamos la configuración personalizada de PHP
COPY docker/php.ini /usr/local/etc/php/conf.d/custom.ini

# Configuramos Xdebug (opcional, para tests)
RUN pecl install xdebug && docker-php-ext-enable xdebug

WORKDIR /var/www/html

docker-compose.yml para desarrollo local

version: '3.8'

services:
  wordpress:
    build: .
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DEBUG: 1
    volumes:
      - ./web/wp-content:/var/www/html/wp-content
      - ./docker/php.ini:/usr/local/etc/php/conf.d/custom.ini

  db:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
      MYSQL_ROOT_PASSWORD: rootpassword
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

[WARNING] No uses docker-compose.yml en producción. Es solo para desarrollo local. En producción, considera orquestadores como Kubernetes o servicios gestionados como WP Engine.

WP-CLI Automatización: El Multitool de WordPress

WP-CLI es la navaja suiza para automatizar tareas en WordPress. En un pipeline CI/CD, lo usamos para:

  • Sincronizar la base de datos entre entornos.
  • Actualizar plugins y temas.
  • Generar contenido de prueba.
  • Ejecutar migraciones de datos.

Script de post-despliegue con WP-CLI

Crea scripts/post-deploy.sh para ejecutar después de cada despliegue:

#!/bin/bash
set -e

# Variables de entorno (inyectadas por CI/CD)
SITE_URL="${SITE_URL:-https://example.com}"
ADMIN_USER="${ADMIN_USER:-admin}"
ADMIN_PASS="${ADMIN_PASS:-securepassword}"
ADMIN_EMAIL="${ADMIN_EMAIL:-admin@example.com}"

echo "=== Post-deploy WordPress ==="

# 1. Verificar que WP-CLI está disponible
if ! command -v wp &> /dev/null; then
    echo "WP-CLI no encontrado. Instalando..."
    curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
    chmod +x wp-cli.phar
    sudo mv wp-cli.phar /usr/local/bin/wp
fi

# 2. Esperar a que la base de datos esté lista
echo "Esperando conexión a la base de datos..."
until wp db check --allow-root 2>/dev/null; do
    sleep 2
done

# 3. Actualizar la URL del sitio (útil en staging)
wp option update siteurl "$SITE_URL" --allow-root
wp option update home "$SITE_URL" --allow-root

# 4. Activar el tema correcto
wp theme activate mi-tema --allow-root

# 5. Actualizar plugins de forma segura
wp plugin update --all --allow-root

# 6. Limpiar cachés
wp cache flush --allow-root
wp rewrite flush --allow-root

# 7. Crear usuario admin si no existe (solo en staging)
if ! wp user get "$ADMIN_USER" --allow-root 2>/dev/null; then
    wp user create "$ADMIN_USER" "$ADMIN_EMAIL" --role=administrator --user_pass="$ADMIN_PASS" --allow-root
fi

echo "=== Post-deploy completado ==="

Integración del script en GitHub Actions

Añade este paso al job de despliegue:

- name: Run WP-CLI post-deploy script
  run: |
    ssh $REMOTE_USER@$REMOTE_HOST "cd $REMOTE_PATH && bash scripts/post-deploy.sh"
  env:
    SITE_URL: ${{ secrets.SITE_URL }}
    ADMIN_USER: ${{ secrets.ADMIN_USER }}
    ADMIN_PASS: ${{ secrets.ADMIN_PASS }}

Estrategias de Despliegue: Blue-Green y Canary

Para sitios WordPress de alto tráfico, el despliegue directo con rsync puede causar downtime. Implementa estrategias avanzadas:

Blue-Green Deployment

  1. Entorno Azul: Producción activa.
  2. Entorno Verde: Nuevo código desplegado, sin tráfico.
  3. Switch: Cambia el balanceador de carga al entorno verde.
# Fragmento de workflow para Blue-Green
- name: Deploy to Green environment
  run: |
    rsync -avz --delete web/ $REMOTE_USER@$REMOTE_HOST:/var/www/green/

- name: Switch load balancer to Green
  run: |
    ssh $REMOTE_USER@$REMOTE_HOST "sudo systemctl reload nginx-green"

Canary Releases con tráfico gradual

Usa un balanceador de carga (como HAProxy o Nginx) para enviar el 10% del tráfico al nuevo entorno, monitorear errores y luego aumentar al 100%.

[INFO] Para implementar Canary en WordPress, asegúrate de que la base de datos sea compartida y las sesiones de usuario no se pierdan. Usa Redis para caché compartida.

Pruebas Automatizadas en el Pipeline

Un pipeline CI/CD sin pruebas es solo un pipeline de despliegue. WordPress permite varios tipos de testing:

PHPUnit para plugins y temas

<!-- phpunit.xml.dist -->
<phpunit bootstrap="tests/bootstrap.php" colors="true">
    <testsuites>
        <testsuite name="Plugin Test Suite">
            <directory>./tests/</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist>
            <directory>./</directory>
            <exclude>
                <directory>./tests/</directory>
                <directory>./vendor/</directory>
            </exclude>
        </whitelist>
    </filter>
</phpunit>

Pruebas de integración con Cypress (E2E)

Para pruebas de frontend, usa Cypress en un job separado:

e2e-tests:
  runs-on: ubuntu-latest
  services:
    wordpress:
      image: wordpress:6.7-php8.2-apache
      env:
        WORDPRESS_DB_HOST: db
        WORDPRESS_DB_USER: wordpress
        WORDPRESS_DB_PASSWORD: wordpress
        WORDPRESS_DB_NAME: wordpress
  steps:
    - uses: actions/checkout@v4
    - name: Run Cypress tests
      uses: cypress-io/github-action@v6
      with:
        build: npm run build
        start: npm start
        wait-on: 'http://localhost:8080'

Gestión de Secretos y Variables de Entorno

Nunca hardcodees credenciales en tu repositorio. Usa los GitHub Secrets para almacenar:

SecretoDescripción
SSH_PRIVATE_KEYClave privada para acceso SSH al servidor
DB_PASSWORDContraseña de la base de datos de producción
WP_CLI_URLURL del sitio para WP-CLI
S3_ACCESS_KEYClave de acceso a S3 para assets

En tu workflow, referencia los secretos con ${{ secrets.NOMBRE }}.

Monitoreo y Rollback Automatizado

Un buen pipeline incluye monitoreo post-despliegue y capacidad de rollback.

Health check después del despliegue

- name: Health check
  run: |
    STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://example.com)
    if [ "$STATUS" -ne 200 ]; then
      echo "Error: Sitio devolvió código $STATUS"
      exit 1
    fi

Rollback automático

Si el health check falla, revierte el despliegue:

- name: Rollback on failure
  if: failure()
  run: |
    ssh $REMOTE_USER@$REMOTE_HOST "cd $REMOTE_PATH && git checkout HEAD~1 -- web/"
    echo "Rollback ejecutado"

Conclusión: DevOps para WordPress es Real

La automatización de despliegue CI/CD para WordPress ya no es un lujo, es una necesidad para equipos que buscan agilidad y fiabilidad. Con GitHub Actions, Docker, y WP-CLI, puedes construir un pipeline robusto que:

  • Ejecuta pruebas autom

¿Necesitas ayuda?Son dos de nuestros técnicos, Agustín y Mikel, y están disponibles para resolver cualquier problema.

Hablar con ellos ahora
Agustín y Mikel