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,killy 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:
| Entorno | Cuenta Linux | Carpeta | Puerto | Base MariaDB |
|---|---|---|---|---|
| stage | wikijs_stage | /var/www/stage.site1 | 3003 | wikidb_stage |
| qa | wikijs_qa | /var/www/qa.site1 | 3004 | wikidb_qa |
| demo | wikijs_demo | /var/www/demo.site1 | 3005 | wikidb_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:
%ise reemplaza por la instancia (stage, qa, demo)wikijs_%ise convierte enwikijs_stage,wikijs_qa,wikijs_demo/var/www/%i.site1se 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
| Comando | Comentario / Propósito |
|---|---|
sudo ss -tuln | Muestra los puertos abiertos TCP/UDP (escucha), sin resolución DNS (rápido). |
sudo lsof -i -P -n | Muestra todos los puertos y los programas que los usan. |
sudo lsof -i -P -n | grep node | Filtra para ver solo los procesos Node.js. |
sudo netstat -tulnp | Comando antiguo equivalente a ss, también muestra los PID. |
sudo apt install net-tools | Instala netstat (necesario en Ubuntu moderno). |
ps aux | grep node | Lista todos los procesos que contienen "node". |
sudo lsof -i :3000 | Muestra el proceso que escucha específicamente en el puerto 3000. |
sudo apt install nmap | Instala nmap, un escáner de puertos. |
sudo nmap -sT -O localhost | Escanea los puertos abiertos en TCP en la máquina local. |
2. Gestión de Servicios Node.js con systemd
| Comando | Comentario / Propósito |
|---|---|
systemctl | grep node | Busca los servicios que contienen "node". |
systemctl list-units --type=service | Lista todos los servicios en ejecución. |
ls /etc/systemd/system/ | Lista los archivos .service instalados manualmente. |
sudo systemctl stop nombre-del-servicio | Detiene limpiamente un servicio (ej: wikijs.service). |
sudo systemctl disable nombre-del-servicio | Impide que el servicio se inicie en el próximo arranque. |
sudo rm /etc/systemd/system/nombre-del-servicio.service | Elimina el archivo de servicio. |
sudo systemctl daemon-reexec | Recarga completamente systemd. |
sudo systemctl daemon-reload | Recarga los archivos .service. |
systemctl list-units --type=service | grep -i node | Lista los servicios Node.js (insensible a mayúsculas). |
systemctl list-units --type=service | grep 3100 | Busca los servicios asociados al puerto 3100. |
sudo systemctl reset-failed | Restablece el estado de los servicios fallidos. |
3. Detención Manual de un Proceso (si no es un servicio)
| Comando | Comentario / Propósito |
|---|---|
sudo kill 1064738 | Intenta matar el proceso (PID 1064738) limpiamente. |
sudo kill -9 1064738 | Mata el proceso a la fuerza (SIGKILL). |
ps -fp 1072723 | Muestra el detalle del proceso 1072723 (formato extendido). |
sudo ls -l /proc/1072723/exe | Muestra 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
| Comando | Comentario / Propósito |
|---|---|
which pm2 | Verifica si pm2 está instalado. |
pm2 list | Lista las aplicaciones gestionadas por PM2. |
pm2 stop all | Detiene todas las aplicaciones PM2. |
pm2 delete all | Elimina todas las referencias a las aplicaciones. |
pm2 unstartup | Desactiva el inicio automático de PM2 al arrancar. |
5. Eliminación Completa de un Servicio systemd
| Comando | Comentario / Propósito |
|---|---|
ls /etc/systemd/system/ | grep -i wiki | Filtra los archivos .service relacionados con "wiki". |
sudo systemctl stop wikijs.service | Detiene el servicio antes de eliminarlo. |
sudo systemctl disable wikijs.service | Desactiva el servicio. |
sudo rm /etc/systemd/system/wikijs.service | Elimina el archivo del servicio. |
sudo systemctl daemon-reload | Recarga la configuración de systemd. |
sudo systemctl reset-failed | Restablece los errores de systemd. |
systemctl list-units --type=service | grep wiki | Verifica si el servicio ha desaparecido. |
systemctl status wikijs.service | Verifica 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
- Cree las 3 instancias (stage, qa, demo) siguiendo los pasos anteriores
- Verifique que todas las instancias estén activas
- 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):
- Reinicie primero la instancia correspondiente
- Ejecute el comando de detención
- Verifique si el servicio realmente se ha detenido
- Documente el resultado en una tabla
Ejercicio 3: Comparación de los Métodos
Cree una tabla comparativa:
| Método | Comando | ¿Funciona? | ¿Por qué? | ¿Recomendado? |
|---|---|---|---|---|
| A | systemctl stop | ? | ? | ? |
| B | systemctl disable | ? | ? | ? |
| C | killall wikijs | ? | ? | ? |
| D | fuser -k port/tcp | ? | ? | ? |
| E | lsof -ti:port | xargs kill -9 | ? | ? | ? |
| F | systemctl reload | ? | ? | ? |
Preguntas de Reflexión
-
¿Por qué
systemctl disableno detiene un servicio que ya está en ejecución?- Explique la diferencia entre
stopydisable
- Explique la diferencia entre
-
¿Cuáles son los riesgos de usar
killallpara detener servicios?- Dé un ejemplo de escenario donde esto podría causar problemas
-
¿Por qué
systemctl reloadno detiene el servicio?- Explique la diferencia entre
reloadyrestart
- Explique la diferencia entre
-
¿Cuál es la diferencia entre
killykill -9?- ¿En qué casos usaría cada uno de estos comandos?
-
¿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 ✅
systemctl stop wikijs@instance- Detención limpia vía systemdfuser -k port/tcp- Detención vía puerto (funciona pero menos limpio)lsof -ti:port \| xargs kill -9- Detención forzada (último recurso)
Métodos a Evitar ❌
systemctl disable- No detiene, solo desactiva al iniciosystemctl reload- Recarga la configuración pero no detienekillall 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.ymlcon 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