Desarrollo y bases de datos
Despliegue automático con Deployer.org para cualquier app
Importante: Actualmente dispones de la herramienta Deploy un sistema avanzado y sencillo de usar que se integra a la perfección con tu repositorio de GitHub, más información en Deploy, herramienta de desplieque automático desde GitHub
Deployer.org es una potente herramienta de despliegue escrita en PHP que automatiza el proceso de llevar tus aplicaciones a servidores.
Este manual te guiará a través del proceso, destacando los puntos clave y posibles desafíos, así como ejemplificando el despligue de dos apps ejemplo, una en WordPress y otra usando Laravel.
Ventajas de usar Deployer:
- Automatización: Reduce tareas manuales y propensas a errores.
- Despliegues Zero-Downtime: Mediante el uso de symlinks, tu sitio permanece online durante la actualización.
- Rollbacks: Permite revertir a una versión anterior fácilmente si algo sale mal.
- Recetas predefinidas: Incluye configuraciones base para frameworks populares como Laravel y WordPress.
- Consistencia: Asegura que el proceso de despliegue sea el mismo cada vez.
- Entornos de staging: Permite crear automáticamente dominios y bases de datos para pruebas.
No todos los servicios de hosting con cPanel serán compatibles o adecuados para Deployer. En nuestro caso, todos nuestros servicios de hosting lo son, por lo que podrás usarlo sin mayor problema.
Acceso SSH
El acceso SSH es esencial para trabajar con Deployer.org, por ello lo primero es revisar que lo tienes activo en tu cuenta:
Y por otro que has configurado tu equipo para conectar por medio de claves, lo que facilitará el uso (puedes conectar vía contraseña, pero tendrás que estar de forma continua introduciendo la misma):
Instalación de Deployer
Antes de configurar el archivo de despliegue, necesitas instalar Deployer en tu máquina local. Puedes hacerlo de varias formas:
Opción 1: Instalación global con Composer
composer global require deployer/deployer
Opción 2: Descarga directa del PHAR
curl -LO https://deployer.org/deployer.phar mv deployer.phar /usr/local/bin/dep chmod +x /usr/local/bin/dep
Opción 3: Como dependencia del proyecto
composer require --dev deployer/deployer
Una vez instalado, verifica que funciona ejecutando:
dep --version
Configuración Básica del Archivo deploy.php
Para comenzar, necesitas crear un archivo deploy.php en la raíz de tu proyecto local. Este archivo contendrá toda la configuración necesaria para conectar con tu servidor cPanel y definir las tareas de despliegue.
Una vez configurado, podrás ejecutar comandos como:
dep deploy- Para desplegar tu aplicacióndep rollback- Para revertir al despliegue anteriordep pwd- Para verificar la conexión y ver el directorio actualdep ls- Para listar archivos en el servidor
<?php namespace Deployer; require 'recipe/common.php'; set('shared_files', []); set('shared_dirs', []); set('writable_dirs', []); set('ssh_multiplexing', false); set('git_ssh_command', 'ssh'); host('tu_dominio_o_ip_cpanel') ->set('remote_user', 'tu_usuario_cpanel') ->set('port', 93) ->set('identity_file', '~/.ssh/id_rsa_cpanel') // Ruta a tu clave privada para cPanel ->set('deploy_path', '/home/tu_usuario_cpanel/ruta_despliegue') // IMPORTANTE: Ruta base para Deployer ->set('http_user', 'tu_usuario_cpanel'); // Usuario bajo el cual corre el servidor web // Tareas task('pwd', function () { $result = run('pwd'); writeln("Current directory: {$result}"); }); task('ls', function () { $result = run('ls -la'); writeln("{$result}"); }); // Notificar al final after('deploy:failed', 'deploy:unlock');
Explicación de Parámetros Clave para cPanel:
remote_user: Tu nombre de usuario de cPanel (el que usas para SSH).identity_file: La ruta en tu máquina local a la clave SSH privada que configuraste para cPanel.deploy_path: Esta es la ruta en el servidor cPanel donde Deployer creará su estructura (releases,shared,current). No pongas esto directamente enpublic_htmlinicialmente. Es mejor una carpeta separada, por ejemplo:/home/tu_usuario_cpanel/my_laravel_appo/home/tu_usuario_cpanel/my_wordpress_site.http_user: El usuario con el que Apache/LiteSpeed ejecuta los scripts PHP. El mismo que tu usuario de cPanel.
Para comprobar que funciona correctamente, puedes ejecutar dep ls lo que debería devolver el listado de ficheros y durectorios del servicio de hosting.
Importante: Diferencias entre Dominios en cPanel
Antes de continuar, es crucial entender las diferencias entre tipos de dominios en cPanel:
-
Dominio Principal: Es el dominio asociado a tu cuenta de hosting. Su DocumentRoot está forzado a ser
/home/tu_usuario_cpanel/public_htmly no se puede cambiar. Si quieres usar Deployer con el dominio principal, necesitarás usar el método de symlink. -
Dominios Addon (Adicionales): Son dominios extra que puedes agregar a tu cuenta. Estos SÍ permiten cambiar el DocumentRoot a cualquier directorio que desees, incluso fuera de
public_html. Con dominios addon, puedes apuntar directamente a{{deploy_path}}/current. -
Subdominios: Generalmente funcionan como los dominios addon y permiten cambiar el DocumentRoot libremente.
Recomendación: Si planeas usar Deployer intensivamente, considera usar un dominio addon en lugar del dominio principal para evitar las limitaciones de public_html.
Configuración Avanzada con cPanel Recipe
Deployer incluye una receta específica para cPanel que automatiza la creación de dominios addon y bases de datos, especialmente útil para entornos de staging. Esta funcionalidad utiliza la API de cPanel v2 para gestionar recursos automáticamente.
Configuración de la Receta cPanel
<?php namespace Deployer; require 'recipe/common.php'; require 'contrib/cpanel.php'; set('cpanel', [ 'host' => getenv('CPANEL_HOST'), 'port' => getenv('CPANEL_PORT'), 'username' => getenv('CPANEL_USERNAME'), 'auth_type' => getenv('CPANEL_AUTH_TYPE'), 'token' => getenv('CPANEL_TOKEN'), 'user' => getenv('CPANEL_USER'), 'db_user' => getenv('CPANEL_DB_USER'), 'db_user_privileges' => getenv('CPANEL_DB_PRIVILEGES'), 'timeout' => 500, 'allowInStage' => ['staging', 'beta', 'alpha'], 'create_domain_format' => '%s-%s-%s', 'create_domain_values' => ['staging', 'master', get('application')], 'subdomain_prefix' => substr(md5(get('application')), 0,4) . '-', 'subdomain_suffix' => getenv('SUBDOMAIN_SUFFIX'), 'create_db_format' => '%s_%s-%s-%s', 'create_db_values' => ['apps', 'staging','master', get('application')], ]);
Variables de Entorno para cPanel API
Crea un archivo .env en tu proyecto local con las credenciales de cPanel:
CPANEL_HOST=tu_servidor_cpanel.com CPANEL_PORT=2083 CPANEL_USERNAME=tu_usuario_cpanel CPANEL_TOKEN=tu_token_api_cpanel CPANEL_USER=tu_usuario_cpanel CPANEL_AUTH_TYPE=hash CPANEL_DB_USER=usuario_db CPANEL_DB_PRIVILEGES="ALL PRIVILEGES" SUBDOMAIN_SUFFIX=.tudominio.com
Tareas Disponibles de cPanel
La receta de cPanel proporciona las siguientes tareas automáticas:
cpanel:createaddondomain: Crea un dominio addon automáticamentecpanel:deleteaddondomain: Elimina un dominio addoncpanel:createdb: Crea una nueva base de datos
Configuración de Staging Automático
host('staging.tudominio.com') ->stage('staging') ->set('cpanel_createdb', vsprintf(get('cpanel')['create_db_format'], get('cpanel')['create_db_values'])) ->set('branch', 'develop') ->set('deploy_path', '~/staging/' . vsprintf(get('cpanel')['create_domain_format'], get('cpanel')['create_domain_values'])) ->set('addondir', 'staging/' . vsprintf(get('cpanel')['create_domain_format'], get('cpanel')['create_domain_values'])); // Automatizar la creación de recursos en staging after('deploy:prepare', 'cpanel:createaddondomain'); after('deploy:prepare', 'cpanel:createdb');
Despliegue de WordPress con Deployer en cPanel
Configuración para WordPress
<?php namespace Deployer; require 'recipe/wordpress.php'; // Receta específica para WordPress require 'recipe/common.php'; // Siempre necesaria // Configuración General (Adaptar si es necesario) set('application', 'MiWordPress'); set('repository', 'git@github.com:tu_usuario/tu_repo_wordpress.git'); // URL de tu repositorio Git // Archivos y directorios compartidos específicos de WordPress set('shared_files', ['wp-config.php']); // wp-config.php se gestiona en 'shared' set('shared_dirs', ['wp-content/uploads']); // Carpeta de subidas es compartida // Directorios con permisos de escritura set('writable_dirs', ['wp-content/uploads']); // Host (Adaptar a tu configuración de cPanel) host('tu_dominio_o_ip_cpanel') ->set('remote_user', 'tu_usuario_cpanel') ->set('port', 93) ->set('identity_file', '~/.ssh/id_rsa_cpanel') ->set('deploy_path', '/home/tu_usuario_cpanel/mi_wordpress_deploy') // Carpeta base para este sitio WP ->set('http_user', 'tu_usuario_cpanel'); // Tareas personalizadas (si son necesarias) // Ejemplo: Si WP-CLI no está global, podrías necesitar definir su ruta // set('bin/wp', '/home/tu_usuario_cpanel/wp-cli.phar'); // Configurar DocumentRoot en cPanel // Debes configurar el DocumentRoot de tu dominio/subdominio en cPanel // para que apunte a: /home/tu_usuario_cpanel/mi_wordpress_deploy/current // Si no puedes cambiar el DocumentRoot, necesitarás un .htaccess en public_html (ver sección abajo) // Notificar al final after('deploy:failed', 'deploy:unlock'); desc('Deploy WordPress'); task('deploy', [ 'deploy:prepare', 'deploy:vendors', // Si usas composer para gestionar WordPress o plugins 'deploy:shared', 'deploy:writable', 'deploy:publish', ]);
Preparación en cPanel
Base de Datos: Crea una base de datos y un usuario para WordPress usando las herramientas de "MySQL Databases" en cPanel. Anota el nombre de la base de datos, el usuario y la contraseña.
Directorio de Despliegue: Asegúrate de que la ruta que especificaste en deploy_path (ej. /home/tu_usuario_cpanel/mi_wordpress_deploy) exista o que Deployer tenga permisos para crearla.
wp-config.php inicial:
- Conéctate por SSH a tu servidor.
- Navega a
{{deploy_path}}/shared(ej./home/tu_usuario_cpanel/mi_wordpress_deploy/shared). Si no existe, créalo:mkdir -p /home/tu_usuario_cpanel/mi_wordpress_deploy/shared. - Crea un archivo
wp-config.phpdentro desharedcon los datos de la base de datos de cPanel y las sales de WordPress. Puedes copiar unwp-config-sample.phpy modificarlo.
<?php define('DB_NAME', 'tu_basedatos_cpanel'); define('DB_USER', 'tu_usuario_db_cpanel'); define('DB_PASSWORD', 'tu_contraseña_db_cpanel'); define('DB_HOST', 'localhost'); // Usualmente localhost en cPanel define('DB_CHARSET', 'utf8mb4'); define('DB_COLLATE', ''); // Sales de WordPress (generarlas desde https://api.wordpress.org/secret-key/1.1/salt/) define('AUTH_KEY', 'pon_tu_sal_aqui'); // ... (resto de sales) ... define('NONCE_SALT', 'pon_tu_sal_aqui'); $table_prefix = 'wp_'; // O el prefijo que desees define('WP_DEBUG', false); if ( ! defined( 'ABSPATH' ) ) { define( 'ABSPATH', __DIR__ . '/' ); } require_once ABSPATH . 'wp-settings.php';
Configurar DocumentRoot:
- En cPanel, ve a "Dominios".
- Para dominios addon (adicionales): Puedes cambiar fácilmente el DocumentRoot para que apunte a
/home/tu_usuario_cpanel/mi_wordpress_deploy/current. Los dominios addon no están restringidos apublic_html. - Para el dominio principal: Está forzado a usar
public_htmlcomo DocumentRoot. En este caso, utiliza el método de symlink que se explica más adelante. - Para subdominios: Generalmente puedes cambiar el DocumentRoot, similar a los dominios addon.
Ejecutar el Despliegue
Desde tu máquina local, en la terminal, navega a la raíz de tu proyecto WordPress (donde está deploy.php) y ejecuta:
dep deploy
Si todo va bien, Deployer clonará tu repositorio, instalará dependencias (si aplica), creará los symlinks para wp-config.php y uploads, y finalmente apuntará el symlink current a la nueva release.
Configurar DocumentRoot con Symlink (Solo para Dominio Principal)
Importante: Este método solo es necesario para el dominio principal de tu cuenta cPanel, que está forzado a usar public_html. Los dominios addon y subdominios pueden cambiar directamente su DocumentRoot sin necesidad de symlinks.
Si tu dominio principal no puede cambiar el DocumentRoot en cPanel, la mejor solución es crear un symlink desde public_html hacia tu directorio de despliegue. Esto se puede automatizar desde Deployer:
Pasos:
-
Configura tu
deploy_pathfuera depublic_html, por ejemplo:/home/tu_usuario_cpanel/mi_wordpress_deploy -
Agrega esta tarea personalizada a tu
deploy.php:
// Tarea para crear symlink de public_html task('cpanel:symlink:public_html', function () { $publicHtmlPath = '/home/{{remote_user}}/public_html'; $deployCurrentPath = '{{deploy_path}}/current'; $temporaryLinkPath = $publicHtmlPath . '.next-' . date('Y-m-d_H-i-s'); if (!test("[ -d $deployCurrentPath ] && [ -f $deployCurrentPath/wp-settings.php ]")) { throw new \RuntimeException('El destino de WordPress no está completo'); } if (test("[ -d $publicHtmlPath ] && [ ! -L $publicHtmlPath ]")) { run("mv $publicHtmlPath {$publicHtmlPath}_backup_" . date('Y-m-d_H-i-s')); writeln("✅ Backup de public_html creado"); } run("ln -s $deployCurrentPath $temporaryLinkPath"); run("mv -Tf $temporaryLinkPath $publicHtmlPath"); if (!test("[ \"$(readlink -f $publicHtmlPath)\" = \"$(readlink -f $deployCurrentPath)\" ]")) { throw new \RuntimeException('No se pudo validar el enlace de public_html'); } writeln("✅ Symlink de public_html creado correctamente"); })->desc('Crear symlink de public_html hacia current'); // Ejecutar después de deploy:symlink after('deploy:symlink', 'cpanel:symlink:public_html');
- Importante: ejecuta primero
dep deploy --dry-run, revisa las rutas y crea una copia verificada de ficheros y base de datos. Antes del primer despliegue, conecta por SSH y renombra tupublic_htmlactual:
cd /home/tu_usuario_cpanel
mv public_html public_html_backup_manual
- Ejecuta el despliegue primero en staging. En producción, valida el destino, el enlace, la portada,
wp-adminy los logs antes de eliminar el backup. Si falla, ejecutadep rollback; para recuperar el directorio original, retira únicamente el symlink verificado y renombrapublic_html_backup_manualde nuevo apublic_html.
Ahora cuando ejecutes dep deploy, Deployer automáticamente:
- Hará el backup de
public_html(si existe) - Creará un symlink desde
public_htmlhacia{{deploy_path}}/current - Tu sitio servirá desde el directorio de despliegue actual
Ventajas de este método:
- Cambio atómico del enlace cuando el sistema admite
mv -T - No requiere cambios en el servidor web
- Funciona con cualquier proveedor de cPanel
- Posibilidad de rollback a una release anterior
- No hay problemas de rutas como con
.htaccess
Tareas Post-Despliegue
- Accede a tu sitio WordPress para completar la instalación si es la primera vez (ej.
tudominio.com/wp-admin/install.php). - Verifica que los permisos en
wp-content/uploadspermitan subir archivos.
Despliegue de Laravel con Deployer en cPanel
Configuración para Laravel
<?php namespace Deployer; require 'recipe/laravel.php'; // Receta específica para Laravel require 'recipe/common.php'; // Siempre necesaria // Configuración del proyecto set('application', 'MiLaravelApp'); set('repository', 'git@github.com:tu_usuario/tu_repo_laravel.git'); // URL de tu repositorio Git set('php_fpm_service', ''); // En cPanel no gestionamos PHP-FPM directamente así // Hosts (Adaptar a tu configuración de cPanel) host('tu_dominio_o_ip_cpanel') ->set('remote_user', 'tu_usuario_cpanel') ->set('port', 93) ->set('identity_file', '~/.ssh/id_rsa_cpanel') ->set('deploy_path', '/home/tu_usuario_cpanel/mi_laravel_deploy') // Carpeta base para esta app Laravel ->set('http_user', 'tu_usuario_cpanel'); // Tarea para symlinkear el storage (si no lo hace la receta por defecto correctamente en cPanel) task('artisan:storage:link:manual', function () { writeln("Recordatorio: Asegúrate que el enlace simbólico de 'storage' está correctamente configurado y accesible."); writeln("Si usas la receta de Laravel, debería intentar crear 'current/public/storage' -> 'shared/storage/app/public'."); writeln("Verifica que tu DocumentRoot en cPanel apunte a 'current/public'."); }); // Configurar DocumentRoot en cPanel // Debes configurar el DocumentRoot de tu dominio/subdominio en cPanel // para que apunte a: /home/tu_usuario_cpanel/mi_laravel_deploy/current/public // Tareas principales de despliegue after('deploy:failed', 'deploy:unlock'); // Desbloquear en caso de fallo desc('Deploy Laravel application'); task('deploy', [ 'deploy:prepare', 'deploy:vendors', // Instalar dependencias de Composer 'deploy:shared', // Crear symlinks para archivos/directorios compartidos (ej. .env, storage) 'artisan:storage:link', // Crear el symlink de storage 'artisan:view:cache', // Cachear vistas (opcional, pero recomendado en prod) 'artisan:config:cache', // Cachear configuración (opcional, pero recomendado en prod) 'deploy:publish', // Publicar la nueva release (symlink current y cleanup) ]);
Las migraciones se mantienen fuera de la tarea automática para que el código pueda desplegarse y validarse antes de modificar producción. No añadas tareas que reconstruyan o siembren la base de datos de producción.
Migraciones de Laravel
Una migración de producción debe avanzar desde el esquema actual y ser compatible temporalmente con la release anterior. Sigue este orden:
- Restaura una copia reciente de producción en staging y ejecuta allí las migraciones hacia delante.
- Revisa las sentencias y el volumen afectado, prueba la aplicación y documenta cómo revertir esquema y datos.
- Justo antes del cambio, detén las escrituras y crea un snapshot de producción cuya restauración se haya verificado.
- Ejecuta únicamente las migraciones revisadas y valida esquema, recuentos, logs y funciones críticas antes de publicar o reabrir.
El rollback de Deployer solo cambia el código; no deshace una migración ni recupera datos eliminados. Si la validación falla, mantén la aplicación en mantenimiento y aplica el plan de reversión revisado o restaura el snapshot antes de volver a la release anterior.
Preparación en cPanel
Base de Datos: Crea una base de datos y un usuario MySQL en cPanel.
Directorio de Despliegue: /home/tu_usuario_cpanel/mi_laravel_deploy.
Archivo .env inicial:
- Conéctate por SSH y navega a
{{deploy_path}}/shared(ej./home/tu_usuario_cpanel/mi_laravel_deploy/shared). Si no existe, créalo:mkdir -p /home/tu_usuario_cpanel/mi_laravel_deploy/shared. - Crea un archivo
.envensharedcon la configuración de tu entorno de cPanel:
APP_NAME="Mi App Laravel" APP_ENV=production APP_KEY= # Genera una con php artisan key:generate localmente y pégala aquí APP_DEBUG=false APP_URL=https://tudominio.com LOG_CHANNEL=stack LOG_LEVEL=error # O 'debug' mientras configuras DB_CONNECTION=mysql DB_HOST=127.0.0.1 # O el host de DB que te de cPanel (suele ser localhost) DB_PORT=3306 DB_DATABASE=tu_basedatos_cpanel DB_USERNAME=tu_usuario_db_cpanel DB_PASSWORD=tu_contraseña_db_cpanel # ... otras configuraciones (cache, session, mail) adaptadas a cPanel # Por ejemplo, para el email, usa los datos SMTP de tu cuenta de cPanel si es necesario. # CACHE_DRIVER=file # SESSION_DRIVER=file # SESSION_LIFETIME=120 # QUEUE_CONNECTION=sync # En shared hosting, las colas complejas pueden no funcionar bien
IMPORTANTE APP_KEY: Genera una llave localmente con php artisan key:generate --show y pégala en el .env del servidor. No dejes esto vacío.
Configurar DocumentRoot:
- En cPanel, ve a "Dominios".
- Para dominios addon (adicionales): Puedes cambiar fácilmente el DocumentRoot para que apunte a
/home/tu_usuario_cpanel/mi_laravel_deploy/current/public. Los dominios addon no están restringidos apublic_html. - Para el dominio principal: Está forzado a usar
public_htmlcomo DocumentRoot. En este caso, utiliza el método de symlink que se explica más adelante. - Para subdominios: Generalmente puedes cambiar el DocumentRoot, similar a los dominios addon.
Ejecutar el Despliegue
Desde tu máquina local, en la terminal, navega a la raíz de tu proyecto Laravel y ejecuta:
dep deploy
Deployer intentará:
- Clonar el repositorio.
- Instalar dependencias con Composer (
deploy:vendors). - Crear el symlink para
.envy el directoriostorage(deploy:shared). - Crear el symlink de
public/storage(artisan:storage:link). - Publicar la release.
Configurar DocumentRoot con Symlink (Solo para Dominio Principal)
Importante: Este método solo es necesario para el dominio principal de tu cuenta cPanel, que está forzado a usar public_html. Los dominios addon y subdominios pueden cambiar directamente su DocumentRoot sin necesidad de symlinks.
Si tu dominio principal no puede cambiar el DocumentRoot en cPanel, la mejor solución es crear un symlink desde public_html hacia el directorio public de tu despliegue Laravel:
Pasos:
-
Configura tu
deploy_pathfuera depublic_html, por ejemplo:/home/tu_usuario_cpanel/mi_laravel_deploy -
Agrega esta tarea personalizada a tu
deploy.php:
// Tarea para crear symlink de public_html hacia Laravel public task('cpanel:symlink:public_html', function () { $publicHtmlPath = '/home/{{remote_user}}/public_html'; $laravelPublicPath = '{{deploy_path}}/current/public'; $temporaryLinkPath = $publicHtmlPath . '.next-' . date('Y-m-d_H-i-s'); if (!test("[ -d $laravelPublicPath ] && [ -f $laravelPublicPath/index.php ]")) { throw new \RuntimeException('El destino público de Laravel no está completo'); } if (test("[ -d $publicHtmlPath ] && [ ! -L $publicHtmlPath ]")) { run("mv $publicHtmlPath {$publicHtmlPath}_backup_" . date('Y-m-d_H-i-s')); writeln("✅ Backup de public_html creado"); } run("ln -s $laravelPublicPath $temporaryLinkPath"); run("mv -Tf $temporaryLinkPath $publicHtmlPath"); if (!test("[ \"$(readlink -f $publicHtmlPath)\" = \"$(readlink -f $laravelPublicPath)\" ]")) { throw new \RuntimeException('No se pudo validar el enlace de public_html'); } writeln("✅ Symlink de public_html hacia Laravel public creado correctamente"); })->desc('Crear symlink de public_html hacia Laravel public'); // Ejecutar después de deploy:symlink after('deploy:symlink', 'cpanel:symlink:public_html');
- Importante: ejecuta primero
dep deploy --dry-run, revisa las rutas y crea una copia verificada de ficheros y base de datos. Antes del primer despliegue, conecta por SSH y renombra tupublic_html:
cd /home/tu_usuario_cpanel
mv public_html public_html_backup_manual
- Prueba primero en staging. En producción, valida el enlace, la portada, una ruta dinámica y los logs antes de eliminar el backup. Si falla, usa
dep rollback; para recuperar el directorio original, retira únicamente el symlink verificado y renombrapublic_html_backup_manualde nuevo apublic_html.
Cuando ejecutes dep deploy, Deployer automáticamente:
- Creará un symlink desde
public_htmlhacia{{deploy_path}}/current/public - Tu sitio Laravel servirá correctamente desde la carpeta
public - Los assets, el
index.phpy el.htaccessde Laravel estarán disponibles
Ventajas de este método:
- Funciona perfectamente con Laravel
- Cambio atómico del enlace cuando el sistema admite
mv -T - Posibilidad de rollback a una release anterior
- No requiere modificar archivos manualmente
- Mantiene la estructura estándar de Laravel
Tareas Post-Despliegue
- Verifica los permisos de los directorios
storageybootstrap/cachedentro de{{deploy_path}}/shared/. Deben tener permisos de escritura para el usuario del servidor web. La receta de Laravel intenta hacer esto condeploy:writable. - Ejecuta
dep artisan:migrate stageúnicamente después de completar el snapshot, staging y plan de reversión descritos; no lo uses como prueba directa en producción. - Verifica que el symlink de
public/storagese haya creado correctamente y sea accesible desde la web.
Estructura de Directorios Esperada por Deployer
Deployer organiza los archivos en el servidor de la siguiente manera dentro de tu deploy_path:
releases/: Contiene todas las versiones de tu código. Cada despliegue crea una nueva carpeta aquí (ej.1,2,3, ...).shared/: Contiene archivos y directorios que persisten entre despliegues.- Para WordPress:
wp-config.php,wp-content/uploads/ - Para Laravel:
.env,storage/(que incluyeapp/,framework/,logs/)
- Para WordPress:
current: Un symlink (enlace simbólico) que apunta a la release activa actualmente en la carpetareleases/. Este es el directorio que tu servidor web debe servir.- WordPress: El
DocumentRootapunta a{{deploy_path}}/current/ - Laravel: El
DocumentRootapunta a{{deploy_path}}/current/public/
- WordPress: El
.dep/: Contiene metadatos que Deployer usa para gestionar los despliegues.
Diagrama Simplificado:
/home/tu_usuario_cpanel/
└── mi_aplicacion_deploy/ (Este es tu 'deploy_path')
├── releases/
│ ├── 1/
│ ├── 2/
│ └── 3/ (última release)
│ ├── app/
│ ├── public/ (para Laravel)
│ │ └── index.php
│ ├── wp-admin/ (para WordPress)
│ ├── wp-content/
│ │ └── uploads -> ../../../shared/wp-content/uploads (symlink)
│ ├── vendor/
│ ├── .env -> ../../shared/.env (symlink para Laravel)
│ └── wp-config.php -> ../../shared/wp-config.php (symlink para WP)
├── shared/
│ ├── .env (para Laravel)
│ ├── wp-config.php (para WordPress)
│ ├── storage/ (para Laravel, con sus subcarpetas)
│ └── wp-content/
│ └── uploads/ (para WordPress, con imágenes, etc.)
├── current -> releases/3 (symlink apuntando a la release activa)
└── .dep/
└── releases.log
Para que tu sitio funcione correctamente, tienes diferentes opciones según el tipo de dominio:
Opción 1: Cambiar DocumentRoot (para dominios addon y subdominios)
- Dominios addon: Pueden apuntar directamente a cualquier ruta
- WordPress:
/home/tu_usuario_cpanel/mi_aplicacion_deploy/current - Laravel:
/home/tu_usuario_cpanel/mi_aplicacion_deploy/current/public
- WordPress:
- Subdominios: Similar a los dominios addon, sin restricciones
Opción 2: Usar symlink desde public_html (solo para dominio principal)
- Dominio principal: Está forzado a usar
public_html, por lo que necesitas symlink:public_html→ symlink haciami_aplicacion_deploy/current(WordPress)public_html→ symlink haciami_aplicacion_deploy/current/public(Laravel)
Solución de Problemas Comunes en cPanel
Error de Conexión SSH
- Verifica Usuario y Host: Asegúrate de que
remote_usery el host endeploy.phpson correctos. - Puerto SSH: Confirma el puerto SSH con tu proveedor.
- Clave SSH:
- La clave pública debe estar autorizada en cPanel.
- La ruta a la clave privada en
identity_filedebe ser correcta en tu máquina local. - Los permisos de tu archivo de clave privada local deben ser restrictivos (ej.
chmod 600 ~/.ssh/id_rsa_cpanel). - Intenta conectar manualmente por SSH desde tu terminal para aislar problemas:
ssh -i ~/.ssh/id_rsa_cpanel -p PUERTO tu_usuario_cpanel@tu_dominio_o_ip_cpanel.
- SSH Multiplexing:
set('ssh_multiplexing', false);a veces ayuda si el servidor no lo soporta bien.
Fallo al Clonar Repositorio (Git)
- Git no instalado: Verifica que
gitesté disponible en el servidor. - Acceso al Repositorio:
- Si usas SSH para clonar (ej.
git@github.com:...), la clave SSH del servidor cPanel (la que está en/home/tu_usuario_cpanel/.ssh/id_rsa) debe tener acceso al repositorio (como deploy key en GitHub/GitLab). - O, si
forwardAgentestá habilitado en tu~/.ssh/configlocal y en Deployer (->forwardAgent(true)en la definición del host), tu clave local se usará. Asegúrate de que esta clave local tenga acceso al repo. - Si usas HTTPS para clonar, y el repo es privado, necesitarás configurar credenciales. Es más simple usar SSH.
- Si usas SSH para clonar (ej.
- Ruta del Repositorio: Verifica que la URL en
set('repository', '...');sea correcta.
Fallo en deploy:vendors (Composer)
- Composer no instalado: Verifica que
composeresté disponible. Si no, considera:- Subir
composer.phara tudeploy_pathy ajustarset('bin/composer', '{{bin/php}} {{deploy_path}}/composer.phar'); - Ejecutar
composer installlocalmente y subir la carpetavendor(no recomendado para consistencia).
- Subir
- Límites de Memoria/Tiempo: Los hostings compartidos pueden tener límites bajos.
composer installpuede fallar. Intentacomposer install --prefer-dist --no-dev -opara optimizar. - Versión de PHP: Asegúrate de que la versión de PHP CLI en el servidor sea compatible con tu
composer.json.
Problemas con Symlinks
- Permisos: El usuario SSH debe poder crear symlinks.
FollowSymLinks: La opciónFollowSymLinksde Apache/LiteSpeed debe estar habilitada para el sitio. Esto es usualmente configurado por el administrador del servidor.- Rutas incorrectas: Verifica las rutas en
shared_files,shared_dirsy la lógica deartisan:storage:link. - Error "Operation not permitted": Contacta a tu proveedor de hosting. Puede que los symlinks estén restringidos.
Errores de Permisos de Escritura
- Asegúrate de que
http_userestá configurado correctamente. - Los directorios listados en
writable_dirs(ej.storage/*,bootstrap/cachepara Laravel;wp-content/uploadspara WordPress) necesitan permisos de escritura para el usuario del servidor web (tu_usuario_cpanelusualmente). - Deployer intenta establecer estos permisos. Si falla, puede que necesites ajustar los permisos manualmente vía SSH/FTP o usar
setfaclsi está disponible y lo sabes usar.
php artisan migrate falla
- Conexión a Base de Datos: Verifica que los datos en
{{deploy_path}}/shared/.env(para Laravel) sean correctos (host, DB, usuario, pass). - Usuario de DB sin privilegios: El usuario MySQL debe tener permisos para crear/alterar tablas en la base de datos asignada.
- Comando no encontrado:
phpoartisanno están en el PATH o no son ejecutables. Puedes intentarset('bin/php', '/ruta/absoluta/a/php');si es necesario.
El sitio muestra una versión antigua o error 404/500 tras el despliegue
- Symlink de public_html no funciona: Si usas el método de symlink, verifica que el symlink se haya creado correctamente:
ls -la /home/tu_usuario_cpanel/public_html. Debe mostrar algo comopublic_html -> /ruta/hacia/deploy_path/current. - DocumentRoot Incorrecto: Si cambias el DocumentRoot manualmente, debe apuntar a
{{deploy_path}}/current/public(Laravel) o{{deploy_path}}/current/(WordPress). - Symlink
currentno actualizado: Revisa los logs de Deployer para ver si la tareadeploy:symlinkse ejecutó correctamente. - Permisos en
current: La carpetacurrenty sus contenidos deben ser legibles por el servidor web. - Errores PHP: Revisa los logs de error de PHP en cPanel o en
{{deploy_path}}/shared/storage/logs/laravel.log(Laravel). - Servidor web en caché: Algunos servidores cachean la resolución de symlinks. Espera unos minutos o contacta al soporte del hosting.
"Shell TTY anidado no soportado" o similar
Prueba añadiendo ->setSshMultiplexing(false) o ->multiplexing(false) a la definición de tu host en deploy.php.
Consejos Adicionales para cPanel
- Empieza Simple: Antes de desplegar una aplicación completa, prueba con una tarea simple como
dep pwdodep lspara verificar la conexión SSH y la ruta base. - Despliegues Lentos: Los hostings compartidos pueden ser lentos. Ten paciencia.
- Limpieza de Releases: Usa
set('keep_releases', 3);(o un número bajo) para no agotar el espacio en disco con releases antiguas. - WP-CLI y
php artisan: Si estos comandos no están en el PATH del servidor, puede que necesites especificar sus rutas absolutas endeploy.php:set('bin/wp', '/home/tu_usuario_cpanel/path/to/wp-cli.phar');set('bin/php', '/opt/cpanel/ea-phpXX/root/usr/bin/php');(la ruta de PHP puede variar)- Para
artisan, Deployer usualmente lo encuentra relativo a{{release_path}}, perobin/phpdebe ser correcto.
- Rollbacks: Prueba la funcionalidad de rollback:
dep rollback. - Staging Automático: Utiliza la receta de cPanel para crear automáticamente entornos de staging con dominios y bases de datos dedicadas para cada rama de desarrollo.
- Habla con tu Proveedor: Si encuentras limitaciones específicas (ej. symlinks deshabilitados, comandos SSH bloqueados), contacta al soporte de tu hosting. Puede que no sea posible usar Deployer con todas sus características en ese entorno.
- Alternativas: Si Deployer resulta demasiado complejo o incompatible con tu cPanel, considera alternativas más simples para la automatización como scripts de Git post-receive (si cPanel lo permite) o herramientas como Plesk (que a veces tiene mejor integración con Git). Para despliegues simples, FTP manual o vía cliente Git también son opciones, aunque menos robustas.
Desplegar con Deployer en cPanel requiere paciencia y adaptación. No todas las funciones de Deployer (especialmente el aprovisionamiento) serán relevantes o posibles. Enfócate en el flujo de despliegue de código y la gestión de releases.
También te puede ayudar