🇺🇸 EN
Cloud
·8 min read·↗·🇺🇸 EN

De Vercel Next.js a Google Cloud Run: Guía de costos y arquitectura

Portada principal del artículo: De Vercel Next.js a Google Cloud Run: Guía de costos y arquitectura

Seamos honestos: me encanta Vercel. Es una plataforma increíble. La experiencia de desarrollo es sin duda una de las mejores que puedes encontrar en el desarrollo web moderno. Si estás empezando un proyecto nuevo o necesitas avanzar rápido, la sigo recomendando sin dudarlo.

Sin embargo, a medida que empecé a alojar más proyectos activos (como herramientas personales, proyectos secundarios de clientes y el sitio web de mi hermana), mi factura mensual empezó a subir. Esos costos imprevistos por ejecución en el edge y exceso de ancho de banda pueden ser una sorpresa desagradable a fin de mes.

Como trabajo a diario con Google Cloud Platform (GCP) en entornos empresariales, decidí que era momento de migrar mi blog y mis aplicaciones secundarias a Google Cloud Run. Quería control total sobre la arquitectura, cero dependencia de un solo proveedor y costos de alojamiento predecibles de $0.

Aquí tienes el recorrido técnico paso a paso de cómo lo hice, de desarrollador a desarrollador.

Empecemos por empaquetar nuestra aplicación de Next.js en un contenedor ligero y listo para producción.


1. Preparando la compilación Standalone de Next.js 📦

El mayor error que cometen los desarrolladores al crear un contenedor para Next.js es copiar toda la carpeta node_modules dentro de Docker. Esto genera imágenes pesadas de más de 2 GB y tiempos de despliegue lentos.

Next.js incluye un modo de salida standalone integrado. Utiliza rastreo de dependencias para empaquetar únicamente los archivos necesarios para ejecutar tu aplicación en producción:

// next.config.ts
import type { NextConfig } from "next";
 
const nextConfig: NextConfig = {
  output: "standalone",
};
 
export default nextConfig;

El Dockerfile multi-etapa optimizado

Aquí tienes el Dockerfile multi-etapa probado en producción que crea una imagen final de unos 120 MB:

# 1. Dependencias base
FROM node:20-alpine AS base
RUN apk add --no-cache libc6-compat
WORKDIR /app
 
# 2. Instalación de dependencias
FROM base AS deps
COPY package.json package-lock.json* ./
RUN npm ci
 
# 3. Compilación (Builder)
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
RUN npm run build
 
# 4. Entorno de ejecución en producción (Runner)
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
 
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
 
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
 
USER nextjs
EXPOSE 3000
 
CMD ["node", "server.js"]

Ahora veamos por qué Google Cloud Run es la opción ideal para alojar este contenedor.


2. ¿Por qué Google Cloud Run? (El servicio justo a la medida) ☁️

GCP puede parecer abrumador al inicio. Tienes App Engine (rígido y anticuado), Compute Engine (demasiado mantenimiento manual de Linux) y GKE (Kubernetes es demasiado complejo para una aplicación web).

Google Cloud Run está en el punto perfecto: es una plataforma serverless de contenedores totalmente administrada que elimina la gestión de servidores y te da toda la flexibilidad de un contenedor Linux.

Las ventajas del nivel gratuito para desarrolladores

Cloud Run ofrece uno de los niveles gratuitos más generosos en la nube:

  • 2 millones de peticiones gratuitas al mes.
  • 180,000 vCPU-segundos y 360,000 GiB-segundos gratuitos al mes.
  • Escalado a cero: cuando nadie visita tu sitio, el uso de CPU baja a 0 y no cuesta nada.
  • 120 minutos de compilación al día gratis con Cloud Build.

Para un blog personal o un proyecto secundario, esto significa que tu factura mensual casi siempre será de $0.00.

Ahora veamos los comandos de despliegue para poner a funcionar tu aplicación.


3. Compilación y despliegue con Cloud Build y Artifact Registry 🚀

En lugar de construir las imágenes en tu máquina local y gastar ancho de banda de subida, usamos Google Cloud Build junto con Artifact Registry:

Paso 1: Crear un repositorio en Artifact Registry

