Saltar al contenido principal

Lab 8.5 - Ejercicio Anexo: Crear 3 Nuevos Servicios Wiki.js y Probar Diferentes Formas de Detenerlos

Objetivos​

Al final de este laboratorio, usted será capaz de:

  • Dominar la creación de instancias adicionales a partir de una plantilla systemd (wikijs@.service)
  • Comparar varios comandos de "detención" e identificar cuáles funcionan correctamente (y por qué)
  • Utilizar plantillas systemd para gestionar múltiples instancias de una misma aplicación
  • Identificar y detener procesos Node.js de diferentes maneras
  • Comprender las diferencias entre stop, disable, kill y otros métodos de detención

Requisitos Previos​

  • Ubuntu 24.04 instalado
  • Acceso sudo/root
  • Wiki.js ya instalado (al menos una instancia)
  • Conocimientos básicos de systemd y MariaDB
  • Terminal abierto

Visión General​

En este laboratorio, usted creará 3 nuevas instancias de Wiki.js (stage, qa, demo) utilizando una plantilla systemd. Luego, probará diferentes métodos para detener estos servicios y comprenderá por qué algunos funcionan y otros no.

Arquitectura de las instancias:

EntornoCuenta LinuxCarpetaPuertoBase MariaDB
stagewikijs_stage/var/www/stage.site13003wikidb_stage
qawikijs_qa/var/www/qa.site13004wikidb_qa
demowikijs_demo/var/www/demo.site13005wikidb_demo

Parte 1: Preparación de la Plantilla systemd​

Paso 1: Crear la Plantilla systemd​

Si aún no tiene una plantilla, créela:

sudo nano /etc/systemd/system/wikijs@.service

Contenido de la plantilla:

[Unit]
Description=Wiki.js Instance %i
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/node server
Restart=always
User=wikijs_%i
Environment=NODE_ENV=production
WorkingDirectory=/var/www/%i.site1

[Install]
WantedBy=multi-user.target

Explicación:

  • %i se reemplaza por la instancia (stage, qa, demo)
  • wikijs_%i se convierte en wikijs_stage, wikijs_qa, wikijs_demo
  • /var/www/%i.site1 se convierte en /var/www/stage.site1, etc.

Paso 2: Recargar systemd​

sudo systemctl daemon-reload

Parte 2: Creación de las Tres Nuevas Instancias​

Paso 1: Crear los Usuarios del Sistema​

# Crear los usuarios para cada instancia
sudo adduser --system --group wikijs_stage
sudo adduser --system --group wikijs_qa
sudo adduser --system --group wikijs_demo

# Permitir la conexión con bash
sudo usermod -s /bin/bash wikijs_stage
sudo usermod -s /bin/bash wikijs_qa
sudo usermod -s /bin/bash wikijs_demo

Paso 2: Crear los Directorios​

# Crear los directorios para cada instancia
sudo mkdir -p /var/www/stage.site1
sudo mkdir -p /var/www/qa.site1
sudo mkdir -p /var/www/demo.site1

# Definir los propietarios
sudo chown -R wikijs_stage:wikijs_stage /var/www/stage.site1
sudo chown -R wikijs_qa:wikijs_qa /var/www/qa.site1
sudo chown -R wikijs_demo:wikijs_demo /var/www/demo.site1

Paso 3: Crear las Bases de Datos MariaDB​

# Conectarse a MariaDB
sudo mysql -u root -p

En el shell de MariaDB:

-- Crear las bases de datos
CREATE DATABASE wikidb_stage;
CREATE DATABASE wikidb_qa;
CREATE DATABASE wikidb_demo;

-- Crear los usuarios
CREATE USER 'wikidb_stage_user'@'localhost' IDENTIFIED BY 'password_stage';
CREATE USER 'wikidb_qa_user'@'localhost' IDENTIFIED BY 'password_qa';
CREATE USER 'wikidb_demo_user'@'localhost' IDENTIFIED BY 'password_demo';

