--- title: "Cómo crear una página de estado estática con cState y Hugo" description: "Crea una página de estado estática con cState y Hugo en Ubuntu 24.04, define tus servicios, publica incidentes en Markdown y despliégala en GitHub Pages." category: "Páginas de Estado e Incidentes" language: es source: https://cubepath.com/es/docs/páginas-de-estado-e-incidentes/instalacion-de-cstate-pagina-de-estado-estatica updated: 2026-09-25 --- # Cómo crear una página de estado estática con cState y Hugo cState es un tema de Hugo que genera una página de estado totalmente estática: no necesita base de datos ni servidor de aplicaciones, y cada incidente es un archivo Markdown guardado en Git. Eso la hace ideal para alojarla fuera de tu propia infraestructura, que es justo lo que se quiere de una página de estado. En este tutorial prepararás el proyecto en Ubuntu 24.04, definirás tus servicios, publicarás un incidente y desplegarás la página en GitHub Pages con un dominio propio. ## Requisitos previos - Un equipo o servidor con Ubuntu 24.04 LTS para editar y previsualizar la página, por ejemplo un VPS de CubePath. - Un usuario no root con privilegios `sudo`. - Una cuenta de GitHub y Git configurado con tu nombre y correo. - Opcional: un subdominio como `status.your_domain` para publicar la página. > Nota: aloja la página de estado fuera de la infraestructura que describe. Si la sirves desde el mismo servidor que se cae, nadie podrá ver el aviso. GitHub Pages cumple ese requisito sin coste. ## Paso 1: Instalar Git y Hugo extended cState necesita la edición *extended* de Hugo, que incluye el compilador de Sass. Además, los temas de Hugo dependen de la versión del generador, así que conviene usar la misma versión que usa el proyecto de ejemplo de cState en lugar de la última. Instala Git y clona el proyecto de ejemplo junto con el tema, que se incluye como submódulo: ```bash sudo apt update sudo apt install git git clone --recurse-submodules https://github.com/cstate/example.git status-page cd status-page ``` Consulta qué versión de Hugo fija el ejemplo en su configuración de Netlify: ```bash grep HUGO_VERSION netlify.toml ``` ```output HUGO_VERSION = "0.xx.x" ``` Descarga el paquete `.deb` de Hugo extended de esa versión desde las releases oficiales de GitHub e instálalo. Sustituye `0.xx.x` por el valor anterior: ```bash HUGO_VERSION=0.xx.x wget "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb" sudo apt install "./hugo_extended_${HUGO_VERSION}_linux-amd64.deb" ``` En un servidor arm64 usa el archivo `linux-arm64.deb`. Comprueba que tienes la edición extended: ```bash hugo version ``` ```output hugo v0.xx.x-...+extended linux/amd64 BuildDate=... ``` No uses el paquete `hugo` de los repositorios de Ubuntu: su versión no la eliges tú y puede no coincidir con la que espera el tema. ## Paso 2: Previsualizar la página en local Arranca el servidor de desarrollo de Hugo. Si trabajas en un VPS remoto, añade `--bind 0.0.0.0` y abre temporalmente el puerto 1313 con `sudo ufw allow 1313/tcp`: ```bash hugo server ``` ```output Web Server is available at http://localhost:1313/ (bind address 127.0.0.1) Press Ctrl+C to stop ``` Abre `http://localhost:1313` en el navegador. Verás la página de ejemplo con varios servicios y algunos incidentes de muestra. El servidor recarga la página cada vez que guardas un archivo, así que déjalo abierto en otra terminal mientras sigues. ## Paso 3: Configurar el sitio y tus servicios Toda la configuración está en `config.yml`. Ábrelo: ```bash nano config.yml ``` Cambia primero los datos generales del sitio, con tu dominio en `baseURL`: ```yaml baseURL: https://status.your_domain/ title: Estado de los servicios languageCode: es ``` Busca dentro de `params` las listas `categories` y `systems`. Los *systems* son los componentes que aparecen en la página y cada uno pertenece a una categoría. Sustituye los del ejemplo por los tuyos, manteniendo el mismo formato que trae el archivo: ```yaml categories: - name: Servicios web description: Servicios que usan directamente los clientes - name: Infraestructura description: Red y servidores systems: - name: Web description: Sitio web público category: Servicios web - name: API description: API REST de la aplicación category: Servicios web - name: Red description: Conectividad de los servidores category: Infraestructura ``` El nombre de cada system es el que usarás luego en el campo `affected` de los incidentes, así que elige nombres cortos y estables. Guarda y comprueba en el navegador que aparecen tus servicios agrupados por categoría. Borra los incidentes de ejemplo para empezar con el historial limpio: ```bash rm content/issues/*.md ``` ## Paso 4: Publicar un incidente Cada incidente es un archivo en `content/issues/`. El ejemplo incluye una plantilla (archetype), así que puedes crear el archivo con Hugo: ```bash hugo new issues/2026-09-25-latencia-api.md ``` ```output Content "/home/your_user/status-page/content/issues/2026-09-25-latencia-api.md" created ``` Ábrelo y rellena la cabecera y el texto: ```bash nano content/issues/2026-09-25-latencia-api.md ``` ```markdown --- title: Latencia elevada en la API date: 2026-09-25T10:30:00+02:00 resolved: false resolvedWhen: severity: disrupted affected: - API section: issue --- Estamos investigando tiempos de respuesta elevados en la API. La web sigue funcionando con normalidad. **Actualización 10:50:** hemos identificado la causa y estamos aplicando la corrección. ``` Los campos que controlan el estado son: - `severity`: `notice` (aviso o mantenimiento), `disrupted` (degradado) o `down` (caído). El componente afectado toma ese estado mientras el incidente no esté resuelto. - `affected`: lista de systems afectados, escritos igual que en `config.yml`. - `resolved` y `resolvedWhen`: cuando el problema se soluciona, pon `resolved: true` y la fecha de resolución, y el componente vuelve a operativo. En la previsualización, el servicio API debe aparecer como degradado y el incidente en la portada. Si no aparece, revisa que `date` no esté en el futuro: Hugo no publica contenido con fecha futura por defecto. ## Paso 5: Subir el proyecto a GitHub Crea un repositorio vacío en GitHub, por ejemplo `your_user/status-page`. El clon apunta todavía al repositorio de ejemplo, así que cambia el remoto y sube tu versión: ```bash git remote set-url origin git@github.com:your_user/status-page.git git add -A git commit -m "Configuración inicial de la página de estado" git push -u origin HEAD:main ``` Asegúrate de que la carpeta `public/`, que genera Hugo, no se sube al repositorio: ```bash grep -qx "public/" .gitignore || echo "public/" >> .gitignore ``` ## Paso 6: Desplegar en GitHub Pages con GitHub Actions GitHub construirá la página con Hugo en cada push. Crea el workflow: ```bash mkdir -p .github/workflows nano .github/workflows/pages.yml ``` Pega el siguiente contenido, con la misma versión de Hugo del paso 1 en `HUGO_VERSION`: ```yaml name: Desplegar página de estado on: push: branches: [main] workflow_dispatch: permissions: contents: read pages: write id-token: write concurrency: group: pages cancel-in-progress: false jobs: build: runs-on: ubuntu-latest env: HUGO_VERSION: 0.xx.x steps: - name: Instalar Hugo extended run: | wget -O "${{ runner.temp }}/hugo.deb" "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb" sudo dpkg -i "${{ runner.temp }}/hugo.deb" - name: Checkout uses: actions/checkout@v4 with: submodules: recursive - name: Configurar Pages id: pages uses: actions/configure-pages@v5 - name: Construir run: hugo --minify --baseURL "${{ steps.pages.outputs.base_url }}/" - name: Subir artefacto uses: actions/upload-pages-artifact@v3 with: path: ./public deploy: needs: build runs-on: ubuntu-latest environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - name: Desplegar id: deployment uses: actions/deploy-pages@v4 ``` En GitHub, ve a **Settings > Pages** del repositorio y en **Source** elige **GitHub Actions**. Después sube el workflow: ```bash git add .github/workflows/pages.yml .gitignore git commit -m "Despliegue en GitHub Pages" git push ``` En la pestaña **Actions** verás el workflow en ejecución. Cuando termine, la página estará disponible en `https://your_user.github.io/status-page/`. ### Usar un dominio propio Crea en tu DNS un registro CNAME de `status.your_domain` hacia `your_user.github.io`. Después, en **Settings > Pages > Custom domain**, escribe `status.your_domain`, espera a que GitHub valide el dominio y marca **Enforce HTTPS**. Comprueba el resultado: ```bash curl -sI https://status.your_domain | head -n 1 ``` ```output HTTP/2 200 ``` ## Paso 7: Resolver el incidente El flujo de trabajo durante un incidente es editar el Markdown y hacer push. Cuando el problema esté solucionado, marca el incidente como resuelto: ```yaml resolved: true resolvedWhen: 2026-09-25T11:15:00+02:00 ``` Añade una última actualización al texto, haz commit y push: ```bash git add content/issues/ git commit -m "Incidente latencia API resuelto" git push ``` En uno o dos minutos la API vuelve a aparecer como operativa y el incidente pasa al historial. También puedes editar el archivo desde la web de GitHub, algo útil si no tienes acceso a tu equipo durante una caída. ## Solución de problemas **`hugo server` falla con un error de SCSS o de plantillas.** Casi siempre es una versión de Hugo que no es extended o que no coincide con la del ejemplo. Revisa `hugo version` y vuelve al paso 1. **El tema no aparece o la página sale en blanco.** El submódulo no se ha descargado. Ejecuta `git submodule update --init --recursive` y comprueba que `themes/cstate` tiene contenido. En el workflow, `submodules: recursive` hace lo mismo. **La página publicada no tiene estilos.** `baseURL` no coincide con la URL real. El workflow ya la sobrescribe con la de GitHub Pages; si usas dominio propio, comprueba que está configurado en **Settings > Pages**. ## Conclusión Tienes una página de estado estática con cState, tus servicios agrupados por categorías, incidentes versionados en Git y despliegue automático en GitHub Pages con dominio propio. Como siguientes pasos, puedes dar acceso de escritura al repositorio a las personas de guardia, preparar plantillas de texto para los incidentes más habituales y enlazar la página desde el pie de tu web y tu panel de clientes.