Actúa como mi ingeniero DevOps. Vas a publicar mi aplicación en mi Cloud Server
de Donweb. Yo no sé de servidores, así que explícame cada paso importante en una
frase simple antes de ejecutarlo.
DATOS DEL SERVIDOR (de mi panel de Donweb):
- IP: {IP_DEL_SERVIDOR}
- Hostname: {HOSTNAME} ← aparece como "Host" en el panel, ej: vps-57585926-x.dattaweb.com
- Puerto SSH: {PUERTO_SSH} ← atención: en Donweb no es el 22, revisa "Puerto" en el panel
- Usuario: root
- Sistema operativo del servidor: {SISTEMA_OPERATIVO} (Ej: Ubuntu 24.04 instalación mínima, recién creado)
← atención: revisa primero que corresponda con el SO del servidor
MI APLICACIÓN:
- Ubicación: {RUTA_LOCAL_ABSOLUTA_O_URL_DEL_REPO}
- El repositorio es: {público / privado / no es un repo, es una carpeta local}
- Tipo: {ej: Node.js / PHP / sitio estático — si no lo sabes, examina el código y dime}
- Puerto interno en el que corre (si aplica): {ej: 3000}
- Variables de entorno / claves que necesita: {ej: DATABASE_URL, API_KEY... / no sé}
- Mi dominio propio (opcional, solo si quiero conectarlo hoy): {ej: miapp.com / por ahora no}
CÓMO LEER ESTE PROMPT (importante):
- Todos los datos que necesitas están en las dos secciones de arriba. Cuando más
abajo diga "la IP", "el puerto SSH", "el hostname", "la ubicación de mi app" o
"mi dominio", me refiero siempre a los valores de esas secciones.
- Antes de ejecutar nada, revísalas: si algún valor quedó vacío, sigue siendo un
texto entre llaves { }, o parece un ejemplo sin completar, detente y pídemelo.
MI ENTORNO LOCAL:
- No asumas mi sistema operativo: detéctalo primero con un comando apropiado
(Windows, macOS o Linux) y adapta todos los comandos locales a lo que
encuentres. En particular:
- Windows: no hay rsync, y ssh-copy-id puede no existir. Para copiar archivos
usa scp (recuerda que scp usa -P mayúscula para el puerto). Para instalar
mi clave pública en el servidor, si ssh-copy-id no está disponible, usa el
método equivalente (leer mi clave .pub y agregarla a authorized_keys en el
servidor vía ssh). Ten cuidado con el formato de rutas (C:...) y el
quoting de PowerShell.
- macOS / Linux: puedes usar scp o rsync — si eliges rsync, verifica primero
que también exista en el servidor (o instálalo allí).
- En todos los casos: git clone directo en el servidor solo si el repo es
público; si es privado o es una carpeta local, copia los archivos desde mi
máquina.
CONTEXTO DEL SERVIDOR:
- Mi Cloud Server ya tiene un firewall virtual administrado desde el panel de
Donweb, con los puertos 80, 443 y el puerto SSH indicado arriba abiertos.
NO instales ni actives otro firewall (ufw/iptables) dentro del servidor:
no hace falta y podría dejarme afuera.
- Si mi aplicación necesita recibir tráfico de internet en algún otro puerto,
no intentes abrirlo desde el servidor: ese firewall se gestiona desde el
panel y lo hago yo. Dime exactamente qué puerto y protocolo (TCP/UDP) hacen
falta y guíame: en mi panel de Donweb → mi Cloud Server → sección
"Firewall" → "Agregar regla" (puerto, protocolo y origen; para acceso
general el origen es 0.0.0.0/0 en IPv4 y ::/0 en IPv6). Antes de pedírmelo,
evalúa si de verdad hace falta: lo normal es que todo el tráfico entre por
nginx en los puertos 80/443 que ya están abiertos.
REGLAS DE SEGURIDAD (obligatorias):
- Nunca escribas, muestres ni guardes mi contraseña en texto plano. La única
vez que se necesita es al instalar la clave SSH (paso 1): ahí me detendré a
escribirla yo. No uses sshpass ni ningún método que requiera ponerla en un
comando o archivo.
- Antes de cualquier acción destructiva (borrar archivos, formatear, reinstalar
servicios existentes), avísame y espera mi confirmación.
- No leas, resumas ni reportes /var/log/auth.log, la salida de lastb, el
correo del sistema ni los intentos de login fallidos, salvo que yo te lo
pida explícitamente. Los intentos de login fallidos en una IP pública son
ruido normal de internet: no los presentes como hallazgo de seguridad ni
listes IPs o direcciones involucradas.
- Lo mismo con cualquier secreto: nunca muestres en pantalla el contenido de
archivos .env ni valores de API keys, tokens o contraseñas — ni los míos
ni los que generes. Si necesitas crear credenciales nuevas (por ejemplo,
el usuario de una base de datos), genera contraseñas fuertes al azar,
guárdalas directo en el .env del servidor (permisos 600) y dime solo en
qué archivo quedaron.
- La base de datos y cualquier servicio interno deben escuchar solo en
localhost (127.0.0.1), nunca en 0.0.0.0. A internet solo se expone lo que
sirve el servidor web / proxy inverso (nginx, Caddy o el que se use).
- No modifiques la configuración de acceso SSH del servidor (puerto,
PasswordAuthentication, PermitRootLogin) salvo que un paso de este prompt
lo pida explícitamente — y nunca sin haber probado antes, en una sesión
nueva, que existe otra vía de acceso funcionando.
- Instala solo lo que mi aplicación necesita: sin paneles, herramientas de
monitoreo ni software extra que yo no haya pedido.
REGLAS DE EJECUCIÓN (para que nada se quede colgado):
- En la PRIMERA conexión SSH usa -o StrictHostKeyChecking=accept-new para que
no quede esperando una confirmación interactiva.
- En el servidor, ejecuta apt siempre con DEBIAN_FRONTEND=noninteractive y
NEEDRESTART_MODE=a para evitar menús interactivos.
- No hagas un upgrade completo del sistema en este primer deploy: solo
apt update e instala lo que haga falta.
- Si mi aplicación necesita una base de datos u otro servicio (Postgres,
MySQL, Redis...), avísame y explícame qué vas a instalar antes de hacerlo.
PASOS:
- Verifica que la ubicación de mi aplicación (sección MI APLICACIÓN) existe y
es accesible. Si no, detente y pregúntame antes de tocar el servidor.
- Configura el acceso por clave SSH (así solo escribo mi contraseña UNA vez):
genera una clave en mi máquina si no tengo una (ssh-keygen, sin passphrase,
ruta por defecto) e instálala en el servidor usando la IP y el puerto SSH
indicados arriba — con ssh-copy-id o el método equivalente según mi sistema
operativo (ver MI ENTORNO LOCAL). Ahí el sistema me pedirá la contraseña y
la escribo yo. Verifica después que puedes entrar sin contraseña. Todo lo
que sigue debe ser no-interactivo.
- Conéctate por SSH y verifica que el servidor responde. Muéstrame sistema,
memoria y disco disponibles.
- Prepara el servidor: actualiza el índice de paquetes e instala lo que mi
aplicación necesite (runtime, nginx). Si la app es Node.js, detecta la
versión que requiere (package.json → engines, .nvmrc, o dependencias) e
instálala desde NodeSource — la versión de los repos de Ubuntu es vieja.
Si el servidor tiene 1-2 GB de RAM, crea un archivo swap de 1 GB.
- Sube mi aplicación al servidor, a una carpeta dentro de /opt con un nombre
corto basado en el nombre de mi app. Instala sus dependencias si tiene.
- Si detectas un .env.example, un .env faltante o referencias a variables de
entorno no definidas, detente y pregúntame los valores antes de arrancar
la aplicación. Guarda el .env en el servidor con permisos 600.
- Configura mi aplicación como servicio del sistema (systemd) para que
arranque sola si el servidor se reinicia, y verifica que quede corriendo.
- Configura nginx como proxy inverso: el puerto 80 debe servir mi aplicación,
respondiendo tanto por la IP como por el hostname del servidor.
Verifica la configuración antes de recargar nginx.
- Verifica el resultado: desde fuera del servidor, haz una petición HTTP al
hostname y prueba también la funcionalidad principal de mi app (formulario,
API, lo que tenga).
- Entrégame un resumen: la URL donde vive mi app (http:// + el hostname),
qué instalaste, dónde quedaron los archivos, y los 3 comandos que me
conviene conocer (ver estado, ver logs, reiniciar la app).
FASE OPCIONAL A — MI DOMINIO + HTTPS (solo si completé "Mi dominio propio"
arriba; si no, pregúntame al terminar el paso 9 si quiero hacerla):
- Quiero que mi app responda en mi dominio. Guíame para crear el registro
DNS: un registro A apuntando a la IP del servidor, en el panel de DNS de
Donweb, Cloudflare u otro proveedor (dime exactamente qué campos completar
según cuál use). Luego verifica con dig/nslookup que el dominio ya resuelve
a la IP — si todavía no propaga, dime cuánto suele tardar y esperemos.
- Cuando resuelva: configura nginx para responder por ese dominio y agrega
HTTPS con un certificado gratuito de Let's Encrypt (certbot), con
renovación automática. Verifica que https:// + mi dominio responde.
FASE OPCIONAL B — SEGURIDAD EXTRA (pregúntame si quiero hacerla ahora):
- Crear un usuario no-root para administrar la app, verificar que mi clave
SSH del paso 1 también funciona para ese usuario en una sesión nueva, y
solo entonces deshabilitar el login por contraseña.
Si algo falla, explícame el error en lenguaje simple, dime si es grave, y
propón la solución antes de aplicarla.