Desarrollo y bases de datos
Deploy automático desde GitHub, GitLab o Bitbucket con rollback instantáneo
El sistema de deploy automático conecta tus repositorios de GitHub, GitLab, Bitbucket, Gitea/Forgejo o cualquier servidor Git accesible por HTTPS con tu hosting, preparando una versión nueva del código antes de activarla mediante un enlace simbólico. Puedes volver rápidamente a una versión conservada. La continuidad de la aplicación también depende de sus migraciones, archivos compartidos y scripts; el cambio de código no revierte esos datos.
Si tu repositorio contiene React, Vue u otro frontend que termina en ficheros HTML, CSS y JavaScript, consulta también cómo alojar una web estática conectada a una API externa.
Accede a la herramienta desde el área de clientes en Hosting → selecciona tu servicio → Deploy+.
Conectar un repositorio

Haz clic en Conectar repositorio. El alta va en tres pasos dentro de la misma tarjeta; hasta que un paso no está resuelto no se puede pasar al siguiente, así que los errores aparecen donde se corrigen.
Paso 1 · Repositorio
- Proveedor: GitHub, GitLab, Bitbucket, Gitea/Forgejo u «Otro servidor Git». GitLab y Gitea admiten instalaciones propias: basta con que la URL apunte a tu servidor.
- URL del repositorio: la dirección
https://del repositorio, la misma que usarías para clonarlo. Las URL de SSH (git@servidor:cuenta/repo.git) no valen: el despliegue clona por HTTPS con token. - Token de acceso: se guarda cifrado y se utiliza para acceder al repositorio y, cuando corresponda, consultar la API del proveedor y gestionar el webhook. Para un repositorio público puedes dejarlo vacío. El desplegable «Cómo crear el token» indica, para el proveedor elegido, dónde crearlo y qué permisos exactos necesita.
- Comprobar acceso: consulta la API del proveedor y responde con el repositorio, si es público o privado, la rama por defecto y la lista de ramas. Si al token le falta un permiso, lo dice aquí y no en mitad del primer despliegue.
- Rama que se despliega: se elige del desplegable con las ramas leídas del repositorio.
Permisos que pide cada proveedor:
| Proveedor | Para clonar | Para crear el webhook |
|---|---|---|
| GitHub (token fine-grained) | Contents: Read, Metadata: Read |
Webhooks: Read and write |
| GitLab | scope read_repository |
scope api |
| Bitbucket (repository access token) | Repositories: Read |
Webhooks: Read and write |
| Gitea / Forgejo | lectura de repositorio | escritura de repositorio o webhooks |
| Otro servidor Git | usuario y token con lectura | no aplica |
Con Otro servidor Git no hay API que consultar: no se comprueba el acceso, no se leen las ramas y el webhook no se puede crear solo. El despliegue en cada push se hace llamando a la URL manual desde tu propia integración. Se te pedirá además el usuario con el que tu servidor acepta la autenticación HTTPS (consulta el usuario requerido por tu proveedor).
Crea siempre el token con la caducidad más corta que te sirva, revócalo cuando elimines el deploy y renuévalo antes de que caduque sin ampliarle permisos. En GitHub, no uses un token classic con el alcance global repo.
Paso 2 · Destino y proyecto
- Tipo de proyecto: elige Laravel, Symfony, WordPress, PHP/Composer, Frontend compilado, HTML estático u Otro proyecto. El perfil propone una raíz web, los archivos compartidos y un script adecuados, que puedes revisar antes de guardar.
- Nombre del repositorio: un identificador para reconocerlo en la lista; se autorrellena con el nombre del repositorio.
- Carpeta donde se publica:
public_htmlpara el dominio principal,subdominios/apppara un subdominio. Debajo del campo se ve la ruta final completa y qué sirve esa carpeta. - Raíz web dentro del repositorio: el perfil la configura como
publicpara Laravel y Symfony,distpara un frontend compilado o la raíz para los proyectos que no usan una subcarpeta pública. Cámbiala si tu build genera otro directorio, comobuilduout. - Archivos y carpetas compartidos: una ruta por línea; se guardan fuera de cada versión y se enlazan en todas.
- Versiones que se guardan: cuántas releases anteriores se conservan para volver atrás. Por defecto, 5.
Paso 3 · Automatización
- Desplegar al hacer push: si el proveedor tiene API y el token puede gestionar webhooks, lo creamos nosotros al conectar el repositorio. Si no, la ficha te da la URL (y el secreto, si pides firma) para pegarlos en la configuración de webhooks del proveedor.
- Comprobar la firma de cada aviso: solo se aceptan los avisos firmados por el proveedor. GitHub y Bitbucket firman con HMAC-SHA256, Gitea también, y GitLab manda el secreto en la cabecera
X-Gitlab-Token. - Script de despliegue: revisa el que propone el perfil o elige Solo compilar assets con Node, PHP con Composer o Sin script. También puedes escribir tus propios comandos; se guarda lo que quede en el cuadro de texto.
El paso termina con un resumen de lo elegido y el botón Conectar repositorio.
Ejecutar deploy
Al hacer clic en Conectar repositorio, el sistema verifica el acceso SSH (activándolo automáticamente si es necesario), valida la configuración y guarda el repositorio. Ahora aparece en la lista con un botón Desplegar ahora.

