DEV Community

Cover image for ¿Listo para el mundo real? Sube tu proyecto de 2º DAW/DAM a un VPS en pocos pasos
Altaskur
Altaskur

Posted on

¿Listo para el mundo real? Sube tu proyecto de 2º DAW/DAM a un VPS en pocos pasos

Tabla de contenidos

Estoy seguro de que si estás en 2º de DAW o DAM y te toca presentar tu proyecto final, has pensado en desplegarlo en un servidor, pensarás que te llevará mucho tiempo, además de no comprender del todo cómo funciona, así que seguramente has pensado en servicios como Netlify o Vercel, que son muy cómodos y fáciles de usar, pero... ¿Qué pasa si quieres algo más? O simplemente aprender a desplegar tu proyecto sin tanta magia por detrás. ¿Se supone que estamos aprendiendo a desarrollar no? Y el despliegue es una parte fundamental del proceso de desarrollo.

Motivación y prevención de errores típicos

Antes de meternos en faena, ¿qué ganas con todo esto? Lo principal es que te quitas riesgos importantes. El más común: tienes todo preparado, llega el día de la defensa y... sorpresa, al iniciar el proyecto en el portátil, no funciona. No te puedes hacer una idea de lo habitual que es eso, y créeme, no te quieres ver en esa situación.

Además, muy típico, cambios de última hora o llevas mucho desarrollado y no has probado nada.
Todo esto te lo puedes saltar usando un despliegue continuo con GitHub Actions (por ejemplo), así cada vez que subas cambios a tu repositorio, se desplegará automáticamente en tu servidor. Esto te ahorra tiempo y te asegura que siempre tienes la última versión funcionando.

¿Y para qué te vas a complicar con un VPS teniendo Netlify o Vercel?

Si solo necesitas publicar una web sencilla, funcionan perfecto. Pero si necesitas un backend completo, bases de datos, bots, tareas automáticas (cron), websockets... puedes montar lo que quieras, aunque sea raro, experimental o muy ambicioso. La única limitación es la capacidad de tu servidor.

Además, con un VPS tienes control total: puedes instalar lo que quieras, configurar el sistema a tu medida y optimizarlo para tu proyecto. No dependes de las limitaciones ni del template que ofrecen.

Ventajas económicas y de aprendizaje

Algo que me parece primordial y sobre todo al estar estudiando, no hay cobros sorpresa: pagas lo mismo cada mes, superes o no la capacidad del servidor. Es muy común en servicios de nube como AWS, Azure o Google Cloud, donde cobras por uso, cualquier fallo, descuido o vulnerabilidad puede hacer que te lleves una sorpresa desagradable al final de mes. Que ya sabemos que no tiene por qué pasar, pero te da muchísima más tranquilidad saber que apagas tu servidor, haces tus cambios y no te cobran más por ello.

Esto es sin duda fue mi principal temor cuando estaba estudiando DAW, aunque me gradué con los dos primeros Tier de AWS, ese temor siempre me ha frenado muchísimo a subir mis proyectos. Así que te muestro la opción más segura que encontré y que sigo aplicando en mis proyectos.

Y por último, el aprendizaje: vas a entender realmente cómo funciona el despliegue, la configuración y la administración de servidores, algo que marca la diferencia y suma muchos puntos cuando salgas al mundo profesional, independientemente de si tiras hacia front o back. Créeme que cuando aprendes que cuantas menos magias mientras estás creando tu base de conocimientos, más fácil te será adaptarte a cualquier tecnología o servicio que surja en el futuro (que te aseguro que van a venir).

Resumen: ganas control, flexibilidad y aprendizaje.

Para el post vamos a elegir https://donweb.com/es-es/cloud-server-altaskur como proveedor de servicios.

¿Por qué https://donweb.com/es-es/cloud-server-altaskur? Es una empresa conocida en Latinoamérica, tiene soporte en español, es sencilla de usar y, lo más importante, para este post he contado con su apoyo, que me ha facilitado un VPS para hacer las pruebas y capturas.

¿Y si tienes otro proveedor? Si tienes otros servicios (OVH, Hetzner, DigitalOcean, etc.), puedes seguir los pasos igual. Como te he comentado antes, las bases son exactamente las mismas; solo cambiarán pequeños detalles del panel.

Pasos iniciales en DonWeb

