Making Of - Wiki de NeoDigital
Esta guía documenta todo el proceso desde la creación del proyecto Astro Starlight hasta su despliegue en un servidor de Digital Ocean utilizando Docker, Nginx y SSL, con integración continua a través de GitHub Actions.
1. Creación del proyecto Astro Starlight
Instalación y configuración inicial
Para crear un nuevo proyecto Astro Starlight:
# Crear nuevo proyecto Astro con Starlightnpm create astro@latest -- --template starlight# Seguir las instrucciones del asistente# Nombre del proyecto: neodigital-wiki
# Instalar dependencias adicionalescd neodigital-wikinpm install @astrojs/sitemap sharpConfiguración del proyecto
Editar el archivo astro.config.mjs para configurar Starlight:
import { defineConfig } from 'astro/config';import starlight from '@astrojs/starlight';import sitemap from '@astrojs/sitemap';
export default defineConfig({ site: 'https://wiki.neodigital.mx', build: { format: 'directory', }, integrations: [ starlight({ title: 'NeoDigital Wiki', defaultLocale: 'root', locales: { root: { label: 'Español', lang: 'es-ES', }, }, social: { github: 'https://github.com/NeoDigital-MX', }, sidebar: [ { label: 'Inicio', items: [ { label: 'Portada', link: '/' }, { label: 'Introducción', link: '/introduction' }, ], }, ], customCss: ['./src/styles/custom.css'], }), sitemap(), ],});Estructura de directorios de Astro Starlight
Astro Starlight sigue una estructura de directorios específica que facilita la organización del contenido. La más importante es la carpeta src/content/docs/, donde se alojan todas las páginas de documentación:
neodigital-wiki/├── public/ # Archivos estáticos (imágenes, favicon, etc.)├── src/│ ├── assets/ # Recursos como imágenes que serán procesados por Astro│ │ └── ... # Otros recursos│ ├── components/ # Componentes de Astro/React/Vue/etc.│ ├── content/│ │ ├── docs/ # Aquí van todos los documentos de Markdown (.md o .mdx)│ │ │ ├── index.md # Página principal (ruta: /)│ │ │ ├── introduction.md # Página de introducción (ruta: /introduction)│ │ │ ├── making-of.md # Este mismo documento (ruta: /making-of)│ │ │ └── ... # Otros documentos│ │ └── config.ts # Configuración de contenido (opcional)│ └── styles/ # Archivos CSS para personalización│ └── custom.css # Estilos personalizados para el sitio├── astro.config.mjs # Configuración principal de Astro├── package.json # Dependencias y scripts└── tsconfig.json # Configuración de TypeScriptCada documento Markdown en src/content/docs/ se convierte automáticamente en una página del wiki, utilizando la siguiente estructura:
---title: Título de la páginadescription: Descripción de la página para SEO y metadatos---
# Contenido principal
El contenido de la página escrito en Markdown...Para crear nuevas secciones en el wiki, simplemente:
- Añade un nuevo archivo
.mden la carpetasrc/content/docs/ - Configura sus metadatos con el frontmatter (sección entre
---) - Añade el documento a la barra lateral en
astro.config.mjs
Además, puedes crear subdirectorios para organizar mejor el contenido, por ejemplo:
src/content/docs/├── guias/ # Subdirectorio para guías│ ├── instalacion.md│ └── configuracion.md└── referencia/ # Subdirectorio para documentación de referencia ├── api.md └── comandos.mdEstos subdirectorios se reflejarán en las URLs, por ejemplo, /guias/instalacion.
2. Dockerización del proyecto
Creación del Dockerfile
Creamos un Dockerfile para la aplicación:
# Etapa de construcciónFROM node:20-alpine AS build
WORKDIR /app
# Copiar package.json y package-lock.jsonCOPY package*.json ./
# Instalar dependenciasRUN npm ci
# Copiar el resto de archivos del proyectoCOPY . .
# Construir la aplicaciónRUN npm run build
# Etapa de producciónFROM nginx:alpine AS production
# Copiar archivos estáticos compiladosCOPY --from=build /app/dist /usr/share/nginx/html
# Configuración básica de nginxCOPY --from=build /app/nginx.conf /etc/nginx/conf.d/default.conf
# Exponer el puertoEXPOSE 80
# Comando de inicioCMD ["nginx", "-g", "daemon off;"]Configuración de Nginx para Docker
Creamos el archivo nginx.conf en la raíz del proyecto:
server { listen 80; server_name localhost;
root /usr/share/nginx/html; index index.html;
location / { try_files $uri $uri/ =404; }
# Configuración para archivos estáticos location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires max; add_header Cache-Control "public, max-age=31536000"; }}Archivo .dockerignore
Creamos un archivo .dockerignore para optimizar el proceso de construcción:
node_modules.git.github.vscode.astrodist*.md.env*!.env.example.dockerignoreDockerfiledocker-compose.yml3. Configuración del servidor en Digital Ocean
Creación y configuración inicial del Droplet
- Crear un Droplet en Digital Ocean con Ubuntu 22.04 y Docker preinstalado
- Conectarse al servidor mediante SSH
# Actualizar el sistemasudo apt update && sudo apt upgrade -y
# Generar clave SSH para GitHubssh-keygen -t ed25519 -C "hola@neodigital.mx"eval "$(ssh-agent -s)"ssh-add ~/.ssh/id_ed25519
# Mostrar la clave pública para agregarla a GitHubcat ~/.ssh/id_ed25519.pub
# Configurar Gitgit config --global user.name "NeoDigital-Droplet1"git config --global user.email "hola@neodigital.mx"
# Verificar conexión con GitHubssh -T git@github.comEstructura de directorios
# Crear estructura de directorios para los repositoriosmkdir -p GitHub/repositoriesConfiguración de acceso rápido a directorios
Editar el archivo .bashrc para añadir un atajo:
nano ~/.bashrcAñadir al final:
# Atajo para acceder rápidamente al directorio de repositoriosrepos() { cd ~/GitHub/repositories/$1}Aplicar los cambios:
source ~/.bashrc4. Despliegue de la aplicación
Clonar el repositorio
# Ir al directorio de repositoriosrepos
# Clonar el repositoriogit clone git@github.com:NeoDigital-MX/neodigital-wiki.gitcd neodigital-wiki/
# Cambiar a la rama DOCKERgit checkout DOCKERInstalar dependencias del servidor
# Instalar Nginx y Certbotapt install -y nginx certbot python3-certbot-nginxConfiguración de Nginx
Modificar la configuración principal de Nginx:
# Crear un respaldo de la configuración originalcp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
# Editar la configuraciónnano /etc/nginx/nginx.confConfiguración optimizada:
user www-data;worker_processes auto;pid /run/nginx.pid;include /etc/nginx/modules-enabled/*.conf;
events { worker_connections 1024; multi_accept on;}
http { ## # Configuraciones básicas ## sendfile on; tcp_nopush on; tcp_nodelay on; types_hash_max_size 2048; server_tokens off; client_max_body_size 64M;
include /etc/nginx/mime.types; default_type application/octet-stream;
## # Configuraciones SSL ## ssl_protocols TLSv1.2 TLSv1.3; # Eliminando protocolos inseguros ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m;
## # Configuraciones de Logging ## access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log;
## # Configuraciones Gzip ## gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
## # Configuraciones de Virtual Host ## include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*;}Configuración del sitio en Nginx
# Crear configuración para el sitionano /etc/nginx/sites-available/wiki.neodigital.mxContenido:
server { listen 80; server_name wiki.neodigital.mx;
location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; }}Activar el sitio:
ln -s /etc/nginx/sites-available/wiki.neodigital.mx /etc/nginx/sites-enabled/rm -f /etc/nginx/sites-enabled/default # Eliminar configuración predeterminadanginx -t # Verificar configuraciónsystemctl restart nginxConstrucción y ejecución del contenedor Docker
# Construir la imagen Dockerdocker build -t neodigital-wiki:latest .
# Ejecutar el contenedordocker run -d -p 3000:80 --name wiki --restart always neodigital-wiki:latest5. Configuración de SSL con Let’s Encrypt
Verificación de DNS
Comprobar que el dominio apunte correctamente al servidor:
nslookup wiki.neodigital.mxConfiguración de firewall
# Permitir tráfico HTTP y HTTPSufw allow 80/tcpufw allow 443/tcpObtención del certificado SSL
# Detener Nginx temporalmentesystemctl stop nginx
# Obtener el certificado en modo standalonecertbot certonly --standalone -d wiki.neodigital.mx
# Iniciar Nginx nuevamentesystemctl start nginxConfiguración de Nginx para HTTPS
nano /etc/nginx/sites-available/wiki.neodigital.mxConfiguración actualizada:
server { listen 80; server_name wiki.neodigital.mx; return 301 https://$host$request_uri;}
server { listen 443 ssl; server_name wiki.neodigital.mx;
ssl_certificate /etc/letsencrypt/live/wiki.neodigital.mx/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/wiki.neodigital.mx/privkey.pem;
# Configuración SSL optimizada ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m;
location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; }}Reiniciar Nginx:
nginx -tsystemctl restart nginx6. Configuración de Despliegue Continuo (CI/CD)
Script de despliegue
mkdir -p /root/scriptsnano /root/scripts/deploy.shContenido:
#!/bin/bash
cd ~/GitHub/repositories/neodigital-wikigit pull origin maindocker build -t neodigital-wiki:latest .docker stop wiki || truedocker rm wiki || truedocker run -d -p 3000:80 --name wiki --restart always neodigital-wiki:latestecho "Despliegue completado: $(date)" >> /var/log/deployments.logHacer el script ejecutable:
chmod +x /root/scripts/deploy.shConfiguración de clave SSH para GitHub Actions
ssh-keygen -t ed25519 -f ~/.ssh/github-actions-key -N ""cat ~/.ssh/github-actions-key.pub >> ~/.ssh/authorized_keyscat ~/.ssh/github-actions-keyConfiguración de GitHub Actions
Crear o modificar el archivo .github/workflows/deploy.yml en el repositorio:
name: Deploy to Digital Ocean Droplet
on: push: branches: - main pull_request: types: - closed branches: - main
jobs: build_and_deploy: if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.merged == true) runs-on: ubuntu-latest
steps: - name: Checkout repository uses: actions/checkout@v4
- name: Set up Node.js uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm'
- name: Install dependencies run: npm ci
- name: Lint run: npm run lint
- name: Build application run: npm run build
- name: Deploy to server via SSH uses: appleboy/ssh-action@master with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USERNAME }} key: ${{ secrets.SSH_PRIVATE_KEY }} script: | cd ~/GitHub/repositories/neodigital-wiki git pull origin main docker build -t neodigital-wiki:latest . docker stop wiki || true docker rm wiki || true docker run -d -p 3000:80 --name wiki --restart always neodigital-wiki:latest echo "Despliegue completado: $(date)" >> /var/log/deployments.logConfiguración de secretos en GitHub
En el repositorio de GitHub:
- Ir a Settings > Secrets and variables > Actions
- Añadir los siguientes secretos:
SSH_HOST: IP del servidor (ej: 164.92.117.29)SSH_USERNAME: usuario (root)SSH_PRIVATE_KEY: clave SSH privada generada
7. Mantenimiento y monitoreo
Verificación de logs
# Logs de Dockerdocker logs wiki
# Logs de desplieguetail -f /var/log/deployments.log
# Logs de Nginxtail -f /var/log/nginx/access.logtail -f /var/log/nginx/error.logComandos útiles para solución de problemas
# Verificar estado de Nginxsystemctl status nginx
# Verificar puertos abiertosnetstat -tuln | grep -E '80|443'
# Reiniciar contenedordocker restart wiki
# Verificar accesibilidad del contenedordocker exec -it wiki curl -I http://localhost8. Flujo de trabajo para crear y publicar contenido
Proceso para añadir nuevas páginas al wiki
Para crear nuevos contenidos en el wiki:
-
Crea un nuevo archivo Markdown en la carpeta
src/content/docs/:Ventana de terminal cd ~/GitHub/repositories/neodigital-wikinano src/content/docs/nuevo-documento.md -
Estructura el documento con el formato correcto:
---title: Título del nuevo documentodescription: Descripción breve para SEO y metadatos---# Título principalContenido del documento en formato Markdown... -
Actualiza la barra lateral en
astro.config.mjspara incluir el nuevo documento:sidebar: [// otras secciones...{label: 'Mi Nueva Sección',items: [{ label: 'Nuevo Documento', link: '/nuevo-documento' }]}] -
Comprueba localmente los cambios (opcional):
Ventana de terminal npm run dev -
Envía tus cambios a revisión:
Ventana de terminal # Crea una rama para tus cambios o usa la rama devgit checkout dev# Añade y haz commit de tus cambiosgit add .git commit -m "Añadir nuevo documento: Nuevo Documento"# Envía tus cambios a la rama devgit push origin dev# Crea un Merge Request desde dev a main# Este paso se realiza en la interfaz de GitHub:# 1. Ve a: https://github.com/NeoDigital-MX/neodigital-wiki# 2. Selecciona "Pull requests" > "New pull request"# 3. Selecciona base:main <- compare:dev# 4. Asigna a Gerardo Alpuche (COO) como revisor -
Espera aprobación: El COO (Gerardo Alpuche) revisará el merge request y lo aprobará si cumple con los criterios de calidad.
-
Una vez aprobado y fusionado, el sistema de CI/CD se encargará automáticamente de desplegar los cambios al servidor.
Con esto, tendrás un sistema completo para desplegar, mantener y actualizar automáticamente tu Wiki basado en Astro Starlight.