Haz clic en Desplegar ahora para el primer despliegue. La ruta debe estar vacía: si contiene una web anterior, el sistema te pedirá que hagas una copia y retires ese contenido antes de continuar.
Mientras dura, la tarjeta de progreso enseña los pasos uno debajo de otro —conexión, clonado, archivos compartidos, script, activación y limpieza— con el tiempo que ha tardado cada uno y el total. La consola va plegada detrás de Ver consola: si algo falla, el paso roto se abre solo con las últimas líneas de la salida, una explicación de qué ha pasado y los botones para reintentar o corregir el token o la URL. Si el error ocurre antes de activar el código nuevo, sigue publicada la versión anterior. Revisa el paso que falló: los scripts pueden haber modificado datos compartidos y un error posterior a la activación requiere comprobar qué versión está sirviendo la web.
El detalle del repositorio también muestra una URL de despliegue manual para integraciones externas. Esa URL contiene un secreto capaz de iniciar despliegues: no la publiques, no la incluyas en capturas ni registros y regénérala inmediatamente si queda expuesta.
Scripts personalizados
La mayoría de proyectos necesitan ejecutar comandos durante el deploy para instalar dependencias o compilar assets. Accede al editor haciendo clic en el menú del repositorio (tres puntos) → Editar script.

Ejemplos para proyectos que incluyen sus archivos de bloqueo (composer.lock o package-lock.json) y los scripts de compilación indicados. npm ci --include=dev instala también las herramientas de construcción; exige que el archivo de bloqueo esté sincronizado. Comprueba antes las versiones de PHP y Node que necesita el proyecto:
Laravel con Composer y npm:
composer install --no-dev --optimize-autoloader php artisan config:cache php artisan route:cache php artisan view:cache export NVM_DIR="$HOME/.nvm" && . "$NVM_DIR/nvm.sh" && npm ci --include=dev export NVM_DIR="$HOME/.nvm" && . "$NVM_DIR/nvm.sh" && npm run build
WordPress con npm:
export NVM_DIR="$HOME/.nvm" && . "$NVM_DIR/nvm.sh" && npm ci --include=dev export NVM_DIR="$HOME/.nvm" && . "$NVM_DIR/nvm.sh" && npm run build
Proyecto PHP simple:
composer install --no-dev
Los scripts se ejecutan en la nueva versión antes de activarla, por lo que un fallo del script impide activar ese código nuevo. Aun así, sus operaciones sobre una base de datos, servicios externos o rutas compartidas pueden afectar a la web publicada y no se deshacen automáticamente. El sistema elimina al guardar líneas que coincidan con patrones bloqueados como sudo, chmod 777, dd, mkfs, fdisk, kill -9, pkill, shutdown, reboot o halt. Reabre el editor y comprueba que el script guardado conserva todas las líneas previstas.
Deploy+ comprueba Node.js antes de ejecutar estos comandos y lo instala automáticamente si falta. Si el proyecto exige una versión concreta, selecciónala antes desde el Gestor de paquetes.
Archivos compartidos y .env
El archivo .env se preserva automáticamente entre deploys. Para compartir archivos o carpetas adicionales, accede a Archivos compartidos (menú → Archivos compartidos) y especifica las rutas relativas, una por línea.