Ahora que lo tenemos todo decidido vamos a comenzar con la aventura. Desde este punto voy a dar por hecho que ya tienes una cuenta en DonWeb y has iniciado sesión en su panel de control, además de tener un VPS contratado.

Recuerda que puedes replicarlo con cualquier proveedor de VPS, los pasos son muy similares.

Puedes crear una cuenta en este enlace: https://donweb.com/es-es/cloud-server-altaskur

Comencemos

Una vez dentro del panel de https://donweb.com/es-es/cloud-server-altaskur y nuestro servidor contratado, vamos a configurar nuestro VPS para que esté listo para desplegar nuestro proyecto.

Elige la imagen de sistema operativo

Elige la imagen de sistema operativo. Selecciona "Instalación Mínima" con Ubuntu 24.04. Esto garantiza un sistema limpio y ligero, ideal para montar solo lo que necesitas.

Que además, si necesitas cualquier otro servicio, tienes muchas imágenes preconfiguradas, con todo disponible. Una de mis favoritas es la de node (que ya viene con node y pm2 instalado), pero para este post vamos a usar una instalación mínima de Ubuntu 24.04, que es la versión LTS más reciente y estable.

¿Por qué una instalación mínima y por qué Ubuntu? Básicamente Ubuntu es un sistema muy fácil de usar con una gran comunidad y documentación, así que si tienes cualquier problema seguro que con una búsqueda rápida encuentras la solución. Podríamos optar por una imagen como Debian (seguramente te lo dirán) porque es la más usada en servidores, pero en este post voy a intentar facilitarte las cosas ante cualquier problema que pueda salirte, y Ubuntu es una de las distribuciones más amigables y con más soporte.

¿Te apetece probar con Debian? 👀 No te juzgo, pensé igual que tú cuando estudiaba. ¡Adelante! Los pasos son muy similares, pero ten en cuenta que la configuración puede variar un poco.

Te recomiendo que una vez tengas hecha con Ubuntu pruebes otras distribuciones e imágenes.

Usuario Root

Crea la contraseña del usuario root. El panel te pedirá establecer una contraseña segura para el usuario root. DonWeb incluye un generador de contraseñas integrado bastante decente, aprovéchalo.

Por si no has estado muy pendiente en clase, el usuario root tiene acceso total a todo el sistema, así que no menosprecies este paso, vale. Es importante aunque no te lo parezca y además siempre puedes cambiarla más adelante.

Confirma y lanza la instalación. Haz clic en continuar y espera unos minutos (no suele ser más de 3 min, que es muchísimo menos de lo que tardas en hacerlo en VirtualBox). Durante este tiempo, el sistema se instala y prepara.

Una vez termine la instalación, tendrás acceso a tu VPS por SSH usando la IP, el usuario root y la contraseña que has puesto antes.

Y sin tener que especificar ni dominio de actualizaciones ni idioma del teclado ni nada de eso, como pasaba con VirtualBox.

Acceso por SSH

Conectarte por SSH a tu VPS te será muy familiar si has usado VirtualBox durante el curso (¡seguro que sí! 😊).

Y si no, ni te preocupes. Suponiendo que estás en un entorno Windows usa la PowerShell o si estás en Mac o Linux, abre la terminal.

¿Dónde están los datos de acceso? Ve al apartado de software y accesos en el panel de DonWeb. Ahí tendrás para copiar en tu terminal un comando como este:

ssh -p[tu puerto] root@[tu_direccion_IP]
Enter fullscreen mode Exit fullscreen mode

El puerto (-p[tu puerto]) y la dirección IP pueden variar según tu VPS. Asegúrate de copiar los valores que te da DonWeb para tu máquina.

Primeros pasos en tu VPS

Ahora estamos en nuestro servidor y lo primero que vamos a hacer es actualizar la máquina. Para ello, ejecuta estos comandos en la terminal:

sudo apt update
sudo apt upgrade
Enter fullscreen mode Exit fullscreen mode

Esto puede tardar un ratito, así que ten paciencia. Actualizar el sistema asegura que tienes todos los parches de seguridad y las versiones más recientes de los paquetes instalados y nos olvidamos de problemas de compatibilidad más adelante.

Crear una snapshot (copia de seguridad)