gcloud artifacts repositories create blog-repo \
  --repository-format=docker \
  --location=us-central1 \
  --description="Next.js Docker Repository"

Paso 2: Compilar el contenedor de forma remota

gcloud builds submit \
  --tag us-central1-docker.pkg.dev/YOUR_PROJECT_ID/blog-repo/danywalls-blog .

Paso 3: Desplegar en Cloud Run

gcloud run deploy danywalls-blog \
  --image us-central1-docker.pkg.dev/YOUR_PROJECT_ID/blog-repo/danywalls-blog \
  --region us-central1 \
  --platform managed \
  --allow-unauthenticated \
  --port 3000 \
  --memory 512Mi \
  --cpu 1 \
  --min-instances 0 \
  --max-instances 5

¡Tu aplicación Next.js ya está en línea en una URL segura con HTTPS y autoescalado gestionado por Google!

A continuación, veamos cómo manejar las variables de entorno sensibles de forma segura.


4. Gestión segura de secretos con Google Secret Manager 🔐

En lugar de definir variables de entorno directamente en tus archivos YAML de despliegue o en la imagen del contenedor, guarda los valores sensibles (claves de API, URLs de bases de datos) en Google Secret Manager:

# 1. Crear el secreto
echo -n "your-secret-api-key" | gcloud secrets create RESEND_API_KEY --data-file=-
 
# 2. Dar acceso a Cloud Run para leer el secreto
gcloud secrets add-iam-policy-binding RESEND_API_KEY \
  --member="serviceAccount:YOUR_PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
  --role="roles/secretmanager.secretAccessor"
 
# 3. Montar el secreto en Cloud Run
gcloud run services update danywalls-blog \
  --region us-central1 \
  --set-secrets=RESEND_API_KEY=RESEND_API_KEY:latest

Esto mantiene tus credenciales totalmente separadas de los commits de código y de los artefactos de compilación.

Ahora pasemos a configurar tu dominio personalizado y el enrutamiento DNS.


5. Dominios personalizados, DNS en Cloudflare y redirecciones WWW 🌐

Mi blog utiliza tanto danywalls.dev como danywalls.com. Para conectar tu dominio personalizado, puedes usar Domain Mappings en Cloud Run:

gcloud beta run domain-mappings create --service danywalls-blog --domain danywalls.com

Google te entregará una lista de registros A y AAAA. Como utilizo Cloudflare para gestionar mis DNS, agregué esos registros directamente en Cloudflare.

Manejo de redirección WWW y URLs canónicas

Un problema común después de salir de Vercel es que www.danywalls.com no resuelve de forma automática. A diferencia de Vercel, Cloud Run trata los subdominios como entidades independientes.

Para solucionarlo:

  1. Agrega un Domain Mapping en Cloud Run para www.danywalls.com (o crea un registro CNAME que apunte a ghs.googlehosted.com).
  2. Crea una regla de redirección en Cloudflare: define una regla de redirección 301 que coincida con https://www.danywalls.com/* y redirija a https://danywalls.com/$1. Esto asegura que los motores de búsqueda indexen una única URL canónica y protege la autoridad SEO de tu sitio.

Ahora vamos a automatizar todo este flujo con GitHub Actions.


6. Despliegue continuo con GitHub Actions 🤖

Para mantener el flujo de trabajo cómodo de hacer un simple git push para desplegar, puedes configurar un workflow en GitHub Actions:

# .github/workflows/deploy.yml
name: Deploy to Cloud Run
 
on:
  push:
    branches:
      - main
 
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4
 
      - name: Authenticate with Google Cloud
        uses: google-github-actions/auth@v2
        with:
          credentials_json: ${{ secrets.GCP_SA_KEY }}
 
      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@v2
 
      - name: Build and Push Container
        run: |
          gcloud builds submit \
            --tag us-central1-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/blog-repo/danywalls-blog .
 
      - name: Deploy Revision to Cloud Run
        run: |
          gcloud run deploy danywalls-blog \
            --image us-central1-docker.pkg.dev/${{ secrets.GCP_PROJECT_ID }}/blog-repo/danywalls-blog \
            --region us-central1 \
            --platform managed

