Saltearse al contenido

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:

Ventana de terminal
# Crear nuevo proyecto Astro con Starlight
npm create astro@latest -- --template starlight
# Seguir las instrucciones del asistente
# Nombre del proyecto: neodigital-wiki
# Instalar dependencias adicionales
cd neodigital-wiki
npm install @astrojs/sitemap sharp

Configuración del proyecto

Editar el archivo astro.config.mjs para configurar Starlight:

astro.config.mjs
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 TypeScript

Cada 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ágina
description: 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:

  1. Añade un nuevo archivo .md en la carpeta src/content/docs/
  2. Configura sus metadatos con el frontmatter (sección entre ---)
  3. 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.md

Estos 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ón
FROM node:20-alpine AS build
WORKDIR /app
# Copiar package.json y package-lock.json
COPY package*.json ./
# Instalar dependencias
RUN npm ci
# Copiar el resto de archivos del proyecto
COPY . .
# Construir la aplicación
RUN npm run build
# Etapa de producción
FROM nginx:alpine AS production
# Copiar archivos estáticos compilados
COPY --from=build /app/dist /usr/share/nginx/html
# Configuración básica de nginx
COPY --from=build /app/nginx.conf /etc/nginx/conf.d/default.conf
# Exponer el puerto
EXPOSE 80
# Comando de inicio
CMD ["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
.astro
dist
*.md
.env*
!.env.example
.dockerignore
Dockerfile
docker-compose.yml

3. Configuración del servidor en Digital Ocean

Creación y configuración inicial del Droplet

  1. Crear un Droplet en Digital Ocean con Ubuntu 22.04 y Docker preinstalado
  2. Conectarse al servidor mediante SSH
Ventana de terminal
# Actualizar el sistema
sudo apt update && sudo apt upgrade -y
# Generar clave SSH para GitHub
ssh-keygen -t ed25519 -C "hola@neodigital.mx"
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# Mostrar la clave pública para agregarla a GitHub
cat ~/.ssh/id_ed25519.pub
# Configurar Git
git config --global user.name "NeoDigital-Droplet1"
git config --global user.email "hola@neodigital.mx"
# Verificar conexión con GitHub
ssh -T git@github.com

Estructura de directorios

Ventana de terminal
# Crear estructura de directorios para los repositorios
mkdir -p GitHub/repositories

Configuración de acceso rápido a directorios

Editar el archivo .bashrc para añadir un atajo:

Ventana de terminal
nano ~/.bashrc

Añadir al final:

Ventana de terminal
# Atajo para acceder rápidamente al directorio de repositorios
repos() {
cd ~/GitHub/repositories/$1
}

Aplicar los cambios:

Ventana de terminal
source ~/.bashrc

4. Despliegue de la aplicación

Clonar el repositorio

Ventana de terminal
# Ir al directorio de repositorios
repos
# Clonar el repositorio
git clone git@github.com:NeoDigital-MX/neodigital-wiki.git
cd neodigital-wiki/
# Cambiar a la rama DOCKER
git checkout DOCKER

Instalar dependencias del servidor

Ventana de terminal
# Instalar Nginx y Certbot
apt install -y nginx certbot python3-certbot-nginx

Configuración de Nginx

Modificar la configuración principal de Nginx:

Ventana de terminal
# Crear un respaldo de la configuración original
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
# Editar la configuración
nano /etc/nginx/nginx.conf

Configuració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

Ventana de terminal
# Crear configuración para el sitio
nano /etc/nginx/sites-available/wiki.neodigital.mx

Contenido:

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:

Ventana de terminal
ln -s /etc/nginx/sites-available/wiki.neodigital.mx /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default # Eliminar configuración predeterminada
nginx -t # Verificar configuración
systemctl restart nginx

Construcción y ejecución del contenedor Docker

Ventana de terminal
# Construir la imagen Docker
docker build -t neodigital-wiki:latest .
# Ejecutar el contenedor
docker run -d -p 3000:80 --name wiki --restart always neodigital-wiki:latest

5. Configuración de SSL con Let’s Encrypt

Verificación de DNS

Comprobar que el dominio apunte correctamente al servidor:

Ventana de terminal
nslookup wiki.neodigital.mx

Configuración de firewall

Ventana de terminal
# Permitir tráfico HTTP y HTTPS
ufw allow 80/tcp
ufw allow 443/tcp

Obtención del certificado SSL

Ventana de terminal
# Detener Nginx temporalmente
systemctl stop nginx
# Obtener el certificado en modo standalone
certbot certonly --standalone -d wiki.neodigital.mx
# Iniciar Nginx nuevamente
systemctl start nginx

Configuración de Nginx para HTTPS

Ventana de terminal
nano /etc/nginx/sites-available/wiki.neodigital.mx

Configuració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:

Ventana de terminal
nginx -t
systemctl restart nginx

6. Configuración de Despliegue Continuo (CI/CD)

Script de despliegue

Ventana de terminal
mkdir -p /root/scripts
nano /root/scripts/deploy.sh

Contenido:

#!/bin/bash
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.log

Hacer el script ejecutable:

Ventana de terminal
chmod +x /root/scripts/deploy.sh

Configuración de clave SSH para GitHub Actions

Ventana de terminal
ssh-keygen -t ed25519 -f ~/.ssh/github-actions-key -N ""
cat ~/.ssh/github-actions-key.pub >> ~/.ssh/authorized_keys
cat ~/.ssh/github-actions-key

Configuració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.log

Configuración de secretos en GitHub

En el repositorio de GitHub:

  1. Ir a Settings > Secrets and variables > Actions
  2. 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

Ventana de terminal
# Logs de Docker
docker logs wiki
# Logs de despliegue
tail -f /var/log/deployments.log
# Logs de Nginx
tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log

Comandos útiles para solución de problemas

Ventana de terminal
# Verificar estado de Nginx
systemctl status nginx
# Verificar puertos abiertos
netstat -tuln | grep -E '80|443'
# Reiniciar contenedor
docker restart wiki
# Verificar accesibilidad del contenedor
docker exec -it wiki curl -I http://localhost

8. Flujo de trabajo para crear y publicar contenido

Proceso para añadir nuevas páginas al wiki

Para crear nuevos contenidos en el wiki:

  1. Crea un nuevo archivo Markdown en la carpeta src/content/docs/:

    Ventana de terminal
    cd ~/GitHub/repositories/neodigital-wiki
    nano src/content/docs/nuevo-documento.md
  2. Estructura el documento con el formato correcto:

    ---
    title: Título del nuevo documento
    description: Descripción breve para SEO y metadatos
    ---
    # Título principal
    Contenido del documento en formato Markdown...
  3. Actualiza la barra lateral en astro.config.mjs para incluir el nuevo documento:

    sidebar: [
    // otras secciones...
    {
    label: 'Mi Nueva Sección',
    items: [
    { label: 'Nuevo Documento', link: '/nuevo-documento' }
    ]
    }
    ]
  4. Comprueba localmente los cambios (opcional):

    Ventana de terminal
    npm run dev
  5. Envía tus cambios a revisión:

    Ventana de terminal
    # Crea una rama para tus cambios o usa la rama dev
    git checkout dev
    # Añade y haz commit de tus cambios
    git add .
    git commit -m "Añadir nuevo documento: Nuevo Documento"
    # Envía tus cambios a la rama dev
    git 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
  6. Espera aprobación: El COO (Gerardo Alpuche) revisará el merge request y lo aprobará si cumple con los criterios de calidad.

  7. 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.