-- Conceder los privilegios
GRANT ALL PRIVILEGES ON wikidb_stage.* TO 'wikidb_stage_user'@'localhost';
GRANT ALL PRIVILEGES ON wikidb_qa.* TO 'wikidb_qa_user'@'localhost';
GRANT ALL PRIVILEGES ON wikidb_demo.* TO 'wikidb_demo_user'@'localhost';

FLUSH PRIVILEGES;
EXIT;

Paso 4: Descargar e Instalar Wiki.js para Cada Instancia​

Para Stage (puerto 3003)​

# Conectarse como wikijs_stage
sudo su - wikijs_stage

# Ir al directorio
cd /var/www/stage.site1

# Descargar Wiki.js
wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz

# Extraer
tar xzf wiki-js.tar.gz

# Eliminar el archivo comprimido
rm wiki-js.tar.gz

# Copiar el archivo de configuración
cp config.sample.yml config.yml

# Editar la configuración
nano config.yml

Configuración para stage:

port: 3003
bindIP: 0.0.0.0
db:
type: mariadb
host: localhost
port: 3306
user: wikidb_stage_user
pass: password_stage
db: wikidb_stage
ssl: false

Guarde y salga. Luego:

exit

Para QA (puerto 3004)​

sudo su - wikijs_qa
cd /var/www/qa.site1
wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz
tar xzf wiki-js.tar.gz
rm wiki-js.tar.gz
cp config.sample.yml config.yml
nano config.yml

Configuración para qa:

port: 3004
bindIP: 0.0.0.0
db:
type: mariadb
host: localhost
port: 3306
user: wikidb_qa_user
pass: password_qa
db: wikidb_qa
ssl: false

Guarde y salga. Luego:

exit

Para Demo (puerto 3005)​

sudo su - wikijs_demo
cd /var/www/demo.site1
wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz
tar xzf wiki-js.tar.gz
rm wiki-js.tar.gz
cp config.sample.yml config.yml
nano config.yml

Configuración para demo:

port: 3005
bindIP: 0.0.0.0
db:
type: mariadb
host: localhost
port: 3306
user: wikidb_demo_user
pass: password_demo
db: wikidb_demo
ssl: false

Guarde y salga. Luego:

exit

Paso 5: Habilitar e Iniciar los Servicios​

# Habilitar e iniciar las tres instancias
sudo systemctl enable --now wikijs@stage
sudo systemctl enable --now wikijs@qa
sudo systemctl enable --now wikijs@demo

Paso 6: Control​

# Verificar el estado de cada instancia
sudo systemctl status wikijs@stage --no-pager
sudo systemctl status wikijs@qa --no-pager
sudo systemctl status wikijs@demo --no-pager

# Verificar que los puertos estén en escucha
sudo ss -tlnp | grep -E '3003|3004|3005'

Parte 3: Identificar los Procesos y Puertos​

Anexo 1: Comandos para Identificar los Procesos Node.js​

1. Mostrar Todos los Procesos Node con la Unidad systemd​

ps -eo pid,user,unit,cmd | grep -w node

2. Versión Compacta: PID + Línea de Comando​

pgrep -a node

3. Bucle: Para Cada PID Node, Mostrar los Puertos que Escucha​

for pid in $(pgrep node); do lsof -Pan -p "$pid" -i; done

4. Mostrar Directamente Todos los Sockets Node Abiertos​

ss -tlnp | grep node

5. Para un PID Específico​

# Reemplace 1234 por el PID real
systemctl status --pid=1234
cat /proc/1234/cgroup | grep system.slice

Parte 4: Probar Diferentes Métodos de Detención​

Métodos de Detención a Probar​

Comando A – Detención Correcta por systemd​

# Detención limpia de la instancia stage
sudo systemctl stop wikijs@stage

Análisis: Este comando detiene limpiamente el servicio mediante systemd. Es el método recomendado.

Comando B – Error Lógico: Desactiva para el Futuro, No Detiene​

# Desactiva el servicio pero no lo detiene inmediatamente
sudo systemctl disable wikijs@qa

