Cómo Desplegar Astro en un VPS con CloudPanel (Guía 2026)
Aprende a desplegar Astro en un VPS con CloudPanel: compila un sitio estático, añade SSL y el CDN de Cloudflare, automatiza los rebuilds y revierte despliegues con seguridad en tu servidor.
21 min de lectura

Desplegar Astro en un VPS con CloudPanel te da lo único que las plataformas gratuitas nunca ofrecen: control total. Tu build, tus cabeceras de caché, tu ruta de rollback y sin límites de minutos de build esperando para sorprenderte a final de mes. El hosting gratuito como Cloudflare Pages, Vercel y Netlify funciona bien hasta que deja de hacerlo: límites de ancho de banda, límites de build o lock-in de plataforma.
CloudPanel es un panel de hosting gratuito que corre sobre Nginx. Gestiona la administración de sitios, el SSL y el aislamiento de usuarios a través de una interfaz web. Despliegas Astro como un Static HTML site y dejas que CloudPanel sirva los archivos compilados directamente desde Nginx. Ningún proceso de Node.js corre en runtime, lo que significa que un VPS pequeño y barato es suficiente. Y desde que Astro 7 salió en junio de 2026 con builds entre un 15 y un 61 % más rápidos (nuestro benchmark de builds de Astro 7), los rebuilds en esa máquina pequeña son más rápidos que antes.
DigitalOcean 100 $ gratis Vultr 100 $ gratis Hetzner 20 € gratis Hostinger VPSLos precios de los VPS subieron en todos los proveedores en 2026. Si estás replanteándote una máquina alquilada, mira qué cambió y cuándo gana un mini PC.
Prerequisitos
Antes de empezar, esto es lo que ya tiene que existir:
- Un servidor VPS. 1 GB de RAM funciona con swap, 2 GB es cómodo. Orden de magnitud: de 5 a 10 $/mes. Cualquier proveedor vale. Yo compararía opciones con DigitalOcean vs Vultr vs Hetzner antes de comprar.
- CloudPanel instalado. Sigue la guía Instalar CloudPanel y alojar apps Node.js si aún no lo tienes. Si todavía estás comparando paneles, mira los mejores paneles de servidor self-hosted.
- Un nombre de dominio con DNS que puedas editar.
- Acceso SSH al servidor como root. Ya que estás, refuerza el acceso SSH de tu servidor. Un VPS público recibe escaneos a los pocos minutos de arrancar.
El stack que monta esta guía: VPS Linux + CloudPanel (Nginx) + NVM + Node 24 + Cloudflare delante. Todo lo demás es opcional.
Mantén CloudPanel actualizado
El changelog de CloudPanel muestra un historial real de CVEs, incluidos fixes de escalada de privilegios entre 2022 y 2024. La versión actual es v2.5.4 (2026-07-01). Ejecuta la rutina de actualización del panel tras instalarlo y no lo dejes obsoleto. Estás exponiendo una UI de administración en una IP pública.
También puedes desplegar Astro en un VPS con Coolify o EasyPanel si prefieres otro panel. Para stacks pesados en Docker son buenas opciones. Para un sitio Astro puramente estático, CloudPanel es el camino más simple.
Si quieres monitorizar CPU, memoria y espacio en disco de tu servidor, mira: Cómo monitorizar recursos de servidor y Docker
Videoguía
El vídeo muestra una UI anterior de CloudPanel
La videoguía se grabó en 2023. El flujo es el mismo, pero la UI de CloudPanel v2.5.x difiere en algunos puntos. Los pasos escritos de abajo están al día para CloudPanel v2.5.4 (2026-07-01). Fíate de ellos si las capturas no coinciden con lo que ves.
Desplegar Astro.js en un VPS con CloudPanel
Hay dos enfoques en CloudPanel: un Static HTML site (recomendado para salida puramente estática) o un Node.js site. El enfoque Static HTML es más simple y barato de correr: CloudPanel sirve los archivos compilados directamente desde Nginx sin ningún proceso Node.js en runtime. Esta es la secuencia completa: sitio, DNS, SSL, Node para compilar, proyecto, build y automatización.
Paso 1: Añade un sitio Static HTML en CloudPanel
- Inicia sesión en tu panel de administración de CloudPanel.
- Ve a Sites > Add Site > Create a Static HTML Site. (La documentación actual de CloudPanel para todos los tipos de sitio está en cloudpanel.io/docs/v2/frontend-area/add-site/.)
- Introduce tu nombre de dominio y crea las credenciales del usuario del sitio.
- Cuando el sitio esté creado, edítalo y cambia el Root Directory para que apunte al directorio
dist:
htdocs/www.yourdomain.com/distAstro genera su build de producción en dist/ por defecto (outDir: './dist'). CloudPanel tiene que servir desde ese directorio, no desde la raíz del proyecto.
Sirve siempre desde dist/, nunca desde la raíz del proyecto
Servir la raíz del proyecto expondría tu directorio .git/, node_modules/, los archivos fuente y el .env a través de Nginx. Apunta el root directory a dist/ y nada más será accesible. Si obtienes un 403 o un 404 tras un build “correcto”, este ajuste es lo primero que debes revisar.