Cada commit enviado a la rama main compila automáticamente en GCP y activa una actualización progresiva sin tiempo de inactividad.

Revisemos las diferencias de arquitectura entre ambas plataformas.


Vercel vs. Google Cloud Run: Comparación de características ⚖️

CaracterísticaVercel (Hobby)Google Cloud Run
Peticiones gratuitas al mes1 millón2 millones
Tiempo máx. de ejecución de función10 a 60 segundosHasta 60 minutos
Minutos de compilación45 min / mes120 min / día
Control del entorno de ejecuciónServerless en Edge / NodeContenedor Linux con Docker completo
Complejidad de configuraciónConfiguración ceroDockerfile inicial y configuración de CLI
Portabilidad entre proveedoresEcosistema de VercelCualquier plataforma de contenedores (AWS, Fly, GCP)

Resumen y próximos pasos 🛠️

Migrar mi sitio de Next.js a Google Cloud Run me dejó tres grandes beneficios:

  1. Facturas predecibles de $0: el nivel gratuito maneja sin problemas decenas de miles de visitantes mensuales en varios sitios.
  2. Verdadera portabilidad con contenedores: la imagen de Docker corre de forma idéntica en local, en entornos de pruebas y en cualquier proveedor de nube.
  3. Experiencia DevOps empresarial: gestión limpia de secretos, compilación remota con Cloud Build y control total sobre la infraestructura.

[!TIP] Siguiente en la serie: ¿Listo para producción? Lee la parte 2: Next.js en Google Cloud Run: Caching en producción, secretos y cero arranques en frío, donde explico cómo usar Cloud CDN para caché en el edge, Google Secret Manager y CI/CD automatizado con Cloud Build.

Si estás ampliando tu configuración de nube e infraestructura, revisa mis artículos sobre Cómo solucionar el spam de newsletters con Cloudflare y la Guía paso a paso de Docker para principiantes.

¡A seguir construyendo!

Parte de la serie Cloud

Explora más guías prácticas y arquitecturas reales en la serie Cloud.

Ver serie completa

Preguntas Frecuentes

¿Por qué migrar una aplicación Next.js de Vercel a Google Cloud Run?

Google Cloud Run ofrece un nivel gratuito generoso (2 millones de peticiones al mes, 180,000 vCPU-segundos), elimina los límites estrictos de tiempo de espera serverless (hasta 60 minutos de ejecución), ofrece 120 minutos de compilación gratuitos al día mediante Cloud Build y evita sorpresas en la factura por ancho de banda o funciones edge en proyectos personales o de clientes.

¿Qué es el modo de salida standalone de Next.js y por qué se necesita para Docker?

El modo standalone (output: 'standalone' en next.config.ts) analiza y empaqueta de forma automática solo las dependencias de producción necesarias en la carpeta .next/standalone, reduciendo el tamaño de la imagen del contenedor de varios gigabytes a cerca de 100 MB.

¿Cómo gestionar variables de entorno y claves de API de forma segura en Cloud Run?

Guarda tus claves sensibles en Google Secret Manager y conéctalas directamente a tu servicio de Cloud Run mediante la opción --set-secrets, otorgando a tu cuenta de servicio el rol 'Secret Manager Secret Accessor' sin incluir secretos dentro de las imágenes de Docker.

¿Cómo gestionar dominios personalizados y redirecciones www en Cloud Run?

Asocia tu dominio personalizado usando Domain Mappings de Cloud Run o Cloud Load Balancing, configura tus registros DNS en Cloudflare y crea una regla de redirección en Cloudflare (por ejemplo, una redirección 301 de www.* a la raíz) para mantener URLs canónicas consistentes para SEO.

Artículos Relacionados

Compartir este artículo

Si esta guía te resultó útil, compártela con tu equipo o con otros desarrolladores.


Software real. Lecciones reales.

Comparto las lecciones que aprendí por las malas, para que puedas evitarlas o estar preparado cuando ocurran.

User avatar
User avatar
User avatar
User avatar
+13K

Únete a 13,800+ desarrolladores y lectores.

Cero spam. Cancela tu suscripción en cualquier momento.