Análisis: Este comando desactiva el servicio al inicio pero no lo detiene si ya está en ejecución. El servicio sigue funcionando hasta el próximo reinicio.

Comando C – ⚠️ Muy Riesgoso: Mata Todos los Procesos "wikijs"​

# Mata todos los procesos llamados "wikijs"
sudo killall wikijs

Análisis: Este comando es riesgoso porque mata todos los procesos que coinciden con el nombre, sin distinción. Puede afectar otros procesos no relacionados.

Comando D – Detención Indirecta vía el Puerto de la Instancia Demo (3005)​

# Mata el proceso que escucha en el puerto 3005
sudo fuser -k 3005/tcp

Análisis: Este comando identifica y mata el proceso que utiliza el puerto 3005. Funciona pero es menos limpio que systemctl.

Comando E – Detención Forzada de QA (puerto 3004) vía lsof + kill -9​

# Encuentra el PID que escucha en 3004 y lo mata
sudo lsof -ti:3004 | xargs sudo kill -9

Análisis: Este comando encuentra el PID del proceso que escucha en el puerto 3004 y lo mata a la fuerza. Funciona pero utiliza SIGKILL (fuerza bruta).

Comando F – Reload ≠ Stop: No Detiene el Servicio​

# Recarga la configuración pero no detiene el servicio
sudo systemctl reload wikijs@demo

Análisis: Este comando recarga la configuración del servicio pero no lo detiene. El servicio sigue funcionando.

Solo Respuestas Correctas​

Los comandos que realmente detienen los servicios son:

# Comando A - Detención limpia
sudo systemctl stop wikijs@stage

# Comando D - Detención vía puerto
sudo fuser -k 3005/tcp

# Comando E - Detención forzada vía puerto
sudo lsof -ti:3004 | xargs sudo kill -9

Verificación de la Detención​

# Verificar que ningún servicio siga activo
sudo systemctl status wikijs@stage
sudo systemctl status wikijs@qa
sudo systemctl status wikijs@demo

# Ver si aún hay puertos en escucha
sudo ss -tlnp | grep node

# Verificar los procesos Node.js
ps aux | grep node

Parte 5: Ampliación (Opcional)​

Reiniciar Limpia y Simultáneamente Todas las Instancias​

# Reiniciar todas las instancias en un solo comando
sudo systemctl restart wikijs@{stage,qa,demo}

Revisar Todos los Puertos Node.js Actualmente Activos​

# Ver todos los puertos Node.js en escucha
sudo lsof -iTCP -sTCP:LISTEN | grep node

Verificar que Todos los Puertos Estén Liberados Tras una Detención​

# Detener todas las instancias
sudo systemctl stop wikijs@{stage,qa,demo}

# Verificar que los puertos estén libres
sudo ss -tlnp | egrep '3003|3004|3005'

Anexo 2: Comandos Útiles para la Gestión de Servicios​

1. Ver Todos los Puertos Activos y los Procesos Relacionados​

ComandoComentario / Propósito
sudo ss -tulnMuestra los puertos abiertos TCP/UDP (escucha), sin resolución DNS (rápido).
sudo lsof -i -P -nMuestra todos los puertos y los programas que los usan.
sudo lsof -i -P -n | grep nodeFiltra para ver solo los procesos Node.js.
sudo netstat -tulnpComando antiguo equivalente a ss, también muestra los PID.
sudo apt install net-toolsInstala netstat (necesario en Ubuntu moderno).
ps aux | grep nodeLista todos los procesos que contienen "node".
sudo lsof -i :3000Muestra el proceso que escucha específicamente en el puerto 3000.
sudo apt install nmapInstala nmap, un escáner de puertos.
sudo nmap -sT -O localhostEscanea los puertos abiertos en TCP en la máquina local.

2. Gestión de Servicios Node.js con systemd​