Cuando termine la actualización, lo siguiente es crear una snapshot. Así tendrás una imagen de tu sistema justo desde el inicio, por si algo falla más adelante y necesitas volver atrás.

Busca en el panel de DonWeb la opción de Snapshots o copias de seguridad y crea una nueva antes de seguir.

Creación de usuario para deploy

Ahora que ya tenemos preparada una versión limpia y actualizada de Ubuntu, vamos a dar el siguiente paso. No es recomendable usar Root. De hecho, cuanto menos lo expongamos mejor, ya que este tiene acceso total al sistema, así que lo primero que hay que hacer es crear un usuario nuevo para gestionar el servidor y el despliegue de tu proyecto.

Vamos a ello. Para ello vamos a crear un usuario, lo vamos a llamar deploy por el tema de semántica, pero puedes ponerle el nombre que quieras.

adduser deploy
Enter fullscreen mode Exit fullscreen mode

Sigue las instrucciones para ponerle contraseña (puede ser distinta a la de root) y, si quieres, rellena los datos adicionales (puedes dejarlos en blanco pulsando Enter).

Después, añade este usuario al grupo sudo para que pueda usar permisos de administración cuando lo necesite:

 usermod -aG sudo deploy
Enter fullscreen mode Exit fullscreen mode

Una vez tienes esto listo, sal de la sesión de root en la terminal y vuelve a conectarte, pero esta vez usando el usuario deploy que acabas de crear.

Para salir de la terminal como root, simplemente escribe:

exit
Enter fullscreen mode Exit fullscreen mode

Ahora inicia sesión de nuevo por SSH, pero cambiando root por deploy y usando la misma IP y puerto que antes:

ssh -p[tu puerto] deploy@[tu_direccion_IP]
Enter fullscreen mode Exit fullscreen mode

Introduce la contraseña del usuario deploy cuando te la pida.

Ahora que ya estamos dentro vamos a empezar a aprovisionar el servidor. Para ello vamos a instalar Node.js con NVM (Node Version Manager), Nginx como instalación mínima para poder desplegar tu proyecto de front y backend con node.

Instalar NVM (Node Version Manager)

Ahora que ya estás conectado como el usuario deploy, vamos a instalar NVM. NVM te permitirá instalar y gestionar diferentes versiones de Node.js de forma sencilla.

En la terminal, ejecuta el siguiente comando para descargar e instalar la última versión de NVM:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
Enter fullscreen mode Exit fullscreen mode

Una vez termine, cierra y vuelve a abrir la terminal, o ejecuta el siguiente comando para cargar NVM en la sesión actual:

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
Enter fullscreen mode Exit fullscreen mode

Para comprobar que NVM está instalado correctamente, ejecuta:

nvm --version
Enter fullscreen mode Exit fullscreen mode

Si ves un número de versión, ¡ya lo tienes listo!

Instalar Node.js LTS con NVM

Ahora que tienes NVM instalado, vamos a instalar la versión LTS de Node.js. La versión LTS es la más recomendada para la mayoría de proyectos porque es la más estable y tiene soporte a largo plazo.

En la terminal, ejecuta:

nvm install --lts
Enter fullscreen mode Exit fullscreen mode

Esto descargará e instalará la última versión LTS disponible de Node.js.

Para comprobar que la instalación se realizó correctamente y estás usando la versión LTS, ejecuta:

node -v
npm -v
Enter fullscreen mode Exit fullscreen mode

Deberías ver los números de versión correspondientes.

¿Por qué instalar Node.js?

Instalar Node.js es necesario porque la mayoría de proyectos modernos de backend y muchas herramientas de frontend (como React, Angular, Vue, Svelte, etc.) usan Node.js para funcionar, tanto en desarrollo como en producción.

Además si tu proyecto está hecho con cualquier stack basado en JavaScript o necesitas ejecutar scripts asique necesitarás Node.js en tu servidor

En resumen: Instalar Node.js te garantiza que tu VPS puede ejecutar la mayoría de proyectos web actuales y es casi imprescindible para DAW/DAM hoy en día.

Instalar Nginx y por qué usarlo

Ahora que ya tienes Node.js instalado, vamos a instalar nginx.

¿Y por qué Nginx? Porque Nginx es un servidor web ligero, rápido y muy usado en producción.
Mucha gente te hablará de Apache, y es el servidor web más antiguo y conocido, ¿pero por qué Nginx? Es más ligero, y en la mayoría de los casos es más fácil de configurar y mantener.

