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_domainpara publicar la página.
Notaaloja 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:
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:
grep HUGO_VERSION netlify.toml
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:
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:
hugo version
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:
hugo server
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:
nano config.yml
Cambia primero los datos generales del sitio, con tu dominio en baseURL:
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:
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:
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:
hugo new issues/2026-09-25-latencia-api.md
Content "/home/your_user/status-page/content/issues/2026-09-25-latencia-api.md" created
Ábrelo y rellena la cabecera y el texto:
nano content/issues/2026-09-25-latencia-api.md
---
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) odown(caído). El componente afectado toma ese estado mientras el incidente no esté resuelto.affected: lista de systems afectados, escritos igual que enconfig.yml.resolvedyresolvedWhen: cuando el problema se soluciona, ponresolved: truey 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:
git remote set-url origin [email protected]: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:
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:
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:
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:
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:
curl -sI https://status.your_domain | head -n 1
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:
resolved: true
resolvedWhen: 2026-09-25T11:15:00+02:00
Añade una última actualización al texto, haz commit y push:
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.
