📋 Contexto

La documentación es uno de los activos más valiosos (y descuidados) en equipos de ingeniería. Wiki interna obsoleta, Google Docs dispersos, README.md desactualizados, conocimiento tribal que solo existe en la cabeza de seniors.

Recientemente implementé Docusaurus, un generador de sitios estáticos open source creado por Meta (Facebook), para centralizar la documentación de un equipo de ingeniería. Este post documenta el proceso, problemas encontrados, y cómo podrías usar Docusaurus en tu contexto (empresa o home lab).

💡 Nota: Este post está basado en experiencia real implementando un sistema de documentación para un equipo de ingeniería, pero toda la información está generalizada para mantener confidencialidad corporativa.

🎯 ¿Qué es Docusaurus?

Docusaurus es un framework de React que convierte archivos Markdown/MDX en un sitio web de documentación profesional.

Características Principales

  • Markdown/MDX: Escribe en Markdown, con soporte para componentes React
  • Versionado: Documenta múltiples versiones de tu software/APIs
  • Search: Búsqueda full-text integrada (Algolia DocSearch gratis)
  • Dark mode: Built-in, sin configuración adicional
  • i18n: Internacionalización nativa
  • Blog integrado: Para changelogs, release notes, tutoriales
  • SEO-friendly: Static site generation (SSG)

¿Por Qué Docusaurus vs Otras Opciones?

Herramienta Pros Contras
Docusaurus Moderno, completo, mantenido por Meta Requiere Node.js, build process
MkDocs Simple, Python-based Menos features, UI básica
Confluence Enterprise, mucho features Caro, pesado, requiere Jira
Notion UI moderna, colaborativo Vendor lock-in, no code-friendly
GitHub Wiki Gratis, integrado con repos UI pobre, features limitados

🛠️ Implementación: Setup Inicial

Prerequisitos

# Node.js 18+ (recomiendo 20 LTS)
node --version

# npm o yarn
npm --version

# Git (para versionado)
git --version

Paso 1: Crear Proyecto Docusaurus

# Crear proyecto nuevo
npx create-docusaurus@latest my-docs classic

cd my-docs

# Estructura generada:
my-docs/
├── docs/                    # Documentación principal
│   └── intro.md
├── blog/                    # Blog (opcional)
│   └── welcome.md
├── src/
│   ├── components/          # Componentes React custom
│   ├── css/                 # Estilos custom
│   └── pages/               # Páginas adicionales
├── static/                  # Assets estáticos (imágenes)
├── docusaurus.config.js     # Configuración principal
└── sidebars.js              # Estructura del menú lateral

Paso 2: Configuración Básica

Editar docusaurus.config.js:

// docusaurus.config.js
module.exports = {
  title: 'Engineering Docs',
  tagline: 'Internal documentation for the engineering team',
  url: 'https://docs.mycompany.internal',
  baseUrl: '/',
  
  // Opciones de deployment
  organizationName: 'mycompany',
  projectName: 'eng-docs',
  
  // Theme config
  themeConfig: {
    navbar: {
      title: 'Engineering Docs',
      logo: {
        alt: 'Logo',
        src: 'img/logo.svg',
      },
      items: [
        {
          type: 'doc',
          docId: 'intro',
          position: 'left',
          label: 'Documentation',
        },
        {to: '/blog', label: 'Changelog', position: 'left'},
        {
          href: 'https://github.com/myorg/docs',
          label: 'GitHub',
          position: 'right',
        },
      ],
    },
    
    // Dark mode (ya viene incluido)
    colorMode: {
      defaultMode: 'dark',
      disableSwitch: false,
      respectPrefersColorScheme: true,
    },
    
    // Footer
    footer: {
      style: 'dark',
      links: [
        {
          title: 'Docs',
          items: [
            {label: 'Getting Started', to: '/docs/intro'},
            {label: 'Architecture', to: '/docs/architecture'},
          ],
        },
        {
          title: 'Community',
          items: [
            {label: 'Slack', href: 'https://myteam.slack.com'},
            {label: 'GitHub', href: 'https://github.com/myorg'},
          ],
        },
      ],
      copyright: `Copyright © ${new Date().getFullYear()} Engineering Team`,
    },
  },
  
  presets: [
    [
      'classic',
      {
        docs: {
          sidebarPath: require.resolve('./sidebars.js'),
          editUrl: 'https://github.com/myorg/docs/edit/main/',
        },
        blog: {
          showReadingTime: true,
          editUrl: 'https://github.com/myorg/docs/edit/main/',
        },
        theme: {
          customCss: require.resolve('./src/css/custom.css'),
        },
      },
    ],
  ],
};

