Desplegar en VPS con GitHub Actions paso a paso
Desplegar en VPS con GitHub Actions significa automatizar el deploy de tu proyecto: hacés git push a la rama principal y un workflow se conecta por SSH al servidor, reconstruye los contenedores y publica los cambios. Sin entrar a mano cada vez. Te ahorra el ritual manual y, sobre todo, los errores tontos de las 11 de la noche.
GitHub Actions es la plataforma de integración y entrega continua (CI/CD) integrada en GitHub desde 2019. Corre flujos de trabajo (workflows) definidos en archivos YAML dentro de .github/workflows/, disparados por eventos como un push o un pull request. Para publicar en un VPS, el workflow abre una conexión SSH al servidor y ejecuta los comandos de build y deploy que vos definas, sin servicios intermedios.
En 30 segundos
- Qué resuelve: reemplaza el deploy manual (entrar por SSH, navegar a la carpeta, correr
docker compose up -d --build) por un push a la rama main. - Qué necesitás: un VPS con acceso SSH, un repo en GitHub y, lo recomendable, Docker instalado en el servidor.
- Cómo se autentica: con un par de claves SSH; la clave privada vive cifrada en GitHub Secrets, nunca en el código.
- Dónde se define: en un archivo
deploy.ymldentro de.github/workflows/, disparado poron: push. - Costo: en repos públicos, GitHub Actions es gratis; en privados, hay minutos incluidos por mes según el plan.
¿Por qué automatizar el deploy en vez de hacerlo a mano?
El caso que cuenta el autor de este tutorial en dev.to lo conoce cualquiera que tenga un VPS propio. Alquiló un servidor a principios de 2025 para sus proyectos personales y cada cambio implicaba el mismo ritual: conectarse por SSH, navegar hasta la carpeta del proyecto y correr docker compose up -d --build.
El problema no es que sea difícil. Es que es aburrido y desmotiva. Él mismo lo admite: muchas veces terminaba no haciendo los cambios que quería justamente para no pasar por ese flujo repetitivo.
Y ahí está el punto real. Cuando un proceso tiene fricción, dejás de iterar. Probás menos cosas. El deploy manual además suma latencia (esa demora molesta entre que tipeás un caracter en la terminal y el VPS responde) y, lo peor, depende de que te acuerdes de todos los pasos en el orden correcto. Tener una pipeline de CI/CD reduce todo eso a una sola acción: un commit. Esto se conecta con lo que analizamos en alternativas de CI/CD disponibles en 2026.
¿Qué requisitos necesito para desplegar en VPS con GitHub Actions?
Antes de tocar un solo YAML, conviene tener esto resuelto:
- Un VPS con acceso SSH habilitado. Cualquier servidor Linux con un usuario y el puerto 22 (o el que uses) accesible. Si todavía no tenés uno, en donweb.com conseguís VPS con root y SSH desde Argentina.
- Un repositorio en GitHub. Público o privado, da igual para el setup; cambia solo el tema de los minutos gratis.
- Docker y Docker Compose en el servidor. No es estrictamente obligatorio, pero si tu app ya corre en contenedores, el deploy se vuelve trivial: el workflow solo dispara un
up --build. - Un par de claves SSH. Una privada que guardás en GitHub Secrets y una pública que dejás en el servidor. Si nunca generaste una, es un comando:
ssh-keygen.
¿Hace falta Docker sí o sí? No. Podés desplegar un sitio estático copiando archivos por rsync, o reiniciar un servicio con systemctl. Pero si ya venías levantando todo con Compose, no le agregues complejidad: usá lo que tenés.
¿Cómo habilito GitHub Actions en mi repositorio?
El primer paso es habilitar Actions y, acá viene lo importante, restringir qué workflows puede correr tu repo. En la fuente original el autor elige esto por seguridad, para que ninguna action maliciosa de un tercero desconocido entre por la ventana.
- Andá a Settings > Actions > General dentro de tu repositorio en GitHub.
- En “Actions permissions”, elegí la opción restringida: permitir las actions creadas por GitHub y las del Marketplace verificado, en lugar de “permitir todo”.
- Guardá los cambios. Con eso ya podés crear tu primer workflow.
Después vas a Settings > Secrets and variables > Actions y cargás los datos sensibles como secrets. Los típicos para un deploy por SSH son tres: SSH_PRIVATE_KEY, SERVER_HOST (la IP) y SERVER_USER. Nunca, jamás, los pongas en el YAML en texto plano.
¿Cómo se arma el archivo de workflow para el deploy?
El workflow vive en .github/workflows/deploy.yml. Se dispara con un push a main, hace checkout del código y abre una conexión SSH al VPS para correr los comandos de despliegue. Un esqueleto mínimo y funcional se ve así:
name: Deploy to VPS
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout del repo
uses: actions/checkout@v4
- name: Conectar por SSH y desplegar
uses: appleboy/ssh-action@v1
with:
host: ${ secrets.SERVER_HOST }
username: ${ secrets.SERVER_USER }
key: ${ secrets.SSH_PRIVATE_KEY }
script: |
cd /ruta/a/tu/proyecto
git pull origin main
docker compose up -d --buildFijate que cada step tiene un name descriptivo. No es decoración: cuando un deploy falla, leer “Conectar por SSH y desplegar” en rojo te dice al toque dónde se rompió, en vez de hacerte adivinar entre pasos sin nombre. Te puede servir nuestra cobertura de por qué GitHub Actions es superior. La estructura exacta de los secrets y permisos puede cambiar con el tiempo, así que conviene chequear la documentación oficial de GitHub Actions antes de copiar y pegar.
¿Cómo configuro el acceso SSH de forma segura?
Esta es la parte donde más gente se manda macanas. La regla de oro: la clave privada no toca el repositorio nunca.
- Generá un par de claves dedicado:
ssh-keygen -t ed25519 -f deploy_key -C "github-actions". Usá una clave exclusiva para esto, no la misma con la que entrás vos. - Pegá la clave pública en el servidor: el contenido de
deploy_key.pubva al final de~/.ssh/authorized_keysdel usuario del VPS. - Ajustá permisos:
chmod 600 ~/.ssh/authorized_keysychmod 700 ~/.ssh. SSH es estricto con esto y, si los permisos están abiertos, ignora el archivo y la conexión falla. - Cargá la clave privada como secret: el contenido completo de
deploy_keyva aSSH_PRIVATE_KEYen GitHub. - Probá la conexión a mano primero: antes de confiar en el workflow, hacé
ssh -i deploy_key usuario@ipdesde tu máquina. Si entra, el workflow va a entrar.
¿Por qué tanto cuidado con una clave dedicada? Porque si algún día se filtra, la revocás borrando una línea del authorized_keys sin perder tu propio acceso. Acá te dejo la comparación de los métodos más comunes para mover el código al servidor:
| Método | Seguridad | Ideal para | Contra |
|---|---|---|---|
| SSH + git pull / Docker | Alta (clave cifrada en Secrets) | Apps en contenedores o con repo en el server | Requiere configurar claves |
| FTP / SFTP | Baja a media | Sitios estáticos simples | Lento, sin atomicidad, credenciales frágiles |
| Registry de Docker (pull de imagen) | Alta | Equipos con varios entornos | Más infraestructura y pasos a mantener |