Al igual que te dije con Ubuntu Vs Debian, Nginx es el más fácil, así que si quieres adentrarte con apache ¡Adelante! 👀 aunque te recomiendo que primero lo montes con Nginx así luego te sonará todo.

¿Y qué es esto de Nginx o Apache? Pues lo que hacen es servir tu página web, similar a un npm start de Node.js, pero a nivel de servidor de modo que hará tu proyecto accesible desde Internet.

No solo sirve para servir páginas web estáticas, sino que también puede actuar como proxy inverso para aplicaciones Node.js, gestionar certificados SSL, balancear carga entre varios servidores y mucho más.

Es compatible con SSL (HTTPS), por lo que es imprescindible si quieres usar certificados y servir tu web de forma segura.

En resumen: Nginx es un servidor web moderno versátil y ligero. Es una herramienta fundamental para desplegar aplicaciones web en producción, ya sea para servir archivos estáticos, actuar como proxy inverso o gestionar certificados SSL.

Instalación básica de Nginx

En tu terminal (con el usuario deploy, usando sudo), ejecuta:

sudo apt update
sudo apt install nginx
Enter fullscreen mode Exit fullscreen mode

Cuando termine, puedes comprobar que Nginx está funcionando abriendo tu navegador y poniendo la IP de tu servidor: Deberías ver la página de bienvenida de Nginx.

Y ya está, ya tienes Nginx instalado y funcionando en tu servidor. Ahora puedes ver la página de bienvenida de Nginx en la carpeta /var/www/html, que es donde se guardan los archivos que Nginx sirve por defecto.

Configuración de puertos en DonWeb

Antes de seguir con el despliegue automático, hay un paso importante que muchas veces se pasa por alto: configurar correctamente los puertos en el panel de DonWeb.

¿Por qué es importante esto? Aunque tengas Nginx funcionando perfectamente en tu servidor, si los puertos no están abiertos en el firewall de DonWeb, nadie podrá acceder a tu web desde Internet. Es como tener una casa perfectamente amueblada pero con la puerta de entrada cerrada.

Cómo configurar los puertos

Ve al panel de DonWeb, busca la sección de Firewall o Configuración de puertos de tu VPS. Ahí verás una interfaz similar a esta:

Los puertos que necesitas abrir como mínimo son:

  • Puerto 80 (HTTP): Para que tu web sea accesible sin HTTPS
  • Puerto 443 (HTTPS): Para cuando configures certificados SSL
  • Puerto SSH: El que usas para conectarte (normalmente aparece ya configurado)

Pasos a seguir

  1. Identifica los puertos necesarios: Para un proyecto web básico, necesitas el 80 y 443
  2. Añade las reglas: En el panel de DonWeb, crea nuevas reglas para estos puertos
  3. Configura el origen: Normalmente puedes dejarlo como "Any" (0.0.0.0/0) para que sea accesible desde cualquier lugar
  4. Aplica los cambios: Guarda la configuración y espera unos segundos a que se aplique

¿Qué pasa si no configuras esto?

Si no abres estos puertos, aunque tu aplicación esté funcionando perfectamente en el servidor, cuando intentes acceder desde tu navegador verás errores tipo "No se puede conectar" o "Tiempo de espera agotado". Es uno de los errores más comunes y que más frustración genera, especialmente cuando todo lo demás está bien configurado.

💡 Tip importante: Si tu aplicación Node.js usa un puerto diferente (como el 3000), también necesitarás abrirlo en el firewall, o mejor aún, configurar Nginx como proxy inverso para que sirva tu aplicación a través del puerto 80/443.

Una vez tengas los puertos configurados correctamente, podrás acceder a tu servidor desde el navegador usando la IP que te proporciona DonWeb, y deberías ver la página de bienvenida de Nginx.

Preparar el acceso SSH para despliegue con GitHub Actions

Ya tenemos tanto backend como frontend preparados para desplegar y un servidor web disponible para servir tu proyecto.

Pero, ¿cómo vamos a subir los archivos de tu proyecto al servidor? ¿Y cómo vamos a hacer que GitHub Actions pueda desplegar automáticamente cada vez que subas cambios?
Para esto, vamos a configurar el acceso SSH para el usuario deploy que acabamos de crear.