CloudPanel también crea la redirección www↔non-www y fuerza HTTP→HTTPS por ti. No necesitas escribir esas reglas a mano.
Paso 2: Apunta el DNS a tu VPS
Añade un registro A en tu proveedor de DNS apuntando tu dominio a la dirección IP del VPS. Si usas Cloudflare, añade el registro A allí y activa el proxy para las ventajas del CDN y la protección DDoS.
dig +short www.yourdomain.com
# With Cloudflare proxy on, you'll see Cloudflare IPs (that's expected)
# With proxy off (DNS only), you should see your VPS IP
Configura el SSL/TLS de Cloudflare en Full (strict)
Con un certificado Let’s Encrypt en el origen (siguiente paso) y Cloudflare delante, pon el modo SSL/TLS en Full (strict) en el dashboard de Cloudflare. El modo Flexible por defecto hace que Cloudflare hable HTTP con tu origen mientras sirve HTTPS a los visitantes. Eso provoca bucles de redirección con las reglas de HTTPS forzado de Nginx, o errores 522/525. Full (strict) verifica el certificado del origen y el bucle desaparece.
Paso 3: Genera un certificado SSL de Let’s Encrypt
En CloudPanel, ve a la sección SSL/TLS de tu sitio y haz clic en New Let’s Encrypt Certificate. CloudPanel gestiona la generación del certificado y la configuración de Nginx automáticamente.
Verifícalo antes de seguir:
curl -I https://www.yourdomain.com
# Expect: HTTP/2 200 (the CloudPanel placeholder page is fine at this stage)
curl -I http://www.yourdomain.com
# Expect: 301 redirect to https://www.yourdomain.comSi curl te da un aviso de certificado, el certificado no se emitió. Comprueba que el registro DNS del Paso 2 ya resuelve antes de reintentar.
Paso 4: Instala Node.js 24 LTS con NVM
Astro necesita Node.js para compilar el sitio. CloudPanel crea usuarios de Linux aislados por sitio, así que instala Node.js bajo el usuario del sitio, no como root. Entra por SSH a tu VPS y cambia al usuario del sitio:
ssh root@your-server-ip
sudo su - www.yourdomain.comInstala NVM (Node Version Manager). La v0.40.8 es la versión actual a septiembre de 2026:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.8/install.sh | bash
source ~/.bashrcInstala Node.js 24, la línea LTS activa:
nvm install 24
nvm alias default 24Verifica la instalación:
node -v
# Should output v24.x.x
nvm ls
# Should show v24.x.x as defaultAstro 7 necesita Node >= 22.12.0
La línea de versiones actual de Astro (7.x, 7.3.5 en npm a octubre de 2026) requiere node >=22.12.0. Node 24 lo cumple y tiene soporte hasta 2028-04-30. Node 22 aún funciona (LTS de mantenimiento hasta 2027-04-30). nvm install 22 instala el 22.x más reciente, que supera el mínimo de 22.12.0, pero 24 te da un año extra de soporte. Instala 24 salvo que tengas una razón para no hacerlo.
Paso 5: Clona y configura tu proyecto Astro
Elimina los archivos de ejemplo que CloudPanel crea por defecto y coloca tu proyecto. El nombre del directorio debe coincidir con lo que CloudPanel espera (www.yourdomain.com).
Clonar un repo existente
cd htdocs
rm -rf www.yourdomain.com
git clone [email protected]:your-username/your-astro-repo.git www.yourdomain.com
cd www.yourdomain.com
npm installPara un repo privado, [email protected]:... necesita una clave SSH para el usuario del sitio. Crea una y añádela al repo como deploy key de solo lectura:
ssh-keygen -t ed25519 -C "deploy-www.yourdomain.com"
cat ~/.ssh/id_ed25519.pub
# Copy the output, then in GitHub: repo Settings > Deploy keys > Add deploy key
# Paste it and leave "Allow write access" uncheckedSi necesitas una guía más detallada de claves SSH con GitHub, mira cómo vincular GitHub con una clave SSH.
Crear un proyecto nuevo
cd htdocs
rm -rf www.yourdomain.com
npm create astro@latest www.yourdomain.com
cd www.yourdomain.com
npm installEsto sigue generando proyectos Astro 7 correctamente. Para un tema de blog ya hecho, mira Bitdoze Astro Theme o AstroWind.
¿Permission denied (publickey)?
Ese error en git clone o git pull significa que el usuario del sitio no tiene ninguna clave SSH registrada en GitHub. Los pasos de la deploy key de arriba son la solución. Prueba con ssh -T [email protected] como usuario del sitio. Deberías ver “Hi username/repo! You’ve successfully authenticated”.
Paso 6: Compila el sitio estático de Astro
Cuando tu sitio esté configurado y el contenido en su lugar, compila la versión de producción:
npm run buildEsto genera los archivos estáticos en dist/. Como el root directory de CloudPanel ya apunta a dist/, el sitio entra en producción en el momento en que termina el build.
Verifica:
curl -I https://www.yourdomain.com
# Expect: HTTP/2 200 and content-type: text/html
curl -I https://www.yourdomain.com/_astro/*.css
# Expect: 200. Astro emits hashed assets under /_astro/¿OOM-killed en un VPS de 1 GB?
npm install y los builds de Astro pueden consumir más de 1 GB de RAM, y el OOM killer del kernel abortará el build encantado. Redimensiona a 2 GB o añade de 1 a 2 GB de swap primero:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstabLos builds más rápidos de Astro 7 (de un 15 a un 61 %, nuestro benchmark de builds de Astro 7) acortan la ventana pero no eliminan el mínimo de memoria. Para sitios pesados, mira optimización de la velocidad de build de Astro.
¿Recompilando un sitio viejo de Astro 4/5/6 en Astro 7?
El nuevo compilador Rust de Astro 7 ya no corrige el markup silenciosamente. Las etiquetas sin cerrar y los atributos sin terminar ahora son errores de build duros, y los espacios en blanco entre elementos inline se colapsan al estilo JSX (los saltos de línea ya no se renderizan como un espacio; usa { ' ' } donde necesites uno). Si te encuentras un muro de errores de markup después de que npm install trajera Astro 7, ese es el motivo. Ruta de actualización: npx @astrojs/upgrade, y luego corrige las líneas reportadas.
Paso 7: Automatiza rebuilds y despliegues
Hacer pull y build a mano cansa al tercer push de contenido. Todo el pipeline es pequeño:
Escribe un script de deploy mínimo como usuario del sitio, en ~/deploy.sh:
#!/usr/bin/env bash
set -euo pipefail
cd ~/htdocs/www.yourdomain.com
git pull
npm ci
npm run buildchmod +x ~/deploy.shUsa npm ci en lugar de npm install. Instala exactamente lo que hay en package-lock.json, así que un rebuild mañana se comporta como el rebuild de hoy. Ahora elige un disparador:
Cron de CloudPanel
En CloudPanel, ve a Cron Jobs del usuario del sitio y ejecuta el script en un horario, por ejemplo cada 5 minutos:
*/5 * * * * /home/www.yourdomain.com/deploy.sh >> /home/www.yourdomain.com/deploy.log 2>&1Para evitar rebuilds innecesarios, añade un check de fetch al principio del script:
cd ~/htdocs/www.yourdomain.com
git fetch -q
[ "$(git rev-parse HEAD)" = "$(git rev-parse @{u})" ] && exit 0El build solo corre cuando el remoto tiene commits nuevos. Tosco, fiable, sin puertos de entrada.
Webhook de GitHub
Añade un webhook en GitHub (Settings > Webhooks del repo): URL de payload apuntando a un listener mínimo en el VPS que ejecuta deploy.sh, content type application/json, evento “Just the push event”.
El listener puede ser un servicio Python de 20 líneas o un script de shell tras un endpoint desechable. Apúntalo a una ruta que no sea el vhost de tu sitio web y ponle un secreto compartido. Si no, cualquiera que encuentre la URL puede disparar builds en tu servidor. Las deploy keys son de solo lectura; el listener del webhook es la única superficie de entrada que añades.
DPLOY
CloudPanel incluye una herramienta de despliegue nativa de Git, DPLOY. Haces push a una rama, DPLOY hace pull y ejecuta tu comando de build. Es la opción “nativa” si quieres que el panel sea dueño del flujo de deploy en lugar de cron más un script de shell.
Revisa la página de docs para los pasos de instalación actuales. La documentación sigue activa y corresponde a la v2.
Uses el disparador que uses: la salida del build acaba en los logs de cron o en el journal del webhook. Cuando un deploy “silenciosamente” no ocurre, ese log es el primer sitio donde mirar. El script es también donde se engancha la salvaguarda de rollback (lo vemos a continuación).
DigitalOcean 100 $ gratis Vultr 100 $ gratis Hetzner 20 € gratis Hostinger VPSRevertir un deploy fallido
npm run build vacía dist/ antes de escribir la salida nueva. Si el build falla a medias (error de markup, OOM kill, dependencia rota), puedes quedarte sirviendo nada. La solución es aburrida: guarda el build bueno anterior hasta que el nuevo esté probado.
Extiende el script de deploy con el intercambio:
#!/usr/bin/env bash
set -euo pipefail
cd ~/htdocs/www.yourdomain.com
git pull
npm ci
# Keep the previous build until the new one is proven
if [ -d dist ]; then
rm -rf dist.last-known-good
mv dist dist.last-known-good
fi
if npm run build && [ -f dist/index.html ]; then
rm -rf dist.last-known-good
else
echo "Build failed or produced no index.html, restoring previous dist" >&2
if [ -d dist.last-known-good ]; then
rm -rf dist
mv dist.last-known-good dist
fi
exit 1
fiLa comprobación [ -f dist/index.html ] atrapa el peor caso: un build que sale con código 0 pero emite un árbol de salida vacío o incorrecto. Si falla, el backup vuelve a su sitio y Nginx sigue sirviendo la versión anterior.
Esto es una estrategia de “última salida estática buena conocida”, no despliegues versionados. Para un sitio estático en solitario es suficiente: el tiempo de restauración es un mv, y el único estado que importa (el repo git) está en otra parte.
Verifica el despliegue y configura las cabeceras de caché
Ejecuta este checklist tras el primer deploy y tras cada rebuild. Lleva 30 segundos y atrapa la mayoría de lo que se rompe:
curl -I https://www.yourdomain.comdevuelve 200 concontent-type: text/html- Un asset hasheado carga:
curl -I https://www.yourdomain.com/_astro/*.cssdevuelve 200 curl -I http://www.yourdomain.comdevuelve un 301 a HTTPS- www y non-www resuelven al mismo contenido (la redirección de CloudPanel)
- Ver código fuente: la página referencia assets compilados bajo
/_astro/, no archivos fuente en crudo
Luego el caché. Astro emite archivos hasheados bajo /_astro/, así que esos se pueden cachear fuerte: Cache-Control: public, max-age=31536000, immutable. El HTML debe tener una vida corta; si no, los visitantes siguen viendo el deploy anterior tras un rebuild.
La plantilla de vhost estático de CloudPanel gestiona el serving básico, pero si quieres cabeceras explícitas y predecibles, añádelas en el editor Vhost del sitio (docs de vhost de CloudPanel):
location /_astro/ {
add_header Cache-Control "public, max-age=31536000, immutable";
}Deja el HTML con el manejo por defecto, o pon un Cache-Control corto (60 segundos es de sobra). En el lado de Cloudflare, pon Browser Cache TTL en “Respect Existing Headers” para que gane el origen. Así un rebuild se ve sin necesidad de purgar.
¿Los deploys no aparecen?
Dos sospechosos habituales: un TTL de caché de HTML largo (solución arriba), o el edge de Cloudflare aún guardando la página vieja. Purga la caché de Cloudflare para las páginas HTML tras un deploy si lo necesitas en vivo inmediatamente. Los assets de /_astro/ no necesitan purga. Sus nombres de archivo cambian cuando cambia su contenido.
Cuando el sitio esté en vivo, vigílalo: monitoriza el uptime con Beszel y Uptime Kuma y sigue los recursos del servidor. Un sitio estático también puede caerse: expiración del certificado, disco lleno, mala configuración de Nginx en la próxima edición.
Si prefieres no poner Cloudflare delante, Bunny.net funciona como CDN edge drop-in sobre el mismo origen. Pull zone apuntando a tu VPS, la misma historia de caché inmutable de /_astro/.
Solución de fallos comunes
La mayoría se arreglan en 2 minutos
Cada entrada de abajo es error → causa → solución. El recorrido completo de cada una está en el paso enlazado dentro.
git clone o git pull falla con Permission denied (publickey)
El usuario del sitio no tiene ninguna clave SSH que GitHub conozca. Genera una (ssh-keygen -t ed25519 como usuario del sitio), añade la clave pública al repo como deploy key de solo lectura y prueba con ssh -T [email protected]. Pasos completos en el Paso 5. Variante común: añadiste la clave a tu cuenta personal de GitHub pero el repo está en una organización que restringe las deploy keys. Usa una deploy key del repo en su lugar.
El build muere en un VPS pequeño (npm install o astro build)
Falta de memoria. En máquinas de 1 GB el OOM killer del kernel aborta el build sin ningún error útil de Astro. Solución: añade de 1 a 2 GB de swap (comandos en el Paso 6) o redimensiona el VPS a 2 GB. Comprueba dmesg -T | grep -i oom para confirmar que es OOM y no otra cosa. Los builds más rápidos de Astro 7 acortan la ventana pero no bajan el mínimo de memoria.
Bucle de redirección o errores 522/525 tras Cloudflare
El modo SSL/TLS de Cloudflare probablemente está en Flexible, así que Cloudflare habla HTTP con tu origen mientras Nginx fuerza HTTPS. Eso es una redirección infinita. Pon SSL/TLS en Full (strict) con el certificado Let’s Encrypt en el origen. Detalles en el Paso 2.
Errores de build duros tras actualizar a Astro 7
El nuevo compilador Rust ya no corrige el markup silenciosamente: etiquetas sin cerrar y atributos sin terminar son errores de build, y los espacios en blanco inline se comportan al estilo JSX. Corrige las líneas reportadas, o ejecuta npx @astrojs/upgrade y trabaja la lista. Detalles en el Paso 6.
El sitio muestra 404 o 403 tras un build correcto
El root directory no está apuntando a dist/. En CloudPanel, edita el sitio y pon el Root Directory en htdocs/www.yourdomain.com/dist. Si el directorio es correcto y dist/index.html no existe, la salida del build fue a otra parte: revisa outDir en astro.config.mjs. Servir la raíz del proyecto en lugar de dist/ “arregla” el 404 y expone .git/. No lo hagas.
El deploy corrió pero los visitantes siguen viendo el sitio viejo
Caché. O el navegador retiene un TTL de HTML largo, o el edge de Cloudflare aún no lo ha expirado. Acorta la caché de HTML (ver la sección de verificación), purga Cloudflare tras el deploy si debe ser instantáneo, y confirma con curl -s https://www.yourdomain.com | grep -o '_astro/[^\"]*\.css' que se están sirviendo nombres de assets hasheados nuevos.
Alternativa: usa el tipo de sitio Node.js de CloudPanel
Static HTML site (recomendado)
Sirve dist/ directamente desde Nginx. Ningún proceso Node.js en runtime.
- Menor huella de memoria. Un VPS de 1 a 2 GB es de sobra
- Nada que mantener vivo (sin PM2, sin gestor de procesos)
- Rebuild con Node, serving con Nginx
El default correcto para cualquier sitio Astro puramente estático.
Node.js site
CloudPanel gestiona la versión de Node.js vía NVM y hace proxy a un puerto de la app.
- Elige Node.js version 24 LTS (soportado desde CloudPanel v2.5.4, 2026-07-01; 22 sigue seleccionable)
- Configura un puerto de app (p. ej. 3000) y corre la app con un gestor de procesos
- Necesario solo si más adelante cambias a SSR con un adapter
La misma versión de Node que instalarías a mano en el flujo estático, solo que gestionada por el panel. El coste es un proceso Node permanente consumiendo RAM 24/7.
Para un sitio puramente estático, usa el tipo Static HTML site. Siempre puedes recrear el sitio como Node.js más adelante si pasas a SSR. Es un cambio de 10 minutos. Si aún estás decidiendo el panel en general, la comparativa de mejores paneles de servidor self-hosted cubre los trade-offs.
Conclusión
Desplegar Astro en un VPS con CloudPanel es el movimiento correcto cuando te quedas corto con los límites del hosting gratuito o quieres control sobre la máquina. El tipo de sitio Static HTML es su versión más simple: Nginx sirve dist/, ningún proceso Node corre en runtime, un VPS de 5 a 10 $/mes es suficiente, y los builds más rápidos de Astro 7 hacen que los rebuilds en esa máquina pequeña duelan menos. Añade el script de deploy, el intercambio de dist.last-known-good y el checklist de verificación, y tendrás una ruta de deploy en la que puedes confiar a la 1 de la madrugada.
Un repaso de seguridad: mantén CloudPanel actualizado. El panel corre con privilegios reales en tu servidor y el changelog muestra el historial de CVEs que demuestra que importa.
DigitalOcean 100 $ gratis Vultr 100 $ gratis Hetzner 20 € gratis Hostinger VPSSi quieres un panel web que también funcione como reverse proxy para contenedores Docker, mira este curso:
Curso de configuración de CloudPanelAdónde ir después:
- Añade un formulario de contacto a tu sitio Astro (gratis, sin backend)
- Crea un blog Astro gratis en Cloudflare si quieres la ruta sin servidor
- Despliega Astro.js en Cloudflare Pages (hosting gratis, zero-config)
- Documentación de despliegue de Astro (cubre todas las plataformas soportadas)