¿Cómo despliego contenedores Docker desde el workflow?
Si ya usás Compose, el deploy es casi gratis. El comando central es el mismo que corrías a mano: docker compose up -d --build. La bandera -d deja los contenedores corriendo en segundo plano (detached) y --build fuerza a reconstruir la imagen con tu código nuevo. Sin --build, levantarías la imagen vieja y te preguntarías por qué “no se aplicó” el cambio.
Para un solo contenedor sin Compose, la alternativa es docker pull de tu imagen seguido de docker run, reemplazando el contenedor anterior. Funciona, pero perdés la declaratividad del docker-compose.yml, que para mí es el verdadero valor: tenés toda la topología de servicios en un archivo versionado. Lo explicamos a fondo en optimizar SEO en deployments multiidioma.
¿Cómo verifico que el deploy salió bien?
Ponele que el workflow termina en verde pero la app no responde. Pasa. Que el comando se ejecute sin error no garantiza que el servicio esté sano. Para eso:
- Definí un healthcheck en Compose: Docker chequea periódicamente que el contenedor responda y lo marca
unhealthysi no. - Mirá los logs en el último step: agregá
docker compose logs --tail=50al final del script para ver el arranque sin volver a entrar por SSH. - Sumá un status badge al README: GitHub te da un badge que muestra si el último deploy pasó o falló, visible de un vistazo.
- Validá el puerto: un
curlrápido contra el endpoint de salud confirma que el servicio está escuchando de verdad.
Qué está confirmado y qué conviene chequear
Confirmado: según la documentación oficial, GitHub Actions usa archivos YAML en .github/workflows/, dispara por eventos como push, y los secrets se inyectan con la sintaxis ${ secrets.NOMBRE }. El flujo de deploy por SSH con docker compose up -d --build está documentado en el tutorial original.
Para chequear vos: la estructura exacta del panel de permisos (Settings > Actions) y los nombres de las opciones cambian con cierta frecuencia, así que la captura que veas en un tutorial de hace un año puede no coincidir. La versión de actions de terceros (como appleboy/ssh-action) también se actualiza: anclá una versión fija (@v1) en vez de usar main.
Errores comunes (y cómo evitarlos)
- Pegar la clave privada en el YAML. El repo queda comprometido para siempre, incluso si después la borrás (queda en el historial de git). Corrección: siempre GitHub Secrets.
- Permisos mal puestos en authorized_keys. SSH ignora el archivo en silencio y la conexión falla con un “permission denied” críptico. Corrección:
chmod 600al archivo y700a la carpeta.ssh. - Olvidarse del
--build. El deploy “funciona” pero levanta la imagen vieja y jurás que tu cambio no se aplicó. Corrección:docker compose up -d --build, siempre. - Usar
@mainen actions de terceros. Un día actualizan y te rompen el pipeline sin que vos hayas tocado nada. Corrección: anclá un tag de versión.
Preguntas Frecuentes
¿Qué es GitHub Actions?
GitHub Actions es la plataforma de CI/CD integrada en GitHub que ejecuta workflows automáticos definidos en archivos YAML. Se dispara ante eventos del repositorio, como un push o un pull request, y permite automatizar tareas como tests, builds y despliegues.
¿Cómo desplegar automáticamente en un VPS con GitHub Actions?
Creás un archivo .github/workflows/deploy.yml disparado por push a la rama main. El workflow se conecta por SSH al servidor usando una clave guardada en GitHub Secrets y ejecuta los comandos de deploy, por ejemplo git pull seguido de docker compose up -d --build. Ya lo cubrimos antes en ejecutar automatizaciones sin APIs externas.
¿Cuánto cuesta usar GitHub Actions?
En repositorios públicos, GitHub Actions es gratis sin límite de minutos. En repos privados hay una cuota de minutos incluidos por mes según el plan de la cuenta, y se cobra el excedente. Para un deploy personal que tarda uno o dos minutos por push, rara vez te acercás al límite.
¿Es seguro guardar la clave SSH en GitHub Secrets?
Sí. Los GitHub Secrets se almacenan cifrados y no aparecen en los logs del workflow (GitHub los enmascara). La buena práctica es usar una clave SSH dedicada solo al deploy, así podés revocarla sin afectar tu acceso personal si alguna vez se compromete.
¿Necesito Docker para desplegar con GitHub Actions?
No es obligatorio. Podés desplegar copiando archivos con rsync o reiniciando servicios con systemctl vía SSH. Docker y Docker Compose son recomendables porque hacen el deploy reproducible y reducen el “en mi máquina funciona”, pero el workflow funciona igual sin contenedores.
Conclusión
Pasar del deploy manual a uno automático con GitHub Actions cambia tu relación con el proyecto: dejás de evitar los cambios por pereza y volvés a iterar seguido. El setup inicial es una tarde: generar una clave SSH dedicada, cargar tres secrets, escribir un YAML de quince líneas y probar la conexión a mano antes de confiar en ella. A partir de ahí, todo deploy es un git push.
Si recién arrancás, no compliques: un solo workflow disparado por la rama main, SSH con clave dedicada y docker compose up -d --build. Sumá healthchecks y logs en el último step para no quedar a ciegas. Y si todavía no tenés dónde correrlo, un VPS con SSH es todo lo que necesitás para empezar.
Fuentes
- Documentación oficial de GitHub Actions – referencia de workflows, eventos y secrets
- Deploying on a VPS with GitHub Actions (dev.to) – tutorial base de este artículo
- Deploy Docker containers in VPS with GitHub Actions (dev.to) – enfoque con contenedores
- Cómo hacer el deploy en un servidor manual y automático con GitHub Actions (holamundo.io) – guía en español






