{"id":1602,"date":"2026-03-13T02:58:05","date_gmt":"2026-03-13T02:58:05","guid":{"rendered":"https:\/\/orpot.com\/blog\/?p=1602"},"modified":"2026-03-25T14:21:34","modified_gmt":"2026-03-25T14:21:34","slug":"como-desplegar-laravel-en-cpanel-usando-github-actions-y-ssh-desde-linux","status":"publish","type":"post","link":"https:\/\/orpot.com\/blog\/como-desplegar-laravel-en-cpanel-usando-github-actions-y-ssh-desde-linux\/","title":{"rendered":"C\u00f3mo desplegar Laravel en cPanel usando GitHub Actions y SSH (desde Linux)"},"content":{"rendered":"<h3>Desplegar aplicaciones Laravel en hosting compartido como cPanel puede parecer complicado al principio.<\/h3>\n<p>A diferencia de una VPS tradicional, aqu\u00ed no tenemos control total del sistema, pero a\u00fan as\u00ed podemos crear un flujo de despliegue moderno usando GitHub, GitHub Actions y SSH.<\/p>\n<p>En este art\u00edculo veremos c\u00f3mo:<\/p>\n<ul>\n<li>instalar Laravel en un servidor con cPanel<\/li>\n<li>usar GitHub como repositorio<\/li>\n<li>configurar GitHub Actions para deploy autom\u00e1tico<\/li>\n<li>conectarnos al servidor v\u00eda SSH<\/li>\n<li>ejecutar comandos Laravel desde consola<\/li>\n<li>trabajar desde una m\u00e1quina Linux<\/li>\n<\/ul>\n<p>Este flujo permite que cada push a GitHub despliegue autom\u00e1ticamente la aplicaci\u00f3n.<\/p>\n<h3>1. Requisitos<\/h3>\n<p>Antes de empezar necesitas:<\/p>\n<ul>\n<li>Cuenta de GitHub<\/li>\n<li>Hosting con cPanel<\/li>\n<li>Acceso SSH habilitado<\/li>\n<li>Laravel instalado localmente<\/li>\n<li>Una m\u00e1quina Linux (Mint, Ubuntu, etc.)<\/li>\n<\/ul>\n<p>Herramientas necesarias en Linux:<\/p>\n<ul>\n<li>git<\/li>\n<li>ssh<\/li>\n<li>rsync<\/li>\n<li>node<\/li>\n<li>npm<\/li>\n<\/ul>\n<h3>2. Crear el proyecto Laravel<\/h3>\n<p>Si a\u00fan no tienes el proyecto:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">composer create-project laravel\/laravel proyecto<\/pre>\n<p>Entrar al proyecto:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">cd proyecto<\/pre>\n<p>&nbsp;<\/p>\n<p>Probar que funciona:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">php artisan serve<\/pre>\n<h3>3. Crear el repositorio en GitHub<\/h3>\n<p>Inicializa git en tu proyecto:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">git init\r\ngit add .\r\ngit commit -m \"first commit\"<\/pre>\n<p>Agrega el repositorio remoto:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">git remote add origin https:\/\/github.com\/USUARIO\/REPO.git<\/pre>\n<p>Sube la rama principal:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">git push -u origin main<\/pre>\n<p>&nbsp;<\/p>\n<p>Si usas entorno staging puedes crear otra rama:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">git checkout -b develop\r\ngit push -u origin develop<\/pre>\n<h3>4. Preparar el servidor cPanel<\/h3>\n<p>En cPanel crea un subdominio o dominio que apunte a una carpeta fuera de public_html.<\/p>\n<p>Ejemplo:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">\/home\/usuario\/laravel-app<\/pre>\n<p>&nbsp;<\/p>\n<p>y el document root debe apuntar a:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">\/home\/usuario\/laravel-app\/public<\/pre>\n<p>Esto es importante porque Laravel sirve todo desde la carpeta public.<\/p>\n<h3>5. Activar acceso SSH en cPanel<\/h3>\n<p>En cPanel busca:<\/p>\n<p><strong>SSH Access<\/strong><\/p>\n<p>y genera una clave.<\/p>\n<p>Luego conecta desde Linux:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">ssh usuario@servidor<\/pre>\n<p>&nbsp;<\/p>\n<p>Ejemplo:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">ssh usuario@servidor.com<\/pre>\n<p>Si todo est\u00e1 bien ver\u00e1s algo como:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">[usuario@server ~]$<\/pre>\n<h3>6. Crear una clave SSH para GitHub Actions<\/h3>\n<p>En tu m\u00e1quina Linux crea una clave:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">ssh-keygen -t ed25519 -C \"github-actions\"<\/pre>\n<p>Se generar\u00e1n dos archivos:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">~\/.ssh\/id_ed25519\r\n~\/.ssh\/id_ed25519.pub<\/pre>\n<p>La clave p\u00fablica debe agregarse al servidor.<\/p>\n<p>En el servidor:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">~\/.ssh\/authorized_keys<\/pre>\n<p>Agrega la clave p\u00fablica.<\/p>\n<h3>7. Guardar secretos en GitHub<\/h3>\n<p>En tu repositorio entra a:<\/p>\n<p><strong>Settings &gt; <\/strong><strong>Secrets and variables &gt;<\/strong><strong>Actions<\/strong><\/p>\n<p>Agrega:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">SSH_HOST\r\nSSH_USER\r\nSSH_PORT\r\nSSH_PRIVATE_KEY<\/pre>\n<p>Ejemplo:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">SSH_HOST=server.com\r\nSSH_USER=usuario\r\nSSH_PORT=22\r\nSSH_PRIVATE_KEY=contenido de id_ed25519<\/pre>\n<h3>8. Crear GitHub Actions para deploy<\/h3>\n<p>Crea el archivo:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">.github\/workflows\/deploy.yml<\/pre>\n<p>Ejemplo b\u00e1sico usando rsync:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"yaml\">name: Deploy Laravel\r\n\r\non:\r\npush:\r\nbranches: [main, develop]\r\n\r\njobs:\r\ndeploy:\r\nruns-on: ubuntu-latest\r\n\r\nsteps:\r\n\r\n- uses: actions\/checkout@v4\r\n\r\n- name: Setup Node\r\nuses: actions\/setup-node@v4\r\nwith:\r\nnode-version: 20\r\n\r\n- name: Build assets\r\nrun: |\r\nnpm install\r\nnpm run build\r\n\r\n- name: Prepare SSH\r\nrun: |\r\nmkdir -p ~\/.ssh\r\necho \"${{ secrets.SSH_PRIVATE_KEY }}\" &gt; ~\/.ssh\/id_ci\r\nchmod 600 ~\/.ssh\/id_ci\r\nssh-keyscan -p ${{ secrets.SSH_PORT }} ${{ secrets.SSH_HOST }} &gt;&gt; ~\/.ssh\/known_hosts\r\n\r\n- name: Deploy with rsync\r\nrun: |\r\nrsync -az --delete \\\r\n-e \"ssh -i ~\/.ssh\/id_ci -p ${{ secrets.SSH_PORT }}\" \\\r\n--exclude \".git\" \\\r\n--exclude \"node_modules\" \\\r\n--exclude \".env\" \\\r\n.\/ \\\r\n${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:\/home\/usuario\/laravel-app\/<\/pre>\n<p>&nbsp;<\/p>\n<p>Ahora cada push a GitHub desplegar\u00e1 autom\u00e1ticamente.<\/p>\n<h3>9. Instalar dependencias en el servidor<\/h3>\n<p>Una vez desplegado el c\u00f3digo entra por SSH:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">ssh usuario@server<\/pre>\n<p>Luego entra al proyecto:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">cd \/home\/usuario\/laravel-app<\/pre>\n<p>Instala dependencias:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">composer install --no-dev --optimize-autoloader<\/pre>\n<h3>10. Crear archivo .env<\/h3>\n<p>Laravel necesita un .env.<\/p>\n<p>Puedes copiar el ejemplo:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">cp .env.example .env<\/pre>\n<p>Editar:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">nano .env<\/pre>\n<p>Configura:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">APP_NAME\r\nAPP_URL\r\nDB_DATABASE\r\nDB_USERNAME\r\nDB_PASSWORD<\/pre>\n<h3>11. Generar la key de Laravel<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">php artisan key:generate<\/pre>\n<h3>12. Ejecutar migraciones<\/h3>\n<p>Si tu servidor usa PHP de cPanel puede ser algo como:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">ea-php82<\/pre>\n<p>&nbsp;<\/p>\n<p>Ejemplo:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">ea-php82 artisan migrate<\/pre>\n<p>&nbsp;<\/p>\n<p>o<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">\/opt\/cpanel\/ea-php82\/root\/usr\/bin\/php artisan migrate<\/pre>\n<h3>13. Permisos necesarios<\/h3>\n<p>Laravel necesita permisos en:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">storage\r\nbootstrap\/cache<\/pre>\n<p>Ejecuta:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">chmod -R 775 storage\r\nchmod -R 775 bootstrap\/cache<\/pre>\n<h3>14. Comandos \u00fatiles por SSH<\/h3>\n<p>Entrar al servidor:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">ssh usuario@server<\/pre>\n<p>Entrar al proyecto:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">cd \/home\/usuario\/laravel-app<\/pre>\n<p>&nbsp;<\/p>\n<p>Limpiar cach\u00e9:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">php artisan optimize:clear<\/pre>\n<p>Migraciones:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\">php artisan migrate<\/pre>\n<h3>15. Flujo final de trabajo<\/h3>\n<p>El flujo queda as\u00ed:<\/p>\n<ol>\n<li>Desarrollas en local<\/li>\n<li>haces commit<\/li>\n<li>haces push a GitHub<\/li>\n<\/ol>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bat\">git add .\r\ngit commit -m \"update\"\r\ngit push<\/pre>\n<ol>\n<li>GitHub Actions se ejecuta<\/li>\n<li>se conecta por SSH al servidor<\/li>\n<li>sincroniza archivos<\/li>\n<li>la app queda actualizada<\/li>\n<\/ol>\n<p>Todo autom\u00e1ticamente.<\/p>\n<p>Aunque cPanel no est\u00e1 pensado para despliegues modernos, con GitHub Actions + SSH + rsync podemos crear un flujo bastante profesional.<\/p>\n<p>Ventajas de este sistema:<\/p>\n<ul>\n<li>deploy autom\u00e1tico<\/li>\n<li>control de versiones<\/li>\n<li>staging y producci\u00f3n<\/li>\n<li>rollback f\u00e1cil con git<\/li>\n<li>sin subir archivos manualmente por FT<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Desplegar aplicaciones Laravel en hosting compartido como cPanel puede parecer complicado al principio. A diferencia&hellip;<\/p>\n","protected":false},"author":1,"featured_media":1612,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[47,198],"tags":[213],"_links":{"self":[{"href":"https:\/\/orpot.com\/blog\/wp-json\/wp\/v2\/posts\/1602"}],"collection":[{"href":"https:\/\/orpot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/orpot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/orpot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/orpot.com\/blog\/wp-json\/wp\/v2\/comments?post=1602"}],"version-history":[{"count":3,"href":"https:\/\/orpot.com\/blog\/wp-json\/wp\/v2\/posts\/1602\/revisions"}],"predecessor-version":[{"id":1607,"href":"https:\/\/orpot.com\/blog\/wp-json\/wp\/v2\/posts\/1602\/revisions\/1607"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/orpot.com\/blog\/wp-json\/wp\/v2\/media\/1612"}],"wp:attachment":[{"href":"https:\/\/orpot.com\/blog\/wp-json\/wp\/v2\/media?parent=1602"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/orpot.com\/blog\/wp-json\/wp\/v2\/categories?post=1602"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/orpot.com\/blog\/wp-json\/wp\/v2\/tags?post=1602"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}