Skip to main content

        Github: Guía Despliegue CI-CD de Hugo a Servidor con GitHub Actions Monorepo - Featured image

Github: Guía Despliegue CI-CD de Hugo a Servidor con GitHub Actions Monorepo

Objetivo: Eliminar el proceso manual de compilar y copiar la carpeta public/ al servidor. Implementaremos un pipeline que, al detectar un git push en la rama principal, compile el sitio y lo transfiera vía SFTP de forma segura utilizando llaves SSH.

Seguridad: Implementación del menor privilegio

En entornos de producción reales, no usamos root. El despliegue se realiza con un usuario restringido que solo tiene acceso a su propio directorio personal. Esto añade una capa de seguridad vital: si el proceso de CI/CD se ve comprometido, el atacante queda atrapado en una “jaula” dentro del $HOME del usuario.

Fase 1: Preparación del Servidor (VPS)

Para que GitHub Actions pueda acceder al VPS sin interacción humana, necesitamos autenticación basada en llaves SSH (sin contraseña).

  1. Abre la terminal y conéctate a tu VPS.

  2. Genera un nuevo par de llaves criptográficas (cuando pida passphrase, presiona Enter para dejarlo en blanco):

ssh-keygen -m PEM -t rsa -b 4096 -f ~/.ssh/github_actions -C "github-cicd"

alt text

  1. Autoriza la llave pública en el servidor:
# Append the new public key to authorized_keys
cat ~/.ssh/github_actions.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

alt text

  1. Imprime la llave privada en pantalla y cópiala completa (desde -----BEGIN hasta END-----):
# Read private key to copy to GitHub Secrets
cat ~/.ssh/github_actions

alt text

Fase 2: Configuración de GitHub Secrets

Por seguridad, las credenciales del servidor jamás deben ir en el código.

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

alt text

  1. Crea los siguientes Repository secrets:

alt text

Repite el proceso para cada “variable”.

  • FTP_SERVER: La IP pública o dominio de tu VPS (ej. 198.51.100.1).

  • FTP_USERNAME: Tu usuario SSH (ej. root o admin).

  • FTP_PORT: 22 (o el puerto SSH personalizado que uses).

  • FTP_SSH_KEY: Pega aquí el contenido exacto de la llave privada que copiaste en la Fase 1.

Fase 3: Creación del Pipeline (YAML)

Dado que tenemos una estructura tipo Monorepo (donde el blog vive dentro de la subcarpeta mxlit-blog/), configuraremos el workflow para que solo compile y despliegue cuando haya cambios específicos en ese directorio.

  1. En la raíz de tu repositorio local (al nivel de la carpeta mxlit-site), crea la ruta: .github/workflows/.

alt text

  1. Dentro, crea un archivo llamado deploy-mxlit.yml y pega este código:
name: Deploy MXLIT to VPS via SFTP

on:
  push:
    branches:
      - main
    paths:
      - 'mxlit-site/mxlit-blog/**'

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          submodules: true 
          fetch-depth: 0   

      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v3
        with:
          hugo-version: 'latest'
          extended: true 

      - name: Build Hugo site
        run: hugo --source mxlit-site/mxlit-blog --minify

      - name: SFTP Deploy
        uses: wlixcc/[email protected]
        with:
          username: ${{ secrets.FTP_USERNAME }}
          server: ${{ secrets.FTP_SERVER }}
          port: ${{ secrets.FTP_PORT }}
          ssh_private_key: ${{ secrets.FTP_SSH_KEY }}
          local_path: './mxlit-site/mxlit-blog/public/*'
          remote_path: '/YourPathHere'  #<----------- Add your path here!
          # Ensure old files are removed from the destination to keep it clean
          delete_remote_files: true
          args: '-o ConnectTimeout=5'

alt text

Fase 4: Despliegue a Producción

El pipeline ya está configurado. El flujo de trabajo diario ahora es simplemente:

  1. Escribir o modificar contenido en Obsidian.

  2. Abrir la terminal y ejecutar:

# Add changes, commit, and push to trigger the pipeline
git add .
git commit -m "docs: add cicd pipeline documentation"
git push origin main
  1. Ir a la pestaña Actions en GitHub para ver la compilación en tiempo real (toma menos de 30 segundos).

alt text


Conclusión

Implementar un flujo de CI/CD para un sitio estático no es solo una cuestión de comodidad; es una estrategia para garantizar que el despliegue sea predecible, seguro y libre de errores humanos. Al pasar de un proceso manual de copia por SFTP a una automatización basada en eventos con GitHub Actions, transformamos nuestro repositorio en la única “fuente de verdad” (Single Source of Truth).

Esta arquitectura monorepo nos permite escalar otros proyectos bajo el mismo paraguas de Git, manteniendo una separación clara de responsabilidades y un historial de cambios auditable. Ahora, el enfoque vuelve a ser lo más importante: crear contenido de valor, sabiendo que la infraestructura se encarga del resto en cuestión de segundos.