Paso 3: Desarrollo Local

# Iniciar servidor de desarrollo
npm run start

# Abre automáticamente: http://localhost:3000
# Hot reload: Guarda cambios y se reflejan automáticamente

📁 Estructura de Documentación

Organización Sugerida

docs/
├── getting-started/
│   ├── intro.md
│   ├── installation.md
│   └── quickstart.md
├── architecture/
│   ├── overview.md
│   ├── services.md
│   └── data-flow.md
├── apis/
│   ├── rest-api.md
│   ├── authentication.md
│   └── examples.md
├── deployment/
│   ├── docker.md
│   ├── kubernetes.md
│   └── ci-cd.md
├── runbooks/
│   ├── incident-response.md
│   ├── maintenance.md
│   └── troubleshooting.md
└── best-practices/
    ├── coding-standards.md
    ├── security.md
    └── testing.md
💡 Tip: Estructura tu documentación por "journey" del usuario, no por componentes técnicos. Piensa: ¿Qué necesita saber alguien nuevo en el equipo primero?

🐛 Problemas Comunes y Soluciones

1. Build Falla con "Out of Memory"

Síntoma: npm run build termina con error FATAL ERROR: Reached heap limit

Causa: Documentación muy grande (100+ páginas) excede memoria de Node.js por defecto.

Solución:

# Aumentar memoria de Node.js
NODE_OPTIONS="--max-old-space-size=4096" npm run build

# O agregar a package.json:
{
  "scripts": {
    "build": "NODE_OPTIONS='--max-old-space-size=4096' docusaurus build"
  }
}

2. Search No Funciona (Algolia)

Síntoma: Barra de búsqueda no encuentra nada.

Causa: Algolia DocSearch requiere aplicar y ser aprobado (puede tardar semanas).

Solución: Usar búsqueda local mientras esperas:

# Instalar plugin de búsqueda local
npm install @easyops-cn/docusaurus-search-local

# docusaurus.config.js
themes: [
  [
    '@easyops-cn/docusaurus-search-local',
    {
      hashed: true,
      language: ['en', 'es'],
    },
  ],
],

3. Imágenes Rotas Después del Build

Síntoma: Imágenes se ven en dev pero no en producción.

Causa: Rutas relativas incorrectas o imágenes no en /static.

Solución:

# Imágenes en /static/img/
static/
└── img/
    └── architecture.png

# En Markdown, usar:
![Architecture](/img/architecture.png)

# NO usar:
![Architecture](../img/architecture.png)  # ❌ Relativo falla

4. Deploy en Servidor Interno Falla (CORS/404)

Síntoma: Sitio deployado da 404 en rutas o assets no cargan.

Causa: baseUrl incorrecto en config.

Solución:

// Si deploy en https://docs.company.com/
baseUrl: '/',

// Si deploy en https://company.com/docs/
baseUrl: '/docs/',

// Reconstruir después de cambiar baseUrl
npm run build

5. Nginx da 403 Forbidden en RHEL/CentOS (SELinux) ⚠️ CRÍTICO

Síntoma: Después de copiar archivos a /var/www/docs, Nginx devuelve 403 Forbidden.

Causa: SELinux (Security-Enhanced Linux) bloquea el acceso de Nginx a archivos con contexto de seguridad incorrecto. Común en RHEL, CentOS, Rocky Linux, AlmaLinux.

Diagnóstico:

# Verificar si SELinux está activo
getenforce
# Output: Enforcing (bloqueará acceso)

# Ver logs de SELinux
sudo ausearch -m avc -ts recent | grep nginx

# Verificar contexto actual de los archivos
ls -Z /var/www/docs/
# Output incorrecta: unconfined_u:object_r:user_home_t:s0

Solución:

# Opción 1: Corregir contexto de archivos (RECOMENDADO)
sudo chcon -R -t httpd_sys_content_t /var/www/docs/