ComandoComentario / Propósito
systemctl | grep nodeBusca los servicios que contienen "node".
systemctl list-units --type=serviceLista todos los servicios en ejecución.
ls /etc/systemd/system/Lista los archivos .service instalados manualmente.
sudo systemctl stop nombre-del-servicioDetiene limpiamente un servicio (ej: wikijs.service).
sudo systemctl disable nombre-del-servicioImpide que el servicio se inicie en el próximo arranque.
sudo rm /etc/systemd/system/nombre-del-servicio.serviceElimina el archivo de servicio.
sudo systemctl daemon-reexecRecarga completamente systemd.
sudo systemctl daemon-reloadRecarga los archivos .service.
systemctl list-units --type=service | grep -i nodeLista los servicios Node.js (insensible a mayúsculas).
systemctl list-units --type=service | grep 3100Busca los servicios asociados al puerto 3100.
sudo systemctl reset-failedRestablece el estado de los servicios fallidos.

3. Detención Manual de un Proceso (si no es un servicio)​

ComandoComentario / Propósito
sudo kill 1064738Intenta matar el proceso (PID 1064738) limpiamente.
sudo kill -9 1064738Mata el proceso a la fuerza (SIGKILL).
ps -fp 1072723Muestra el detalle del proceso 1072723 (formato extendido).
sudo ls -l /proc/1072723/exeMuestra el binario real ejecutado por el proceso.
sudo cat /proc/1072723/cmdline | tr '\0' ' 'Muestra el comando exacto que lanzó el proceso.

4. Detección y Detención de Procesos Gestionados por PM2​

ComandoComentario / Propósito
which pm2Verifica si pm2 está instalado.
pm2 listLista las aplicaciones gestionadas por PM2.
pm2 stop allDetiene todas las aplicaciones PM2.
pm2 delete allElimina todas las referencias a las aplicaciones.
pm2 unstartupDesactiva el inicio automático de PM2 al arrancar.

5. Eliminación Completa de un Servicio systemd​

ComandoComentario / Propósito
ls /etc/systemd/system/ | grep -i wikiFiltra los archivos .service relacionados con "wiki".
sudo systemctl stop wikijs.serviceDetiene el servicio antes de eliminarlo.
sudo systemctl disable wikijs.serviceDesactiva el servicio.
sudo rm /etc/systemd/system/wikijs.serviceElimina el archivo del servicio.
sudo systemctl daemon-reloadRecarga la configuración de systemd.
sudo systemctl reset-failedRestablece los errores de systemd.
systemctl list-units --type=service | grep wikiVerifica si el servicio ha desaparecido.
systemctl status wikijs.serviceVerifica si el servicio aún existe.
ls -l /etc/systemd/system/Lista completa para verificar manualmente.
grep -r ExecStart /etc/systemd/system/Busca las líneas de inicio en todos los servicios.

Anexo 3: Lista Exhaustiva de Comandos​

Comandos para Ver los Puertos​

sudo ss -tuln
sudo lsof -i -P -n
sudo lsof -i -P -n | grep node
sudo netstat -tulnp
sudo apt install net-tools
ps aux | grep node
sudo lsof -i :3000
sudo apt install nmap
sudo nmap -sT -O localhost

Comandos systemd​

systemctl | grep node
systemctl list-units --type=service
ls /etc/systemd/system/
sudo systemctl stop nombre-del-servicio
sudo systemctl stop wikijs.service
sudo systemctl disable nombre-del-servicio
sudo rm /etc/systemd/system/nombre-del-servicio.service
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
systemctl | grep 3100
systemctl | grep node
sudo systemctl stop wikijs.service

Comandos kill​

sudo kill 1064738
sudo kill -9 1064738
sudo ss -tuln | grep 3100
sudo lsof -i :3100

Comandos PM2​

which pm2 && pm2 list
pm2 stop all
pm2 delete all
pm2 unstartup

Comandos de Diagnóstico​

sudo systemctl list-units --type=service | grep -i node
ps aux | grep node
ps -fp 1072723
sudo ls -l /proc/1072723/exe
sudo cat /proc/1072723/cmdline | tr '\0' ' '
ls /etc/systemd/system/ | grep -i wiki
ls /lib/systemd/system/ | grep -i wiki
grep -r 3100 /etc/systemd/system/