¿Por qué necesitas esto?

GitHub Actions puede ejecutar scripts y comandos automáticamente cada vez que subes código (push).

Para que pueda copiar los archivos o ejecutar comandos en tu servidor, necesita conectarse por SSH sin pedirte la contraseña cada vez. Así te olvidas de hacer zips con el build del proyecto de ftp y subirlo manualmente. Esto normalmente se tarda mucho tiempo, son muchos pasos y cuantos más pasos más probable es que algo falle (sobre todo si lo haces a última hora 👀 que ya sabemos lo que pasa).

Por seguridad y automatización, se usan claves SSH, no contraseñas. Así no tienes que escribir la contraseña cada vez que quieras hacer un despliegue ni hardcodear la contraseña en tu repositorio de GitHub (que también te veo venir).

Pasos para configurar SSH para el usuario deploy

Entonces desde la terminal nos vamos a tu servidor VPS y vas a ejecutar el siguiente comando:

ssh-keygen -t ed25519 -C "deploy@tuproyecto"
Enter fullscreen mode Exit fullscreen mode

Pulsa Enter en todas las preguntas (puedes poner una ruta o dejar la predeterminada y no pongas passphrase).

Copia la clave pública al servidor usando el siguiente comando (reemplaza los datos según tu configuración):

ssh-copy-id -p[tu puerto] deploy@[tu_direccion_IP]
Enter fullscreen mode Exit fullscreen mode

Si no tienes ssh-copy-id, puedes copiar manualmente el contenido de ~/.ssh/id_ed25519.pub al archivo ~/.ssh/authorized_keys en el servidor, dentro del usuario deploy. Puede ser que tengas que crear o la carpeta .ssh o el archivo authorized_keys si no existen. Revísalo primero con un ls -la en la carpeta del usuario deploy.

mkdir -p ~/.ssh
echo "tu_clave_publica" >> ~/.ssh/authorized_keys
Enter fullscreen mode Exit fullscreen mode

Una vez lo tenemos, vamos a asegurarnos de que los permisos son correctos:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Enter fullscreen mode Exit fullscreen mode

Ahora ya podemos usar las claves SSH para conectarnos al servidor desde GitHub Actions sin necesidad de introducir la contraseña cada vez y comenzar a desplegar tu proyecto automáticamente.

Configurar GitHub Actions para usar la clave privada

Abre tu clave privada (por ejemplo, ~/.ssh/id_ed25519) con un editor de texto y cópiala entera.

Ve a tu repositorio en GitHub → Settings → Secrets and variables → Actions.

Crea un nuevo Secret llamado, por ejemplo, DEPLOY_KEY y pega ahí el contenido de la clave privada.

Y ya está, ahora tu GitHub Actions puede usar esta clave para conectarse a tu servidor y desplegar tu proyecto automáticamente.

Aún queda un paso más. Ahora mismo lo único que hemos hecho es guardar la clave privada en GitHub de manera segura, pero aún no le hemos dicho a GitHub Actions que la use y lo más importante no le hemos dicho cómo ha de usarla.

Configurar un workflow de GitHub Actions para desplegar tu proyecto

Aquí es donde empieza la fiesta realmente. Hay muchas formas de hacer esto y sobre todo ha de ser adaptado a tu proyecto, según estés usando Frontend con (React, Angular, Vue, Svelte, etc.) o Backend con Node.js (Express, NestJS, etc.) o cualquier otro lenguaje o framework. Cada uno tiene su propia manera de ser desplegado, así que eso tendrás que adaptarlo a tu proyecto.

Pero te voy a dar un ejemplo básico de cómo podrías configurar un workflow de GitHub Actions para desplegar tu proyecto al servidor usando un HTML estático simulando un build de un proyecto de frontend ya realizado.

📚 Contenido relacionado: Si tienes un proyecto Angular y quieres desplegarlo, puedes ver mi post sobre cómo desplegar Angular 19 en GitHub Pages. Esta enfocado a GitHub Pages pero puedes adaptarlo al VPS sin problema.

Lo primero necesitarás crear una carpeta en tu proyecto llamada .github/workflows y dentro de esta un archivo llamado deploy.yml o el nombre que quieras, pero con la extensión .yml. Aquí es donde vamos a definir el workflow de GitHub Actions que no es nada más que un conjunto de pasos que se ejecutarán automáticamente cada vez que subas cambios a tu repositorio.