Por ejemplo:
storage/app storage/logs uploads
Los archivos compartidos se guardan en ~/deploy/nombre-repo/shared/ y se enlazan automáticamente en cada versión. Puedes editar el .env directamente desde el menú → Editar .env. El fichero compartido se actualiza de inmediato y, en aplicaciones Laravel, se limpian las cachés automáticamente. En un frontend compilado, las variables que se incorporan al JavaScript solo cambian al ejecutar un build nuevo, por lo que después debes lanzar otro despliegue.
La opción de variables de entorno de Deploy+ gestiona ese archivo .env; no es un almacén global de variables del servidor ni exporta automáticamente sus valores a todos los procesos. Cada aplicación debe cargar el fichero con el mecanismo de su framework o con una librería equivalente. Laravel, por ejemplo, utiliza vlucas/phpdotenv. Un PHP web, una tarea cron o un comando del script de despliegue podrá leer los valores si inicia la aplicación o su cargador de configuración; un comando independiente que no cargue el .env no los recibirá como variables del sistema.
LiteSpeed y PHP Selector no ofrecen dentro de la cuenta un gestor de secretos compartido entre PHP web, cron y Deploy+. Las variables que el administrador del servidor pueda proporcionar al PHP web no se trasladan por ello a los otros dos contextos. Deploy+ tampoco incluye actualmente una integración incorporada con gestores externos como 1Password: si la aplicación utiliza uno, ella debe implementar su consulta y entregar los valores a cada proceso.
Las variables se cargan dentro de cada proceso y no se transfieren por sí solas a otras aplicaciones. Sin embargo, todas las aplicaciones de una misma cuenta de cPanel se ejecutan con el mismo usuario: un proceso de esa cuenta podría leer el .env si conoce su ubicación. Guardarlo fuera de la raíz web impide descargarlo por HTTP, pero no crea una frontera de seguridad entre las aplicaciones de la cuenta. Para un aislamiento completo hace falta un servicio de hosting independiente, con otro usuario de sistema.
Para comprobar los tres contextos puedes utilizar primero una variable sin información secreta. La prueba debe hacer que el PHP web, el cron y el comando de despliegue inicien el mismo cargador; no hace falta modificar credenciales reales ni reiniciar el servidor. Si un contexto no carga el fichero, la ausencia de la variable describe ese proceso, no una pérdida del .env compartido.
Prepara el contenido persistente antes de publicarlo. Una ruta compartida existente prevalece sobre el archivo que llegue en el repositorio; añadirla a la lista no combina automáticamente ambas versiones. No incluyas código que quieras actualizar con cada despliegue dentro de una carpeta compartida. Evita compartir node_modules si utilizas npm ci: esa orden elimina y reconstruye la carpeta, y podría afectar a otras releases que apuntasen a ella. Conserva una copia antes de modificar esta configuración.
El .env compartido afecta a la aplicación activa. En una instalación Laravel existente, conserva su APP_KEY; cambiarla no forma parte de un despliegue habitual. No introduzcas secretos en las variables que un frontend compila dentro del JavaScript público. Antes de editar el .env, conserva una copia privada: el rollback cambia el código publicado, pero no recupera una versión anterior de este archivo.
Historial y rollback
El Historial de despliegues se abre desde el menú del repositorio y aparece dentro de su propia ficha, en una tabla con fecha, disparador (Manual, Push, Rollback o Programado), commit desplegado con su mensaje y autor, duración y estado. El filtro Todos / Fallidos deja ver solo lo que se rompió. Haz clic en Ver detalle para desplegar los pasos con sus tiempos y la salida completa de la consola.