# Opción 2: Usar restorecon (si tienes políticas configuradas)
sudo restorecon -Rv /var/www/docs/

# Opción 3: Permitir Nginx leer home directories (solo si es necesario)
sudo setsebool -P httpd_read_user_content 1

# Verificar que el contexto está correcto
ls -Z /var/www/docs/
# Output correcto: unconfined_u:object_r:httpd_sys_content_t:s0
⚠️ Importante para SysAdmins RHEL:
  • NUNCA uses setenforce 0 (deshabilitar SELinux) en producción
  • Siempre corrige los contextos de seguridad correctamente
  • En scripts de deployment, agrega chcon después del scp
  • Si usas rsync, considera rsync -avz --context para preservar contexto

🖥️ Infraestructura y Deployment

Opción 1: GitHub Pages (Más Simple)

# docusaurus.config.js
organizationName: 'myorg',
projectName: 'docs',
deploymentBranch: 'gh-pages',

# Deploy con un comando
GIT_USER= npm run deploy

# Disponible en: https://myorg.github.io/docs/

Opción 2: Docker + Nginx (Para Empresas)

# Dockerfile
FROM node:20-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Nginx para servir estáticos
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
# docker-compose.yml
version: '3.8'
services:
  docs:
    build: .
    ports:
      - "8080:80"
    restart: unless-stopped
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro

Opción 3: Vercel/Netlify (Deploy Automático)

# Conectar repo GitHub a Vercel:
# 1. Import project from GitHub
# 2. Vercel detecta Docusaurus automáticamente
# 3. Deploy automático en cada push a main
# 
# URL: https://my-docs.vercel.app

Opción 4: Home Lab (Self-Hosted)

Para tener tu propia documentación en home lab:

# 1. Build estático
npm run build
# Output: build/ directory