Te dejo un ejemplo básico de cómo podría ser este archivo:

¿Quieres ver en detalle un workflow de GitHub Actions completo? o alguna tecnología en concreto? Dímelo en los comentarios y lo preparo para un próximo post.

name: 🚀 Deploy Web to VPS

on:
  push:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: "pages"
  cancel-in-progress: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: ⚙️ Execute Deployment SSH Command
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USERNAME }}
          key: ${{ secrets.VPS_SSH_KEY }}
          port: ${{ secrets.VPS_SSH_PORT }}
          script: |
            cd /var/www/html/
            if [ -d "[nombre proyecto]/.git" ]; then
              echo "El repositorio ya existe, haciendo pull..."
              cd [nombre proyecto]
              git pull
            else
              if [ -d "[nombre proyecto]" ]; then
                echo "Existe [nombre proyecto] pero NO es repo, borrando carpeta..."
                rm -rf [nombre proyecto]
              fi
              echo "Clonando repo..."
              git clone ${{ secrets.VPS_REPO_URL }}
            fi
Enter fullscreen mode Exit fullscreen mode

Explicación del workflow de GitHub Actions paso a paso

Ahora que ya tienes el archivo YAML del workflow, vamos a explicar qué hace cada parte para que entiendas exactamente cómo funciona este despliegue automático.

Configuración básica del workflow

name: 🚀 Deploy Web to VPS
Enter fullscreen mode Exit fullscreen mode

Aquí defines el nombre que aparecerá en la pestaña de Actions de tu repositorio de GitHub. El emoji es opcional pero ayuda a identificar rápidamente el workflow.

Disparadores del workflow

on:
  push:
    branches: [main]
  workflow_dispatch:
Enter fullscreen mode Exit fullscreen mode

Esta sección define cuándo se ejecutará el workflow:

  • push: branches: [main] → Se ejecuta automáticamente cada vez que haces push a la rama main
  • workflow_dispatch → Te permite ejecutar el workflow manualmente desde la interfaz de GitHub

¿Por qué usar ambos? El automático te ahorra trabajo en el día a día, y el manual te da control cuando necesitas hacer un despliegue específico.

Permisos y concurrencia

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: "pages"
  cancel-in-progress: true
Enter fullscreen mode Exit fullscreen mode

Permisos: Define qué puede hacer GitHub Actions en tu repositorio:

  • contents: read → Puede leer el código de tu repositorio
  • pages: write → Puede escribir en GitHub Pages (si lo usas)
  • id-token: write → Puede generar tokens de identidad para autenticación

Concurrencia: Evita que se ejecuten múltiples despliegues al mismo tiempo:

  • Si hay un despliegue en curso y haces otro push, cancela el anterior y ejecuta el nuevo
  • Esto previene conflictos y problemas de estado inconsistente

Definición del trabajo (job)

jobs:
  deploy:
    runs-on: ubuntu-latest
Enter fullscreen mode Exit fullscreen mode

Aquí defines:

  • deploy → Nombre del trabajo (puedes tener varios jobs en un workflow)
  • runs-on: ubuntu-latest → El sistema operativo donde se ejecutará (GitHub proporciona la máquina virtual)

El paso de despliegue

steps:
  - name: ⚙️ Execute Deployment SSH Command
    uses: appleboy/ssh-action@v1
Enter fullscreen mode Exit fullscreen mode

¿Qué es appleboy/ssh-action? Es una acción desarrollada por la comunidad que facilita ejecutar comandos SSH desde GitHub Actions. Es como si GitHub se conectara por SSH a tu servidor y ejecutara comandos automáticamente.

Configuración de la conexión SSH

with:
  host: ${{ secrets.VPS_HOST }}
  username: ${{ secrets.VPS_USERNAME }}
  key: ${{ secrets.VPS_SSH_KEY }}
  port: ${{ secrets.VPS_SSH_PORT }}
Enter fullscreen mode Exit fullscreen mode

Estos son los GitHub Secrets que configuraste antes:

  • VPS_HOST → La IP de tu servidor
  • VPS_USERNAME → El usuario deploy que creaste
  • VPS_SSH_KEY → La clave privada SSH
  • VPS_SSH_PORT → El puerto SSH de tu servidor

