Aplica a: Cloud Server con CloudPanel instalado · Tiempo estimado: 30 min
¿Qué vas a lograr?
Desplegar una aplicación Node.JS en CloudPanel con dominio propio, certificado SSL y gestión de procesos con PM2 para que la aplicación siga funcionando después de reinicios del servidor.
Antes de empezar
Necesitás tener CloudPanel instalado y las configuraciones básicas completadas. También es útil tener conocimientos básicos de consola Linux, aunque el tutorial es seguible para principiantes.
1. Apuntar el dominio al servidor
En la zona DNS de tu proveedor, creá dos registros para el dominio o subdominio que usará la aplicación:
Registro A apuntando a la IPv4 del servidor
Registro AAAA apuntando a la IPv6 del servidor
Podés obtener ambas IPs en Mis Servicios → Cloud & IaaS → Gestionar → Información.
Esperá unos minutos para que los cambios se propaguen.
2. Crear el sitio Node.JS en CloudPanel
En CloudPanel, andá a Sitios → Crear nuevo sitio → Crear un sitio a Node.JS
Completá los datos:
Dominio de la aplicación
Versión de Node.JS
Puerto en el que correrá la aplicación
Usuario del sitio y contraseña (para acceso SSH posterior)
Hacé clic en Crear
3. Instalar el certificado SSL
En Sitios, hacé clic en Administrar sobre el sitio recién creado
Andá a SSL/TLS → Acciones → Certificado Let's Encrypt nuevo
Presioná Crear e instalar
4. Subir la aplicación al servidor
Subí los archivos de tu aplicación (incluyendo package.json) a la carpeta del sitio en el servidor:
/home/[usuario-del-sitio]/htdocs/[tu-dominio]/
Podés hacerlo por SFTP con FileZilla usando las credenciales del usuario del sitio, o desde el Administrador de archivos de CloudPanel.
5. Instalar las dependencias
Conectáte al servidor por SSH usando las credenciales del usuario del sitio (no como root) y ejecutá:
cd /home/qr-app/htdocs/qr.cloudme.fun/
npm install
Al finalizar la instalacion verás algo similar a esta captura:
6. Instalar PM2
PM2 es un administrador de procesos que mantiene la aplicación corriendo en segundo plano. Cada sitio Node en CloudPanel requiere su propia instancia de PM2:
cd /home/qr-app/htdocs/qr.cloudme.fun/
npm install pm2@latest -g
Al finalizar la instalación veremos algo similar a esta captura:
7. Ejecutar la aplicación con PM2
pm2 start npm --name qr-app -- start
Si todo está en orden veremos algo como esto:
Finalmente, si nuestra aplicación se ejecutó sin errores, utilizaremos el comando pm2 save para guardar la configuración.
pm2 save
8. Verificar que funciona
Abrí el navegador e ingresá a https://tu-dominio.com. Si la aplicación responde correctamente, el despliegue fue exitoso.
9. Configurar inicio automático tras reinicio del servidor
Para que la aplicación arranque sola después de un reinicio:
echo $PATH
Editá el crontab:
crontab -e
Agregá estas dos líneas al final, reemplazando PASTE_THE_OUTPUT_OF_$PATH con el resultado del paso anterior:
PATH=PASTE_THE_OUTPUT_OF_$PATH
@reboot pm2 resurrect & /dev/nullGuardá los cambios, reiniciá el servidor y verificá que la aplicación responde.
10. Reiniciar la aplicación después de cambios en el código
pm2 restart qr-app
Comentarios finales
Para desplegar varias aplicaciones en el mismo servidor, repetí estos 10 pasos por cada una — cada aplicación debe correr en un puerto distinto.
Código de ejemplo: generador de códigos QR
A continuación el código de una aplicación de ejemplo que genera un código QR a partir de un UUID pasado en la URL, funcionando como una API. Si el QR ya fue generado previamente, lo devuelve sin regenerarlo.
package.json
{
"name": "qrapp",
"version": "1.0.0",
"description": "Aplicación Node.js que genera y sirve códigos QR a partir de un UUID",
"main": "qrapp.js",
"scripts": {
"start": "node qrapp.js"
},
"keywords": [],
"author": "Donweb.cloud",
"license": "ISC",
"dependencies": {
"express": "^4.18.2",
"qrcode": "^1.5.1"
}
}qrapp.js
const express = require('express');
const QRCode = require('qrcode');
const fs = require('fs');
const path = require('path');
const app = express();
const port = 3005;
const qrDir = path.join(__dirname, 'qr-codes');
// Asegurarse de que el directorio exista
if (!fs.existsSync(qrDir)){
fs.mkdirSync(qrDir);
}
app.get('/:uuid', async (req, res) => {
try {
const uuid = req.params.uuid;
const reg = new RegExp("^[0-9A-Za-z]{8}-[0-9A-Za-z]{4}-4[0-9A-Za-z]{3}-[89ABab][0-9A-Za-z]{3}-[0-9A-Za-z]{12}$");
if (!uuid) {
return res.status(400).send('Falta el UUID');
}
if(!reg.test(uuid)){
return res.status(400).send('Invalid UUID');
}
// Ruta donde se almacenará o se ha almacenado el código QR
const filePath = path.join(qrDir, `${uuid}.png`);
// Comprobar si el archivo ya existe
if (fs.existsSync(filePath)) {
return res.sendFile(filePath);
}
// Si no existe, generar el código QR y guardar como un archivo
QRCode.toFile(filePath, uuid, {
scale: 28,
margin: 4
}, (err) => {
if (err) {
console.error('Error al guardar el código QR:', err);
return res.status(500).send('Error al generar el código QR');
}
res.sendFile(filePath);
});
} catch (err) {
console.error(err);
res.status(500).send('Error al generar el código QR');
}
});
app.listen(port, '127.0.0.1', () => {});