Para hacer rollback a una versión anterior, localiza el deploy en el historial y elige Volver a esta versión en su menú; se pide confirmación antes de tocar nada. El sistema verifica que la versión existe, cambia el enlace simbólico para apuntar a ella y actualiza el directorio. Cuando la release sigue disponible, no necesita clonar el código de nuevo y el cambio suele ser rápido. Comprueba después que las páginas y operaciones principales funcionan con los datos actuales.
Si la versión ya no está en el servidor porque la limpieza automática la borró, el sistema la reconstruye: clona el repositorio y le pide a tu proveedor Git ese commit concreto. Tarda más que un rollback normal y requiere que el proveedor permita recuperar el commit y que las credenciales sigan siendo válidas. También vuelve a ejecutar el script configurado, que debe seguir siendo compatible con ese código y sus dependencias.
El rollback no restaura la base de datos, el .env ni los archivos compartidos. Planifica por separado la recuperación de una migración o de datos modificados. Las versiones guardadas no sustituyen a una copia de seguridad.
Si un deploy está en progreso y necesitas cancelarlo, haz clic en Cancelar Deploy. Espera a que el estado confirme la cancelación y revisa la web. La petición puede llegar cuando una operación ya está en marcha; cancelar no revierte sus cambios en datos ni sustituye a un rollback después de la activación.
Cómo funciona la herramienta de deploy
El sistema crea una estructura en ~/deploy/nombre-repo/ con tres directorios principales: releases/ contiene cada versión desplegada con timestamp, current es un enlace simbólico a la versión activa, y shared/ contiene archivos compartidos como .env y storage/. Tu directorio web (public_html u otro) apunta a current, que a su vez apunta a la versión activa en releases/.
Cuando ejecutas un deploy, se crea una nueva carpeta en releases/, se clona el código, se ejecutan los scripts y cuando todo está listo se actualiza current para apuntar a la nueva versión. El cambio del enlace es rápido, pero no garantiza por sí solo que todas las peticiones, procesos o cambios de esquema sean compatibles durante la publicación. El rollback funciona igual, simplemente cambia current a una versión anterior que ya existe.
El clonado se hace en profundidad 1: cada versión recibe los archivos del último commit de la rama, no el historial del repositorio. En un repositorio con años de vida el historial pesa mucho más que el código en sí, así que el deploy es bastante más rápido y cada versión ocupa menos espacio de tu cuenta. Si tu script de despliegue necesita el historial (por ejemplo git describe o git rev-list --count para generar un número de versión), no lo encontrará: guarda ese dato en un archivo desde tu sistema de integración continua o calcúlalo de otra forma.
Solución de problemas
La cuenta no tiene acceso SSH: La herramienta intenta activarlo automáticamente. Si el servidor rechaza la clave incluso después de reinstalarla, vuelve a ejecutar el deploy y contacta con soporte con el registro; la herramienta usa una clave gestionada y no depende de la contraseña de cPanel. Ya existe un deploy en progreso: Solo puede haber un deploy activo por repositorio, espera a que termine o cancélalo. Scripts personalizados fallan: Revisa la sintaxis de los comandos en bash y consulta el output del deploy para identificar qué comando falló. Un fallo anterior a la activación impide publicar el código nuevo; revisa también los posibles cambios en datos compartidos. Webhook no se activa: verifica en la configuración de webhooks del proveedor (en GitHub, Settings → Webhooks) que está creado y revisa las entregas recientes. Si la ficha del repositorio dice «Webhook pendiente», usa Instalar; si dice «Webhook manual», copia la URL que aparece en el detalle y pégala tú en el proveedor. El proveedor rechaza el token al clonar: cada marca lo dice de una forma («HTTP Basic: Access denied» en GitLab, un 403 en GitHub, «Invalid or expired token» en Bitbucket). El registro del deploy traduce esos mensajes y dice qué permiso falta o si el token caducó.
También te puede ayudar
- Automatización de tareas de deploy en Git con el fichero .cpanel.yml Define tareas de despliegue en .cpanel.yml, ejecútalas tras push o pull y aprende a lanzar el proces...
- Desplegar WordPress y Laravel en cPanel con Deployer Prepara despliegues por versiones con Deployer, configura archivos compartidos y comprueba qué puede...
- Git, interfaz gráfica con clonado, historial y deploy automático Gestiona repositorios Git desde cPanel; crea o clona proyectos, actualiza ramas, despliega con .cpan...
- Alojar React, Vue y webs estáticas conectadas a APIs externas Comprueba si tu frontend JavaScript cabe en un hosting compartido, conéctalo a Supabase, Firebase u...
¿Algo no cuadra o ha cambiado? Cuéntanoslo y lo revisamos.