{"id":7256,"date":"2025-11-04T22:48:07","date_gmt":"2025-11-04T21:48:07","guid":{"rendered":"https:\/\/www.hostingtg.com\/blog\/?p=7256"},"modified":"2025-11-04T22:48:15","modified_gmt":"2025-11-04T21:48:15","slug":"next-js","status":"publish","type":"post","link":"https:\/\/www.hostingtg.com\/blog\/next-js\/","title":{"rendered":"Next.js con Easypanel: gu\u00eda pr\u00e1ctica de despliegue"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Por qu\u00e9 Next.js + Easypanel<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Si hoy tuviera que montar una app que pueda crecer de landing a SaaS serio sin rehacer el stack, empezar\u00eda por aqu\u00ed. Next.js me da ese equilibrio entre libertad y productividad: <strong>pongo el archivo en la carpeta correcta y ya tengo ruta<\/strong>; no me peleo con configuraciones kilom\u00e9tricas ni routers extra. En mi experiencia, eso acelera al equipo porque la estructura por convenciones minimiza decisiones triviales y te deja foco para el negocio. Easypanel, por su parte, quita fricci\u00f3n al despliegue: repositorio, build, variables, dominio y listo. Esa suma hace que pasar de \u201cfunciona en local\u201d a \u201cest\u00e1 en producci\u00f3n\u201d sea un viaje corto y predecible.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img fetchpriority=\"high\" decoding=\"async\" width=\"900\" height=\"402\" src=\"https:\/\/www.hostingtg.com\/blog\/wp-content\/uploads\/2025\/09\/servidores-vps-easypanel.webp\" alt=\"servidores vps easypanel\" class=\"wp-image-6996\" title=\"\"><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Adem\u00e1s, Next.js no se siente \u201cpesado\u201d. Si quiero algo simple, puedo. Si necesito algo enterprise (SSR con datos, ISR, middlewares, Server Actions, im\u00e1genes optimizadas, internacionalizaci\u00f3n\u2026), tambi\u00e9n. Ah\u00ed Easypanel acompa\u00f1a bien porque te permite <strong>elegir c\u00f3mo construir<\/strong> (Nixpacks o Dockerfile) y c\u00f3mo <strong>ejecutar<\/strong> (contenedor con la versi\u00f3n de Node que necesites, secrets separados por entorno, dominios con SSL en 1\u20132 clics, y despliegues conectados al repositorio). El resultado: menos tiempo en infraestructura reactiva y m\u00e1s tiempo donde realmente se compite \u2014 producto, performance y UX.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Mi regla: si el proyecto es est\u00e1ndar y no tiene dependencias nativas raras, empiezo con Nixpacks (r\u00e1pido, sin escribir Docker). Si necesito control total, monorepo complejo o binarios del sistema, voy a Dockerfile. Veremos ambos caminos con detalle, m\u00e1s CI\/CD, logs, SSR\/ISR y un checklist final para salir a producci\u00f3n con confianza.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Requisitos y decisiones previas<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Antes de pulsar \u201cDeploy\u201d, cierra estas casillas:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Versiones y runtime.<\/strong> Elige Node LTS (por ejemplo 18 o 20) y bloquea el gestor de paquetes (npm, yarn o pnpm) con su lockfile. Define los scripts:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>\"build\": \"next build\"<\/code><\/li>\n\n\n\n<li><code>\"start\": \"next start -p $PORT\"<\/code> (el puerto suele venir del entorno)<\/li>\n\n\n\n<li>Opcional: <code>\"postinstall\": \"next telemetry disable || true\"<\/code> para pipelines limpios.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Estructura del proyecto.<\/strong> App Router (<code>\/app<\/code>) recomendado para proyectos nuevos. Mant\u00e9n <code>next.config.js<\/code> lo m\u00e1s simple posible y activa <code>output: \"standalone\"<\/code> si vas a Docker (lo usaremos m\u00e1s abajo).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Archivos est\u00e1ticos e im\u00e1genes.<\/strong> Aseg\u00farate de configurar dominios permitidos en <code>images.domains<\/code> y revisa si habr\u00e1 assets grandes (sirve desde \/public o desde un storage\/CDN). Si usar\u00e1s ISR, piensa en periodos de revalidaci\u00f3n y etiquetas (<code>revalidateTag<\/code>\/<code>revalidatePath<\/code>).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Entornos y secrets.<\/strong> Define las variables m\u00ednimas (ejemplos: <code>NEXT_PUBLIC_APP_URL<\/code>, <code>DATABASE_URL<\/code>, <code>NEXTAUTH_URL<\/code>, <code>NEXTAUTH_SECRET<\/code>, claves de proveedores OAuth\/SMTP, tokens de terceros). Cada entorno (desarrollo, staging, producci\u00f3n) debe tener su set independiente en el panel.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Build method.<\/strong> Decide <strong>Nixpacks<\/strong> (cero Docker, r\u00e1pido) o <strong>Dockerfile<\/strong> (control total). Si vienes de monorepo o usas dependencias nativas (Sharp, librer\u00edas de compresi\u00f3n, etc.) y quieres cache fino, Dockerfile suele ser mejor.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Dominio.<\/strong> Piensa si lanzar\u00e1s primero sobre un subdominio de staging y luego har\u00e1s el switch al apex. Esto simplifica pruebas y evita cache \u201cpegajoso\u201d en producci\u00f3n durante el lanzamiento.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En mi caso, esta fase previa es donde se gana velocidad m\u00e1s adelante: cuantas menos sorpresas con scripts, versiones y variables, m\u00e1s fluido es todo el ciclo. La filosof\u00eda Next.js de \u201ctodo montado\u201d te permite dedicar estas decisiones al <strong>c\u00f3mo<\/strong> quieres operar, no a pelearte con los cimientos.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Opci\u00f3n 1: Nixpacks para Next.js (cu\u00e1ndo elegirlo, configuraci\u00f3n y l\u00edmites)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Cu\u00e1ndo elegir Nixpacks.<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Proyecto Next.js \u201cnormal\u201d con Node puro, sin dependencias del sistema complicadas.<\/li>\n\n\n\n<li>Quieres ir r\u00e1pido y no escribir Dockerfile.<\/li>\n\n\n\n<li>Repositorio simple (no monorepo) o monorepo donde puedas especificar <code>root<\/code> f\u00e1cilmente.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>C\u00f3mo funciona a grandes rasgos.<\/strong> Nixpacks detecta el tipo de proyecto, instala Node, el gestor de paquetes, ejecuta <code>install<\/code> y <code>build<\/code>, y arranca la app con un comando deducido (puedes sobrescribirlo). Lo interesante es que optimiza la imagen final sin que t\u00fa te metas en multi-stage.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Buenas pr\u00e1cticas.<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Asegura que el <code>start<\/code> escuche en <code>$PORT<\/code>.<\/li>\n\n\n\n<li>Si usas <code>pnpm<\/code>, mant\u00e9n el <code>pnpm-lock.yaml<\/code> actualizado para cache efectivo.<\/li>\n\n\n\n<li>Si usas im\u00e1genes remotas con <code>next\/image<\/code>, verifica que <code>images.domains<\/code> est\u00e9 correcto; fallos aqu\u00ed se ven como 404 o errores en producci\u00f3n.<\/li>\n\n\n\n<li>En App Router, marca <code>revalidate<\/code> a nivel de fetch o de ruta si deseas ISR; si no, tendr\u00e1s SSR por defecto seg\u00fan el tipo de data fetching.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>L\u00edmites y se\u00f1ales de cambio a Dockerfile.<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Necesitas instalar paquetes del sistema (por ejemplo <code>libvips<\/code> espec\u00edfico para Sharp) o una versi\u00f3n concreta poco com\u00fan.<\/li>\n\n\n\n<li>Monorepo complejo con filtros de build avanzados.<\/li>\n\n\n\n<li>Requieres caches finos por etapa, herramientas adicionales (por ejemplo Playwright para pruebas en build), o un <code>entrypoint<\/code> muy custom.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">En muchos proyectos he empezado con Nixpacks por la <strong>rapidez<\/strong>: repositorio, variables, dominio, deploy\u2026 y a producci\u00f3n. Cuando el proyecto crece (m\u00e1s servicios, colas, jobs, workers, edge\u2026), salto a Docker para tener control quir\u00fargico.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Opci\u00f3n 2: Dockerfile para Next.js (multi-stage, cach\u00e9s y <code>output: standalone<\/code>)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Cuando necesitas control absoluto, Dockerfile te lo da. La receta moderna para Next.js pasa por <strong>multi-stage<\/strong>: una etapa de build (con todas las dependencias para compilar) y otra de runtime (ligera).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Ejemplo base (Node 20 + pnpm):<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Etapa de build\nFROM node:20-slim AS builder\nWORKDIR \/app\n\n# Dependencias de sistema (si usas Sharp u otros binarios, a\u00f1ade aqu\u00ed)\nRUN apt-get update &amp;&amp; apt-get install -y --no-install-recommends \\\n  ca-certificates openssl git \\\n  &amp;&amp; rm -rf \/var\/lib\/apt\/lists\/*\n\n# PNPM (opcional)\nRUN corepack enable\n\n# Copia e instala\nCOPY package.json pnpm-lock.yaml .\/\nRUN pnpm install --frozen-lockfile\n\n# Copia resto y build\nCOPY . .\n# Recomendado para Docker: standalone\n# next.config.js => module.exports = { output: 'standalone' }\nRUN pnpm build\n\n# Etapa de runtime\nFROM node:20-slim AS runner\nWORKDIR \/app\nENV NODE_ENV=production\n# Usuario no root (opcional)\nRUN useradd -m nextjs\nCOPY --from=builder \/app\/.next\/standalone .\/ \nCOPY --from=builder \/app\/public .\/public\nCOPY --from=builder \/app\/.next\/static .\/.next\/static\n\n# Puerto inyectado por la plataforma\nENV PORT=3000\nEXPOSE 3000\n\nUSER nextjs\nCMD &#91;\"node\", \"server.js\"]\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Puntos clave.<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>output: 'standalone'<\/code> reduce la imagen final, copiando solo lo necesario para ejecutar.<\/li>\n\n\n\n<li>Si usas <code>sharp<\/code> u otra lib nativa, instala paquetes del sistema en la etapa de build.<\/li>\n\n\n\n<li>Cache: copia los lockfiles y ejecuta <code>install<\/code> antes de copiar el resto del c\u00f3digo para aprovechar capas.<\/li>\n\n\n\n<li>En monorepo, usa <code>WORKDIR<\/code> y <code>COPY<\/code> dirigidos a tu <code>apps\/web<\/code> (por ejemplo) y controla qu\u00e9 se copia con <code>.dockerignore<\/code>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Cu\u00e1ndo compensa.<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Monorepos, pipelines complejas, dependencias nativas.<\/li>\n\n\n\n<li>Necesitas reproducibilidad exacta entre entornos.<\/li>\n\n\n\n<li>Quieres optimizar tama\u00f1o de imagen, tiempos de build y caches de forma granular.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">De nuevo, Next.js no se siente pesado aqu\u00ed: con <code>standalone<\/code> el runtime queda limpio y el arranque es predecible. Esa sensaci\u00f3n de \u201cel framework no te encierra\u201d es la que me hace c\u00f3modo llevando este enfoque a proyectos serios.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Variables de entorno y secrets en Easypanel<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Un despliegue estable se sostiene en <strong>secrets bien gestionados<\/strong>. Mi check m\u00ednimo para Next.js:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>App URL:<\/strong> <code>NEXT_PUBLIC_APP_URL<\/code> (cliente) y <code>NEXTAUTH_URL<\/code> si usas NextAuth.<\/li>\n\n\n\n<li><strong>Auth:<\/strong> <code>NEXTAUTH_SECRET<\/code> o equivalente para firmar tokens.<\/li>\n\n\n\n<li><strong>Base de datos:<\/strong> <code>DATABASE_URL<\/code> (Postgres) y variables de pooling si aplican.<\/li>\n\n\n\n<li><strong>Terceros:<\/strong> claves OAuth (Google, GitHub\u2026), SMTP para emails, storage, analytics.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Buenas pr\u00e1cticas:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Nada de <code>.env<\/code> en el repo.<\/strong> Sube los valores al panel por entorno.<\/li>\n\n\n\n<li><strong>Rotaci\u00f3n peri\u00f3dica.<\/strong> Cambia claves sensibles y prueba el rollback antes.<\/li>\n\n\n\n<li><strong>Separaci\u00f3n de entornos.<\/strong> Staging y prod con valores distintos; evita usar la base de datos de producci\u00f3n en staging.<\/li>\n\n\n\n<li><strong>Flags de features.<\/strong> Controla lanzamientos con variables booleanas o de porcentaje para no depender de deployments para cada experimento.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Con esto, cada \u201cpush\u201d a la rama principal no rompe porque un secreto faltaba. En mi experiencia, esta disciplina quita tickets de emergencia y deja que el equipo se concentre en lo que importa.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Dominios y SSL (Let\u2019s Encrypt) + redirecciones<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Conecta tu dominio al servicio de la app y <strong>emite SSL<\/strong> (Let\u2019s Encrypt suele ser autom\u00e1tico). Recomendaciones:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Apex vs <code>www<\/code>.<\/strong> Elige uno como can\u00f3nico. Si el can\u00f3nico es apex (<code>tudominio.com<\/code>), redirige <code>www<\/code> \u2192 apex con 301.<\/li>\n\n\n\n<li><strong>HTTPS forzado.<\/strong> Activa HSTS y redirecci\u00f3n de HTTP \u2192 HTTPS.<\/li>\n\n\n\n<li><strong>Subdominios por entorno.<\/strong> <code>staging.tudominio.com<\/code> o <code>preview-pr-123.tudominio.com<\/code> ayudan a QA y demo sin tocar producci\u00f3n.<\/li>\n\n\n\n<li><strong>Rutas cr\u00edticas.<\/strong> Aseg\u00farate de que <code>\/api\/*<\/code> no quede tras redirecci\u00f3n err\u00f3nea ni rompa CORS si tienes servicios externos.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Este paso es r\u00e1pido, pero es crucial para Core Web Vitals (evitas hops extra), SEO (can\u00f3nico claro) y seguridad. Tambi\u00e9n es el momento ideal para configurar <strong>redirecciones<\/strong> desde proyectos antiguos o landings temporales.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">7) Bases de datos y servicios externos (Postgres\/Redis)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Si tu Next.js usa base de datos (muy probable), con\u00e9ctala as\u00ed:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>DATABASE_URL<\/code><\/strong> con SSL habilitado si el proveedor lo exige.<\/li>\n\n\n\n<li><strong>Pooling.<\/strong> Usa un pool (por ejemplo pgbouncer o el pool del ORM) en SSR para no agotar conexiones.<\/li>\n\n\n\n<li><strong>Migraciones.<\/strong> Automatiza <code>prisma migrate deploy<\/code> o herramienta equivalente en el build o en un job post-deploy.<\/li>\n\n\n\n<li><strong>Backups y retenci\u00f3n.<\/strong> Define frecuencia, retenci\u00f3n y restauraciones de prueba (un backup que nunca has probado es un backup te\u00f3rico).<\/li>\n\n\n\n<li><strong>Redis \/ cach\u00e9s.<\/strong> Si vas a usar ISR con invalidaciones frecuentes, Redis puede servir para coordinar se\u00f1ales o throttling.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Cuida los timeouts y el tama\u00f1o m\u00e1ximo de cuerpo (<code>bodyParser<\/code>) si tu app maneja cargas de archivos o webhooks grandes. Tambi\u00e9n revisa que los <strong>webhooks de terceros<\/strong> (Stripe, GitHub, etc.) apunten a la URL p\u00fablica correcta tras cada cambio de dominio.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">CI\/CD con GitHub: auto-deploy y rollback<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">La magia viene cuando el servidor \u201cse despliega solo\u201d al hacer push a <code>main<\/code>. Flujo t\u00edpico:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Git conectado.<\/strong> Vinculas el repo y seleccionas la rama de producci\u00f3n.<\/li>\n\n\n\n<li><strong>Previews.<\/strong> Opcionalmente, cada PR genera un despliegue temporal para QA (con su URL).<\/li>\n\n\n\n<li><strong>Auto-deploy en <code>main<\/code>.<\/strong> Al mergear, se dispara el build (Nixpacks o Docker) y el lanzamiento.<\/li>\n\n\n\n<li><strong>Rollback r\u00e1pido.<\/strong> Si algo va mal, vuelves a la release anterior en un clic y luego investigas con calma.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Me gusta acompa\u00f1arlo con <strong>checks de humo<\/strong>: tras el deploy, una ruta de health (<code>\/api\/health<\/code>) responde 200; si falla, alarmo y hago rollback. Con esto, el equipo no vive con miedo al \u201cdeploy del viernes\u201d. Y como Next.js abstrae mucha complejidad, <strong>te concentras en la l\u00f3gica de negocio<\/strong>, no en apagar fuegos de infraestructura.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Logs, m\u00e9tricas y salud de la app<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Si no lo ves, no lo controlas. Imprescindibles:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Logs estructurados<\/strong> (JSON o nivelados) y retenci\u00f3n al menos 7\u201314 d\u00edas.<\/li>\n\n\n\n<li><strong>M\u00e9tricas b\u00e1sicas:<\/strong> errores 4xx\/5xx, latencia p95\/p99, consumo de CPU\/memoria del contenedor.<\/li>\n\n\n\n<li><strong>Alertas:<\/strong> si los 5xx suben o la latencia se dispara, notifica a Slack\/Email.<\/li>\n\n\n\n<li><strong>Health checks:<\/strong> endpoint de salud y\/o probe de contenedor.<\/li>\n\n\n\n<li><strong>Tracing ligero:<\/strong> si usas Server Actions\/SSR con llamadas externas, a\u00f1ade un correlaci\u00f3n ID en logs para seguir una petici\u00f3n de punta a punta.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Esta visibilidad te permite reaccionar en minutos, no horas. Y cuando la app crece, ya tienes el m\u00fasculo operativo para escalar sin sorpresas.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">ISR\/SSR en producci\u00f3n: invalidaci\u00f3n y cach\u00e9<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Next.js brilla con <strong>ISR (Incremental Static Regeneration)<\/strong>: p\u00e1ginas est\u00e1ticas que se <strong>revalidan<\/strong> cada X segundos\/tags, lo que combina rendimiento y frescura. Consejos:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Elegir bien qu\u00e9 es SSR y qu\u00e9 es ISR.<\/strong> Cat\u00e1logos, art\u00edculos o landings suelen ir con ISR; dashboards y perfiles con datos frescos, SSR.<\/li>\n\n\n\n<li><strong><code>revalidateTag<\/code>\/<code>revalidatePath<\/code>.<\/strong> \u00dasalos tras cambios en CMS o acciones administrativas: cuando edito un producto, disparo la invalidaci\u00f3n exacta.<\/li>\n\n\n\n<li><strong>Cache-Control.<\/strong> Para rutas p\u00fablicas, ajusta <code>s-maxage<\/code> y <code>stale-while-revalidate<\/code> si invocas un CDN.<\/li>\n\n\n\n<li><strong>Edge vs Node.<\/strong> Si tienes l\u00f3gica simple de lectura, considera runtime edge para latencia menor; si haces operaciones pesadas\/bibliotecas nativas, mant\u00e9n Node.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">As\u00ed obtienes sensaciones de <strong>app veloz<\/strong> (LCP bajo) sin renunciar a contenido actualizado. En mi caso, esto ha sido clave para que la UX se sienta fluida sin pagar cada vista con una petici\u00f3n cara.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Errores comunes y c\u00f3mo arreglarlos<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>La app no arranca en producci\u00f3n.<\/strong> El <code>start<\/code> no usa <code>$PORT<\/code> o el <code>CMD<\/code> apunta a un archivo incorrecto en Docker. Soluci\u00f3n: <code>next start -p $PORT<\/code> o <code>node server.js<\/code> con <code>standalone<\/code>.<\/li>\n\n\n\n<li><strong>Im\u00e1genes rotas.<\/strong> Falta el dominio en <code>images.domains<\/code> o el loader. Revisa <code>next.config.js<\/code>.<\/li>\n\n\n\n<li><strong>Dependencia nativa que peta.<\/strong> En Nixpacks, migra a Docker e instala el paquete del sistema.<\/li>\n\n\n\n<li><strong>Variables de entorno faltantes.<\/strong> Producci\u00f3n no tiene los mismos <code>.env<\/code> que local. Crea una <strong>matriz por entorno<\/strong> en el panel y marca cu\u00e1les son obligatorias.<\/li>\n\n\n\n<li><strong>Tiempo de build exagerado.<\/strong> Falta cache de dependencias, lockfile desactualizado, o Docker copia todo antes de <code>install<\/code>. Reordena las capas.<\/li>\n\n\n\n<li><strong>Rutas 404 al mover de <code>pages<\/code> a <code>app<\/code>.<\/strong> Revisa anidados, layouts y middlewares; documenta el refactor para el equipo.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Aqu\u00ed es donde agradezco que Next.js <strong>no se sienta pesado<\/strong>: arreglas un punto, despliegas y listo, sin romper el resto del castillo.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Checklist publicaci\u00f3n y rendimiento<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>&#x2705; Node LTS y gestor de paquetes bloqueado<\/li>\n\n\n\n<li>&#x2705; Scripts <code>build<\/code> y <code>start<\/code> correctos<\/li>\n\n\n\n<li>&#x2705; Nixpacks o Dockerfile decidido y probado<\/li>\n\n\n\n<li>&#x2705; Variables de entorno por entorno (staging\/prod)<\/li>\n\n\n\n<li>&#x2705; Dominio can\u00f3nico y SSL activos, redirecciones 301 configuradas<\/li>\n\n\n\n<li>&#x2705; Base de datos conectada, migraciones y backups probados<\/li>\n\n\n\n<li>&#x2705; Logs, m\u00e9tricas, alertas y health checks en marcha<\/li>\n\n\n\n<li>&#x2705; ISR\/SSR definidos, invalidaciones controladas<\/li>\n\n\n\n<li>&#x2705; CI\/CD con auto-deploy y rollback verificado<\/li>\n\n\n\n<li>&#x2705; Core Web Vitals revisados (LCP, CLS, INP)<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Sobre Next.js<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Next.js y Easypanel se complementan para que pases de idea a producci\u00f3n con un <strong>camino corto y sin sobresaltos<\/strong>. En mi d\u00eda a d\u00eda, me quedo con dos verdades: la <strong>estructura por convenciones de Next.js<\/strong> te permite ir r\u00e1pido sin sentirte atrapado, y Easypanel <strong>te despeja el despliegue<\/strong> para que te concentres en el negocio. Empieza con Nixpacks si quieres velocidad y, cuando el proyecto lo pida, salta a Docker para control absoluto. A\u00f1ade CI\/CD, observabilidad y un plan claro de ISR\/SSR, y tienes una base para crecer de landing a producto serio sin rehacer nada.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">FAQs<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u00bfNixpacks o Dockerfile para Next.js en Easypanel?<\/strong><br>Nixpacks para ir r\u00e1pido en proyectos sin dependencias nativas ni monorepos complejos. Dockerfile si necesitas control, multi-stage, binarios del sistema o optimizaci\u00f3n fina.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u00bfC\u00f3mo manejo las variables y secrets?<\/strong><br>En el panel por entorno. Nada de <code>.env<\/code> en el repo. Define matriz m\u00ednima (<code>APP_URL<\/code>, <code>DATABASE_URL<\/code>, <code>NEXTAUTH_*<\/code>, proveedores externos) y rota claves sensibles con regularidad.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u00bfPuedo tener previews por PR?<\/strong><br>S\u00ed: conecta el repo y habilita despliegues por rama\/PR. Es la forma m\u00e1s segura de validar cambios con QA y stakeholders.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u00bfC\u00f3mo activo ISR sin sorpresas?<\/strong><br>Marca <code>revalidate<\/code> en las rutas adecuadas y dispara <code>revalidateTag<\/code>\/<code>revalidatePath<\/code> al publicar contenido. Combina con cach\u00e9 en CDN si aplica.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u00bfY si mi build falla por Sharp u otra nativa?<\/strong><br>Migra a Dockerfile e instala los paquetes del sistema en la etapa de build. Activa <code>output: 'standalone'<\/code> para una imagen runtime ligera.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Opini\u00f3n Personal<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Lo dir\u00e9 sin rodeos: para proyectos web serios, <strong>Next.js + Easypanel<\/strong> me ha dado la mejor relaci\u00f3n entre velocidad de desarrollo y previsibilidad en producci\u00f3n. Next.js siempre me ha parecido ese punto medio ideal entre la libertad de React puro y el \u201cya lo tengo todo montado\u201d que necesitas cuando el proyecto va en serio. Me encanta no tener que pelearme con lo b\u00e1sico: pones el archivo en la carpeta correcta y autom\u00e1ticamente tienes una ruta funcionando. Ese detalle \u2014que parece menor\u2014 reduce reuniones tontas, discusiones sobre convenciones y tickets de configuraci\u00f3n que no aportan negocio.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Por el lado del despliegue, Easypanel me ha ahorrado ese ciclo de \u201cmonta el servidor, escribe el Dockerfile perfecto, afina Nginx, cruza los dedos y reza\u201d. Aqu\u00ed el flujo es m\u00e1s directo: conecto repositorio, defino variables, elijo <strong>Nixpacks<\/strong> si quiero ir a toda pastilla o Dockerfile si necesito control milim\u00e9trico\u2026 y ya. No es magia, es eliminar fricci\u00f3n.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Lo que realmente importa cuando el reloj corre<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Cuando est\u00e1s lanzando, el tiempo que inviertes en infra <strong>compite<\/strong> con el tiempo que inviertes en producto. Next.js te deja concentrarte en la l\u00f3gica del negocio: SSR cuando toca, ISR para p\u00e1ginas que deben volar, Server Actions y rutas por archivos sin ceremonias. No se siente \u201cpesado\u201d. Si quiero hacerlo simple, puedo; si quiero hacerlo enterprise, tambi\u00e9n. Ese rango es oro para iterar r\u00e1pido sin hipotecar el futuro del proyecto.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Easypanel, por su parte, quita el eterno \u201c\u00bfqui\u00e9n se encarga del server?\u201d del medio. Conectar dominio, emitir SSL, gestionar secrets y tener un rollback decente deja de ser un mini-proyecto. Y aunque no reemplaza pr\u00e1cticas serias (logs, health checks, alertas), s\u00ed te pone lo suficiente en bandeja para no convertir cada release en una odisea.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Nixpacks vs Dockerfile: uso la navaja de Ockham<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Nixpacks<\/strong> cuando el proyecto es Next.js \u201cnormal\u201d (sin dependencias nativas raras ni monorepo complejo). Menos decisiones, menos superficie de fallo, m\u00e1s velocidad.<\/li>\n\n\n\n<li><strong>Dockerfile<\/strong> cuando necesito instalar binarios del sistema (hola, <code>sharp<\/code>), orquestar monorepos o rascar segundos de build con multi-stage y cach\u00e9 fino.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Mi regla pr\u00e1ctica: empiezo con Nixpacks para validar valor de negocio; si el proyecto crece (tr\u00e1fico, equipo, entornos), salto a Dockerfile. No al rev\u00e9s.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">D\u00f3nde este combo brilla de verdad<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Equipos peque\u00f1os\/medianos<\/strong> que quieren entregar valor cada semana sin abrir un frente de DevOps a tiempo completo.<\/li>\n\n\n\n<li><strong>Productos con contenido<\/strong> (blog, cat\u00e1logo, marketplace) donde ISR marca la diferencia en Core Web Vitals.<\/li>\n\n\n\n<li><strong>SaaS B2B<\/strong> que necesitan SSR selectivo, autenticaci\u00f3n, webhooks y un pipeline de deployments que no d\u00e9 miedo los viernes.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">En estas situaciones, la sensaci\u00f3n de \u201cpasar de funciona en local a est\u00e1 en producci\u00f3n\u201d en horas \u2014y no en d\u00edas\u2014 cambia el \u00e1nimo del equipo. Y el \u00e1nimo del equipo, cr\u00e9eme, cambia la calidad del producto.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Lo que NO compro a ciegas<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No todo es perfecto. Si vas a un <strong>monorepo grande<\/strong> con m\u00faltiples apps, workers y colas, probablemente querr\u00e1s Dockerfile desde el d\u00eda uno, pol\u00edticas de cache personalizadas y scripts de despliegue m\u00e1s granulados. Si tienes requerimientos de <strong>compliance<\/strong> (auditor\u00eda estricta de im\u00e1genes, firma, escaneo), tambi\u00e9n te tocar\u00e1 afinar el pipeline y documentar cada paso. Y si tu frontend depende de <strong>librer\u00edas nativas<\/strong> ex\u00f3ticas, no esperes que Nixpacks lo adivine todo: toca ensuciarse las manos (para eso est\u00e1 Docker).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tampoco creo que el combo substituya el criterio: <strong>variables de entorno<\/strong> bien pensadas, <strong>matriz de entornos<\/strong> (staging \u2260 producci\u00f3n), <strong>observabilidad<\/strong> m\u00ednima (logs estructurados, alertas por 5xx, probe de salud) y <strong>plan de rollback<\/strong> son innegociables. La plataforma ayuda; la disciplina la pones t\u00fa.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Por qu\u00e9 sigo volviendo a este stack<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Porque entrega lo que promete: <strong>ritmo sin deuda oculta<\/strong>. Next.js me deja construir desde landing hasta eCommerce sin sentir que el framework se me queda corto, y Easypanel me da un carril r\u00e1pido a producci\u00f3n sin atarme a una caja negra. Puedo empezar simple y subir a enterprise cuando haya tracci\u00f3n; no al rev\u00e9s. Y esa es, para m\u00ed, la diferencia entre herramientas que enamoran en una demo y herramientas que aguantan producto real.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Mi veredicto<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Si est\u00e1s entre \u201cquiero salir esta semana\u201d y \u201cquiero que esto escale si funciona\u201d, <strong>Next.js + Easypanel<\/strong> es una elecci\u00f3n muy sensata. Empezar\u00eda con Nixpacks para velocidad, organizar\u00eda bien secrets y dominios, activar\u00eda ISR donde aporte rendimiento y, cuando el proyecto lo pida, migrar\u00eda a Docker para control absoluto. No hay trucos: solo menos fricci\u00f3n y m\u00e1s foco en lo que s\u00ed mueve la aguja.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">\u00bfT\u00fa c\u00f3mo lo ves? \u00bfTe ha funcionado mejor Nixpacks o vas directo a Dockerfile? \u00bfQu\u00e9 dolores te has encontrado al desplegar Next.js? <strong>Cu\u00e9ntamelo en comentarios<\/strong>: leo y respondo, y si hay patrones comunes preparo una gu\u00eda ampliada con ejemplos pr\u00e1cticos.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Por qu\u00e9 Next.js + Easypanel Si hoy tuviera que montar una app que pueda crecer de landing a SaaS serio sin rehacer el stack, empezar\u00eda por aqu\u00ed. Next.js me da ese equilibrio entre libertad y productividad: pongo el archivo en la carpeta correcta y ya tengo ruta; no me peleo con configuraciones kilom\u00e9tricas ni routers [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":7257,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_aifi_custom_prompt":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[952],"tags":[1174,1090,867],"class_list":["post-7256","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-guias","tag-next-js","tag-python","tag-servidores-vps"],"_links":{"self":[{"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/posts\/7256","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/comments?post=7256"}],"version-history":[{"count":2,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/posts\/7256\/revisions"}],"predecessor-version":[{"id":7259,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/posts\/7256\/revisions\/7259"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/media\/7257"}],"wp:attachment":[{"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/media?parent=7256"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/categories?post=7256"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/tags?post=7256"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}