# 2. Copiar a tu servidor
scp -r build/* user@your-server:/var/www/docs/

# 3. Nginx config
server {
    listen 80;
    server_name docs.yourdomain.com;
    root /var/www/docs;
    index index.html;
    
    location / {
        try_files $uri $uri/ $uri.html /index.html;
    }
}

💡 Caso de Uso Empresarial (Generalizado)

El Problema Que Resolvimos

Un equipo de ingeniería con:

  • 15+ microservicios sin documentación unificada
  • Confluence obsoleto (última actualización: 2 años atrás)
  • README.md dispersos en múltiples repos
  • Onboarding de nuevos devs: 2-3 semanas
  • Preguntas repetitivas en Slack

La Solución: Sistema de Documentación Centralizado

Implementamos Docusaurus con:

  • Arquitectura: Diagramas de componentes, flujo de datos
  • APIs: Documentación de endpoints con ejemplos
  • Runbooks: Procedimientos de incidentes, deploys
  • ADRs: Architectural Decision Records (por qué tomamos cada decisión)
  • Onboarding: Guía step-by-step para nuevos developers

Resultados (Después de 3 Meses)

Métricas:
• Onboarding time: 2-3 semanas → 3-5 días (80% reducción)
• Preguntas repetitivas en Slack: -60%
• Tiempo buscando información: -70%
• Incidentes por falta de documentación: -50%
• Satisfacción del equipo: +85%

🏠 Caso de Uso: Home Lab

¿Por Qué Docusaurus en un Home Lab?

Documentar tu home lab con Docusaurus es útil si:

  • Tienes múltiples servicios y te olvidas cómo configuraste cada uno
  • Experimentas con tecnologías y quieres documentar aprendizajes
  • Quieres compartir tus proyectos públicamente (como yo con este blog)
  • Estás preparándote para certificaciones (documentar lo que aprendes)

Estructura para Home Lab

docs/
├── services/
│   ├── n8n.md              # Setup de n8n
│   ├── nginx.md            # Configuración Nginx
│   ├── postgres.md         # PostgreSQL configs
│   └── cloudflare.md       # Cloudflare Tunnel
├── infrastructure/
│   ├── network.md          # Configuración de red
│   ├── hardware.md         # Specs del servidor
│   └── security.md         # Firewall, fail2ban
├── procedures/
│   ├── backup.md           # Procedimientos de backup
│   ├── restore.md          # Cómo restaurar
│   └── updates.md          # Actualizar servicios
├── troubleshooting/
│   ├── docker.md           # Problemas comunes Docker
│   ├── network.md          # Issues de red
│   └── performance.md      # Debugging performance
└── learning/
    ├── certifications.md   # Progreso de certificaciones
    ├── projects.md         # Ideas de proyectos
    └── resources.md        # Links útiles, cursos

Ejemplo: Documentar Tu Servidor

---
id: server-specs
title: Server Hardware Specifications
sidebar_position: 1
---

# Server Hardware

## Overview

Home lab server built from Lenovo G480 (2013).

## Specifications

| Component | Details |
|-----------|---------|
| **CPU** | Intel Celeron B970 (2 cores, 2.3 GHz) |
| **RAM** | 4 GB DDR3 |
| **Storage** | 512 GB SSD |
| **Network** | Ethernet 1 Gbps |
| **Power** | 12-18W idle, 30-40W load |

## Services Running

- Docker (n8n, PostgreSQL, Nginx)
- Cloudflare Tunnel
- System monitor (sysmon_web.py)

## Known Issues

### Lid Close Suspension

**Problem:** Closing laptop lid suspends the system.

**Solution:**
\`\`\`bash
sudo nano /etc/systemd/logind.conf
# Set:
HandleLidSwitch=ignore
\`\`\`

### Temperature Management

- Summer: Keep lid open (better ventilation)
- Winter: Lid can be closed (lower temps)
- Monitor: https://mytechzone.dev/status.html

🚀 Features Avanzadas

1. Componentes React Personalizados

// src/components/APIEndpoint.js
import React from 'react';

export default function APIEndpoint({method, path, description}) {
  return (
    
{method} {path}

{description}

); } // Uso en MDX: import APIEndpoint from '@site/src/components/APIEndpoint';

2. Versionado de Documentación

# Crear nueva versión (cuando lanzas v2.0 de tu API)
npm run docusaurus docs:version 2.0

# Estructura resultante:
docs/                    # Current (v2.1 en desarrollo)
versioned_docs/
├── version-2.0/        # Docs de v2.0
└── version-1.0/        # Docs de v1.0

# Dropdown automático en UI para cambiar versiones

3. Search con Algolia (Gratis para Open Source)

# Aplicar en: https://docsearch.algolia.com/apply/

# Después de aprobación, agregar a config:
themeConfig: {
  algolia: {
    apiKey: 'YOUR_API_KEY',
    indexName: 'my-docs',
    appId: 'YOUR_APP_ID',
  },
}

📊 Infraestructura Necesaria

Mínimo Viable (Para Empezar)

Componente Requerimiento
Servidor 1 vCPU, 512 MB RAM (sitio estático)
Storage ~50-100 MB (build output)
Node.js v18+ (solo para build, no en runtime)
Web Server Nginx, Apache, o cualquiera
SSL Let's Encrypt (gratis)

Setup Empresarial (Recomendado)

Componente Requerimiento
CI/CD GitHub Actions, GitLab CI
Build Server 2 vCPU, 4 GB RAM (para builds)
CDN CloudFront, Cloudflare (opcional)
Authentication OAuth, SSO (si es interno)
Search Algolia DocSearch (gratis) o local

🔄 CI/CD Pipeline

GitHub Actions (Auto-Deploy)

# .github/workflows/deploy.yml
name: Deploy Docs

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '20'
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Build
        run: npm run build
      
      - name: Deploy to Server
        run: |
          rsync -avz --delete build/ ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }}:/var/www/docs/
        env:
          SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
⚠️ Seguridad: Para documentación interna de empresa, asegúrate de:
  • Deploy en red interna (VPN required)
  • Autenticación con SSO/OAuth (ver implementación abajo ⬇️)
  • NO hacer el repo público en GitHub si contiene info sensible
  • Usar secrets de GitHub para credenciales

🔐 Autenticación Empresarial (Critical)

⚠️ IMPORTANTE: Docusaurus por sí solo NO tiene autenticación built-in. Para documentación interna de empresa, DEBES agregar una capa de autenticación usando un Reverse Proxy (Nginx/Apache) con OIDC, LDAP, o OAuth2.

Opción 1: Nginx + OpenID Connect (OIDC)

Integración con proveedores corporativos (Okta, Azure AD, Keycloak):

# 1. Instalar módulo de autenticación
# Para Nginx Plus (comercial):
sudo apt-get install nginx-plus-module-njs nginx-plus-module-auth-spnego

# Para Nginx Open Source, usar oauth2-proxy
docker run -d \
  --name oauth2-proxy \
  -p 4180:4180 \
  quay.io/oauth2-proxy/oauth2-proxy:latest \
  --provider=oidc \
  --client-id="YOUR_CLIENT_ID" \
  --client-secret="YOUR_CLIENT_SECRET" \
  --oidc-issuer-url="https://your-idp.company.com" \
  --cookie-secret="RANDOM_SECRET_32_CHARS" \
  --email-domain="company.com" \
  --upstream="http://localhost:8080" \
  --http-address="0.0.0.0:4180"
# 2. Configurar Nginx como reverse proxy
server {
    listen 443 ssl;
    server_name docs.company.internal;
    
    ssl_certificate /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;
    
    # Proxy a oauth2-proxy
    location /oauth2/ {
        proxy_pass http://127.0.0.1:4180;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
    }
    
    # Verificar autenticación antes de servir Docusaurus
    location / {
        auth_request /oauth2/auth;
        error_page 401 = /oauth2/sign_in;
        
        # Headers de usuario autenticado
        auth_request_set $user $upstream_http_x_auth_request_user;
        auth_request_set $email $upstream_http_x_auth_request_email;
        
        proxy_set_header X-User $user;
        proxy_set_header X-Email $email;
        
        # Proxy a Docusaurus
        root /var/www/docs;
        try_files $uri $uri/ $uri.html /index.html;
    }
}

Opción 2: Apache + LDAP

Para empresas con Active Directory o OpenLDAP:

# httpd.conf o site config

    ServerName docs.company.internal
    DocumentRoot /var/www/docs
    
    SSLEngine on
    SSLCertificateFile /etc/httpd/ssl/cert.pem
    SSLCertificateKeyFile /etc/httpd/ssl/key.pem
    
    
        AuthType Basic
        AuthName "Company Documentation"
        AuthBasicProvider ldap
        
        # LDAP Configuration
        AuthLDAPURL "ldap://ldap.company.com:389/ou=users,dc=company,dc=com?uid?sub?(objectClass=*)"
        AuthLDAPBindDN "cn=readonly,dc=company,dc=com"
        AuthLDAPBindPassword "BIND_PASSWORD"
        
        # Requerir autenticación
        Require valid-user
        
        # O restringir a grupo específico
        Require ldap-group cn=engineering,ou=groups,dc=company,dc=com
    
    
    # Rewrite para SPA
    
        RewriteEngine On
        RewriteBase /
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /index.html [L]
    

Opción 3: Cloudflare Access (Más Simple)

Si tu docs está públicamente accesible pero quieres restringir acceso:

# 1. En Cloudflare Dashboard:
#    - Ir a Zero Trust → Access → Applications
#    - Add application → Self-hosted
#    - Domain: docs.company.com
#    - Policy: Allow emails ending in @company.com

# 2. En tu servidor Docusaurus, NO necesitas cambios
#    Cloudflare intercepta ANTES de llegar al origin

# 3. (Opcional) Verificar headers de Cloudflare Access en Nginx
server {
    location / {
        # Cloudflare Access agrega header Cf-Access-Authenticated-User-Email
        if ($http_cf_access_authenticated_user_email = "") {
            return 403;
        }
        
        root /var/www/docs;
        try_files $uri $uri/ $uri.html /index.html;
    }
}

Comparación de Métodos de Autenticación

Método Complejidad Costo Mejor Para
Nginx + OIDC 🟡 Media 💰 Gratis (oauth2-proxy) Empresas con Okta/Azure AD
Apache + LDAP 🟡 Media 💰 Gratis Empresas con Active Directory
Cloudflare Access 🟢 Baja 💰💰 $3-7/usuario/mes Startups, equipos pequeños
VPN Only 🟢 Muy baja 💰 Gratis Docs muy sensibles, red interna
Basic Auth 🟢 Muy baja 💰 Gratis ❌ NO recomendado (passwords compartidos)
💡 Recomendación: Para empresas medianas/grandes, usa Nginx + OIDC con tu proveedor de identidad corporativo (Okta, Azure AD). Para startups o equipos pequeños, Cloudflare Access es la opción más simple y económica.

💡 Best Practices

1. Docs-as-Code

  • ✅ Documentación vive en Git (versionado, historial)
  • ✅ Pull requests para cambios (code review de docs)
  • ✅ CI/CD para deploy automático
  • ✅ Linting de Markdown (vale-cli, markdownlint)

2. Organización del Contenido

  • ✅ User journey primero (Getting Started → Advanced)
  • ✅ Una página = Un concepto
  • ✅ Evitar páginas gigantes (split en subsecciones)
  • ✅ Links internos frecuentes

3. Mantenimiento Sostenible

  • ✅ Asignar "doc owner" por sección
  • ✅ Review trimestral (marcar páginas obsoletas)
  • ✅ Incentivar contribuciones (parte del onboarding)
  • ✅ Metrics: qué páginas se leen más (Analytics)

4. Seguridad y Compliance

  • ✅ NO documentar passwords, API keys, secrets
  • ✅ Generalizar IPs, nombres de servidores productivos
  • ✅ Review de Legal/Security antes de hacer público
  • ✅ Separar docs públicas vs internas

📈 Comparación: Antes vs Después

Aspecto Antes (Confluence) Después (Docusaurus)
Búsqueda 🟡 Lenta, resultados malos 🟢 Instant, relevante
Actualización 🔴 Manual, nadie lo hace 🟢 PR automatizados, CI/CD
Versionado 🔴 No hay, confusión 🟢 Múltiples versiones, dropdown
Performance 🟡 Lenta (server-side) 🟢 Instant (estático + CDN)
Costo 🔴 $10-50/user/mes 🟢 $0 (self-hosted) o $10/mes (Vercel)
Code snippets 🟡 Formateado malo 🟢 Syntax highlighting perfecto
Mantenibilidad 🔴 Difícil, nadie contribuye 🟢 Fácil (Markdown), PRs naturales

🎯 Ideas para Diferentes Contextos

1. Documentación de APIs (Equipo Backend)

docs/
├── api-reference/
│   ├── authentication.md
│   ├── users-endpoint.md
│   └── orders-endpoint.md
├── guides/
│   ├── getting-started.md
│   └── best-practices.md
└── changelog.md

2. Runbooks de SRE (Equipo Ops)

docs/
├── incidents/
│   ├── database-down.md
│   ├── high-latency.md
│   └── disk-full.md
├── maintenance/
│   ├── db-migration.md
│   └── scaling-nodes.md
└── monitoring/
    ├── alerts-guide.md
    └── dashboards.md

3. Knowledge Base Personal (Home Lab)

docs/
├── server-setup/
│   ├── debian-installation.md
│   └── docker-compose.md
├── services/
│   ├── n8n-workflows.md
│   └── monitoring.md
├── troubleshooting/
│   └── common-issues.md
└── learning/
    ├── aws-notes.md
    └── kubernetes-study.md

4. Portfolio + Tutoriales (Blog Técnico)

Exactamente como mi blog actual, pero con Docusaurus:

  • Mejor search
  • Versionado de posts
  • Categorías automáticas
  • Tags con páginas dedicadas

💰 Costos de Implementación

Home Lab (Self-Hosted)

Setup inicial:     4-6 horas
Costo hardware:    $0 (servidor ya existe)
Costo hosting:     $0 (self-hosted)
Costo dominio:     $10-15/año (opcional)
Costo SSL:         $0 (Let's Encrypt)
Mantenimiento:     1 hora/mes

Total año 1: ~$15 (solo dominio)

Empresarial (Hosted)

Setup inicial:     1-2 semanas (configuración, migración)
Developer time:    40-80 horas ($4,000-8,000 en salarios)
Hosting:           $20-50/mes (Vercel Pro, Netlify)
Algolia Search:    $0 (DocSearch gratuito para open source)
CI/CD:             $0 (GitHub Actions gratis para public repos)

Total año 1: ~$500-1,000 (hosting)
vs Confluence: ~$5,000-10,000/año (10-20 usuarios)
ROI: En contexto empresarial, Docusaurus se paga solo en el primer mes solo con el tiempo ahorrado en búsqueda de información.

🐛 Troubleshooting Avanzado

Problema: Hot Reload Muy Lento

Causa: Proyecto muy grande, Docusaurus recompila todo.

Solución: Fast refresh mode

# docusaurus.config.js
module.exports = {
  future: {
    experimental_faster: true,
  },
};

Problema: Build Toma 10+ Minutos

Causa: Muchas imágenes grandes sin optimizar.

Solución: Optimizar imágenes antes del build

# Instalar plugin
npm install @docusaurus/plugin-ideal-image

# Usar en docs:
import Image from '@theme/IdealImage';

Problema: Links Rotos Después de Refactor

Solución: Usar plugin de validación

# Instalar
npm install @docusaurus/plugin-client-redirects

# Configurar redirects
plugins: [
  [
    '@docusaurus/plugin-client-redirects',
    {
      redirects: [
        {
          from: '/old-path',
          to: '/new-path',
        },
      ],
    },
  ],
],

💡 Lecciones Aprendidas

  • Empieza simple: No necesitas todas las features desde día 1. README básico → Docusaurus básico → Features avanzadas gradualmente.
  • La migración es costosa: Copiar contenido de Confluence/Notion a Markdown toma tiempo. Considera hacerlo gradualmente.
  • Documentación es iterativa: Mejor tener algo básico y funcional que esperar a que sea "perfecto".
  • Ownership es crítico: Asigna responsables por sección o se vuelve obsoleta.
  • Search es fundamental: Sin búsqueda buena, nadie usa la documentación.
  • Docs-as-code funciona: Devs contribuyen más cuando es Markdown en Git que una wiki web.
  • Performance importa: Build optimizado (< 2 min) o los devs no contribuyen.

🚀 Migración desde Otras Plataformas

Desde Confluence

# Usar herramienta de conversión
npm install -g confluence-to-markdown

confluence-to-markdown \
  --space "MYSPACE" \
  --user "[email protected]" \
  --token "YOUR_TOKEN" \
  --output ./docs

# Review manual necesario (tablas, macros custom)

Desde Notion

# Export desde Notion (Markdown & CSV)
# Settings → Export All → Markdown

# Convertir a formato Docusaurus
# Revisar frontmatter y links manualmente

Desde README.md Dispersos

# Script para consolidar READMEs de múltiples repos
#!/bin/bash

for repo in repo1 repo2 repo3; do
    git clone https://github.com/myorg/$repo /tmp/$repo
    cp /tmp/$repo/README.md docs/services/$repo.md
done

✅ Resultado Final

Una plataforma de documentación que:

  • ✅ Es moderna y rápida (React, Static Site Generation)
  • ✅ Es mantenible (Markdown, Git workflow familiar)
  • ✅ Escala bien (de 10 páginas a 1000+)
  • ✅ Es económica ($0-50/mes vs $5000/año Confluence)
  • ✅ Tiene búsqueda excelente
  • ✅ Es accesible (dark mode, responsive)
  • ✅ Fomenta contribuciones (PRs como en código)
Mi experiencia: Implementar Docusaurus transformó la cultura de documentación del equipo. De "nadie documenta" a "PRs siempre incluyen docs update".

El secreto: Hacer que documentar sea TAN fácil como hacer un commit de código.

🎓 Casos de Uso Más Allá de Documentación

  • Blog técnico: Como este que estás leyendo (aunque yo uso HTML puro)
  • Changelog público: Release notes de tu software
  • Knowledge base: FAQ, troubleshooting guides
  • Tutorial site: Curso online, bootcamp interno
  • API docs: Con componentes interactivos (Swagger UI integrado)
  • Design system: Documentar componentes UI, guías de estilo

💭 Conclusión

Docusaurus es una solución moderna y pragmática para documentación técnica. No es perfecto (requiere conocimientos de Node.js/React), pero para equipos de ingeniería es una opción excelente que combina lo mejor de docs-as-code con una UI profesional.

Si tu equipo usa Git diariamente, implementar Docusaurus es natural. Si tu home lab tiene más de 5 servicios, Docusaurus te ayudará a no olvidar cómo configuraste todo.

Mi recomendación: Empieza pequeño. Un npx create-docusaurus, una carpeta con 5 archivos Markdown, y despliega a GitHub Pages. Después crece orgánicamente según necesites.