¿Por qué secrets? Porque esta información es sensible y no debe estar visible en tu código público.

La lógica del script de despliegue

script: |
  cd /var/www/html/proyects/
  if [ -d "[nombre proyecto]/.git" ]; then
    echo "El repositorio ya existe, haciendo pull..."
    cd [nombre proyecto]
    git pull
  else
    if [ -d "[nombre proyecto]" ]; then
      echo "Existe [nombre proyecto] pero NO es repo, borrando carpeta..."
      rm -rf [nombre proyecto]
    fi
    echo "Clonando repo..."
    git clone ${{ secrets.VPS_REPO_URL }}
  fi
Enter fullscreen mode Exit fullscreen mode

Vale, ahora vamos a lo que realmente hace este script cuando se ejecuta en tu servidor. Primero se mueve a la carpeta /var/www/html/ que es donde están los archivos que Nginx sirve por defecto. Una vez ahí, lo primero que hace es verificar si ya existe una carpeta con el nombre de tu proyecto y además si esa carpeta es un repositorio Git válido.

Si encuentra que ya tienes el proyecto ahí y es un repo Git, genial, solo hace un git pull para bajarse los últimos cambios que hayas hecho. Es súper eficiente porque no tiene que descargar todo otra vez, solo los archivos que cambiaron.

Pero si encuentra una carpeta con el nombre de tu proyecto pero resulta que no es un repositorio Git (esto puede pasar si algo se rompió antes o si pusiste archivos manualmente), lo que hace es borrar toda esa carpeta y empezar de cero. Mejor limpio que con archivos raros por ahí.

Y finalmente, si no existe absolutamente nada, pues clona el repositorio completo desde GitHub usando la URL que tienes guardada en los secrets.

¿Por qué funciona tan bien esta lógica?

Si ya tienes el proyecto desplegado, solo actualiza lo que necesita, que es mucho más rápido que estar bajando todo cada vez. Y si algo falló en algún momento (que pasa más de lo que te imaginas), no se queda ahí dando vueltas con archivos corruptos, simplemente borra todo y empieza fresh.

Además funciona igual de bien tanto si es la primera vez que despliegas como si ya llevas meses actualizando el proyecto. No tienes que estar pensando en casos especiales ni nada raro.

Un detalle importante sobre los secrets

Ojo que aparte de todos los secrets de SSH que configuramos antes, también vas a necesitar agregar VPS_REPO_URL en GitHub. Este es simplemente la URL de tu repositorio, algo como https://github.com/tuusuario/tuproyecto.git. Nada del otro mundo pero es importante no olvidarlo.

Cómo funciona todo el proceso completo

En resumen, cada vez que haces push a main, GitHub se da cuenta automáticamente y arranca todo el proceso. Crea una máquina virtual con Ubuntu (que es gratis, por cierto), se conecta por SSH a tu VPS usando todas las credenciales que guardaste de forma segura, ejecuta el script que acabamos de ver y boom, tu proyecto queda desplegado con la última versión.

¡Y ya está! Te olvidas completamente de estar subiendo archivos a mano, de hacer FTP, de comprimir carpetas y toda esa marabunta. Cada vez que hagas un cambio en tu código y lo subas a GitHub, automáticamente se despliega en tu servidor. Es como magia pero que realmente entiendes cómo funciona.

💡 Tip: Puedes personalizar este workflow según tu proyecto. Por ejemplo, si usas React, podrías añadir pasos para hacer npm install y npm run build antes del despliegue.

Como ves este script es muy básico y puedes adaptarlo y mejorar muchísimo. Te animo a que lo hagas, y si realmente quieres o tienes dudas, no dudes en preguntarme en los comentarios y preparo un post centrado sólo en GitHub Actions y cómo hacer despliegues más avanzados.

💡 Contenido relacionado: Si quieres ver un ejemplo práctico de GitHub Actions en acción, he creado un post sobre cómo desplegar Angular 19 en GitHub Pages desde GitHub Actions, donde explico paso a paso un workflow completo para proyectos frontend.

Mejoras y optimizaciones avanzadas

El workflow que acabamos de ver es funcional, pero hay muchas formas de mejorarlo. Aquí te dejo algunas ideas para que puedas expandir y optimizar tu setup:

🔒 Nota importante de seguridad: Este tutorial está enfocado en el aprendizaje y la funcionalidad básica. Para entornos de producción empresariales, considera implementar medidas adicionales como fail2ban, configuración de firewall más restrictiva, auditorías de seguridad regulares y políticas de acceso más estrictas.

🚀 ¿Quieres que haga una segunda parte sobre despliegue avanzado?

Estas son solo algunas ideas básicas. Si hay interés, puedo preparar un post completo cubriendo temas avanzados como

  • Seguridad avanzada: Configuración de fail2ban, certificados SSL automáticos con Let's Encrypt, hardening del servidor
  • Nginx avanzado: Configuración como proxy inverso, configuración específica de proyectos, load balancing, optimización de performance
  • Monitoreo y logs: Configuración de Grafana, Prometheus, gestión centralizada de logs
  • Bases de datos: Instalación y configuración de MySQL, PostgreSQL, MongoDB con backups automáticos
  • Dockerización completa: Convertir todo el setup a contenedores Docker con Docker Compose
  • CI/CD robusto: Tests automáticos, análisis de código, despliegues con aprobación manual
  • Entornos diferenciados: Configuración entornos de desarrollo, staging y producción con GitHub Actions

💡 Tip para proyectos robustos: Si quieres asegurar la calidad de tu código antes del despliegue, te recomiendo configurar herramientas de linting y formateo. Tengo un post completo sobre cómo crear un proyecto nuevo con ESLint, Stylelint, Commitlint y Husky que te ayudará a automatizar las verificaciones de calidad antes de cada commit.

¡Comenta si te interesa alguno de estos temas y veré cuál es el que más demanda tiene para hacer la segunda parte!

Solución de problemas comunes

Cuando empiezas con despliegues en VPS, es normal que te encuentres con algunos problemas. Aquí te dejo los más comunes y cómo solucionarlos:

Error: "Permission denied" al hacer git pull

Si tu workflow falla con errores de permisos:

# En tu servidor, asegúrate de que el usuario deploy es el propietario
sudo chown -R deploy:deploy /var/www/html/
sudo chmod -R 755 /var/www/html/
Enter fullscreen mode Exit fullscreen mode

Error: "Host key verification failed"

Si GitHub Actions no puede conectarse por SSH:

# En tu servidor, regenera las claves SSH
ssh-keygen -R github.com
ssh-keyscan github.com >> ~/.ssh/known_hosts
Enter fullscreen mode Exit fullscreen mode

Nginx muestra "403 Forbidden"

Si tu web no se ve correctamente:

# Verifica los permisos de la carpeta web
sudo chmod -R 755 /var/www/html/
sudo chown -R www-data:www-data /var/www/html/
Enter fullscreen mode Exit fullscreen mode

El workflow se ejecuta pero no se actualiza la web

Verifica que los archivos están en el lugar correcto:

# Conecta por SSH y verifica
ls -la /var/www/html/[tu-proyecto]/
# Si es un proyecto con build, asegúrate de copiar los archivos compilados a la carpeta correcta
Enter fullscreen mode Exit fullscreen mode

🔧 Tip de debugging: Siempre puedes conectarte por SSH a tu servidor después de un despliegue para verificar qué está pasando. Los logs de Nginx están en /var/log/nginx/ y puedes verlos con sudo tail -f /var/log/nginx/error.log

Conclusión

El proceso te va a llevar poco tiempo. Calculo que unas 2 horas si es la primera vez que lo haces, pero una vez lo tengas montado, cada vez que hagas un cambio en tu proyecto y lo subas a GitHub, se desplegará automáticamente en tu servidor sin que tengas que hacer nada más.

Y lo mejor de todo, te quitas de encima el miedo a que algo falle el día de la defensa. Tu proyecto estará siempre actualizado y funcionando, y tú podrás centrarte en lo que realmente importa: demostrar todo lo que has aprendido.

Recuerda darle las gracias a https://donweb.com/es-es/cloud-server-altaskur por el apoyo y por facilitarme un VPS para hacer las pruebas y capturas de este post. Si quieres probarlo, puedes crear una cuenta en DonWeb.

Y si tienes alguna duda o quieres que profundice en algún aspecto, ¡déjamelo en los comentarios!

Top comments (0)