Comandos de Eliminación​

sudo systemctl stop nombre.service
sudo systemctl disable nombre.service
sudo systemctl daemon-reload
sudo systemctl reset-failed
ls /etc/systemd/system/
ls /etc/systemd/system/ | grep -i wiki
sudo systemctl stop wikijs.service
sudo systemctl disable wikijs.service
sudo rm /etc/systemd/system/wikijs.service
sudo systemctl daemon-reload
sudo systemctl reset-failed
systemctl list-units --type=service | grep wiki
systemctl status wikijs.service
ls -l /etc/systemd/system/
grep -r ExecStart /etc/systemd/system/

Ejercicios Prácticos​

Ejercicio 1: Crear e Iniciar las 3 Instancias​

  1. Cree las 3 instancias (stage, qa, demo) siguiendo los pasos anteriores
  2. Verifique que todas las instancias estén activas
  3. Verifique que los puertos 3003, 3004, 3005 estén en escucha

Ejercicio 2: Probar los Métodos de Detención​

Para cada método de detención (A, B, C, D, E, F):

  1. Reinicie primero la instancia correspondiente
  2. Ejecute el comando de detención
  3. Verifique si el servicio realmente se ha detenido
  4. Documente el resultado en una tabla

Ejercicio 3: Comparación de los Métodos​

Cree una tabla comparativa:

MétodoComando¿Funciona?¿Por qué?¿Recomendado?
Asystemctl stop???
Bsystemctl disable???
Ckillall wikijs???
Dfuser -k port/tcp???
Elsof -ti:port | xargs kill -9???
Fsystemctl reload???

Preguntas de Reflexión​

  1. ¿Por qué systemctl disable no detiene un servicio que ya está en ejecución?

    • Explique la diferencia entre stop y disable
  2. ¿Cuáles son los riesgos de usar killall para detener servicios?

    • Dé un ejemplo de escenario donde esto podría causar problemas
  3. ¿Por qué systemctl reload no detiene el servicio?

    • Explique la diferencia entre reload y restart
  4. ¿Cuál es la diferencia entre kill y kill -9?

    • ¿En qué casos usaría cada uno de estos comandos?
  5. ¿Por qué usar una plantilla systemd (wikijs@.service) en lugar de crear 3 archivos de servicio separados?

    • ¿Cuáles son las ventajas y desventajas de cada enfoque?

Resumen de los Métodos de Detención​

Métodos Recomendados ✅​

  1. systemctl stop wikijs@instance - Detención limpia vía systemd
  2. fuser -k port/tcp - Detención vía puerto (funciona pero menos limpio)
  3. lsof -ti:port \| xargs kill -9 - Detención forzada (último recurso)

Métodos a Evitar ❌​

  1. systemctl disable - No detiene, solo desactiva al inicio
  2. systemctl reload - Recarga la configuración pero no detiene
  3. killall wikijs - Demasiado riesgoso, puede afectar otros procesos

Verificación Final​

Verifique que ha logrado:

  • Crear la plantilla systemd wikijs@.service
  • Crear los 3 usuarios del sistema (wikijs_stage, wikijs_qa, wikijs_demo)
  • Crear los 3 directorios e instalar Wiki.js en cada uno
  • Crear las 3 bases de datos MariaDB
  • Configurar los archivos config.yml con los puertos correctos
  • Habilitar e iniciar las 3 instancias
  • Verificar que los puertos 3003, 3004, 3005 estén en escucha
  • Probar todos los métodos de detención
  • Comprender por qué algunos métodos funcionan y otros no
  • Responder las preguntas de reflexión

Próximos Pasos​

  • Lab 8.1: Gestión de Servicios systemd (revisión)
  • Lab 8.2: Servicios Personalizados (profundización)
  • TP 2: Reverse Proxy NGINX (para exponer las instancias vía un reverse proxy)

Lab creado el: Diciembre 2024