Cómo implementar una aplicación Next.js con Vultr Kubernetes Engine y Vultr Load Balancer

Introducción

Next.js es un marco React popular para desarrollar sitios web estáticos y aplicaciones web modernas. La aplicación Next.js generalmente se implementa en una plataforma sin servidor. Sin embargo, hay algunos escenarios que desea implementar en su servidor controlado y escalarlos en su infraestructura. Este tutorial explica cómo implementar una aplicación Next.js de pila completa en Vultr Kubernetes Engine. los example La aplicación está construida con Next.js y usa Prisma para conectarse con una base de datos MySQL.

Aquí hay algunas ventajas de este enfoque:

  • Implemente la aplicación Next.js como close como sea posible a la base de datos.
  • Evite el problema de los arranques en frío en el enfoque sin servidor.
  • Precios predecibles de servidores en la nube y ancho de banda en comparación con las plataformas sin servidor.

Hay tres partes separadas en este tutorial:

  • Parte 1: compilar y enviar la imagen de Docker al registro de imágenes de Docker Hub
  • Parte 2: implementar y escalar la aplicación Next.js con Vultr Kubernetes Engine
  • Parte 3: exponer la aplicación Next.js con certificados SSL seguros

requisitos previos

Antes de comenzar, debe:

  • Tener una base de datos MySQL externa
  • implementar un Clúster Vultr Kubernetes con al menos 3 nodos.
  • Configurar kubectl y git en tu máquina.
  • Instale Docker en su máquina
  • Registre una cuenta de Docker Hub para almacenar la imagen de Docker

Parte 1: compilar y enviar la imagen de Docker al registro de imágenes de Docker Hub

La aplicación Next.js utilizada en este tutorial es una aplicación de pila completa llamada next-short-urls . El código fuente de esta aplicación se puede encontrar en este repositorio . Vultr también ha archivado el repositorio aquí.

Este es un acortador de URL simple creado con Next.js, TypeScript y Prisma. Prisma es un ORM de código abierto que lo ayuda a crear y administrar la base de datos MySQL.

  1. Clonar el código fuente del example solicitud:

                              
                                $ git clone -b v1.10.0 https://github.com/quanhua92/next-short-urls
    
                              
                            
  2. Prepara un .env entorno de archivo con el siguiente contenido. Este .env El archivo se usa en la etapa de creación de la imagen de Docker para generar páginas estáticas. La imagen de Docker de producción final no se incluye en este archivo.

                              
                                DATABASE_URL="DATABASE_URL_HERE"
    SECRET_COOKIE_PASSWORD="SOME_SECRET_PASSWORD_WITH_MIN_LENGTH_32"
    AWAIT_HISTORY_UPDATE="0"
    
                              
                            

    He aquí una breve explicación del contenido de .env expediente:

    • DATABASE_URL es una cadena de conexión de base de datos que comienza con mysql://
    • SECRET_COOKIE_PASSWORD es una contraseña especificada por la aplicación con una longitud mínima de 32
    • AWAIT_HISTORY_UPDATE es una variable de entorno que necesita la aplicación.
  3. Asegúrese de que el DockerFile El archivo contiene el siguiente contenido. Este es un DockerFile de varias etapas con deps , builder y runner etapas

                              
                                # Install dependencies only when needed
    FROM node:16-alpine AS deps
    # Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
    RUN apk add --no-cache libc6-compat
    WORKDIR /app
    
    COPY package.json yarn.lock ./
    RUN yarn install --frozen-lockfile
    
    # If using npm with a `package-lock.json` comment out above and use below instead
    # COPY package.json package-lock.json / 
    # RUN npm install
    
    # Rebuild the source code only when needed
    FROM node:16-alpine AS builder
    WORKDIR /app
    COPY --from=deps /app/node_modules ./node_modules
    COPY . .
    # generate the prisma type
    RUN npx prisma generate
    
    RUN yarn build && yarn install --production --ignore-scripts --prefer-offline
    # Production image, copy all the files and run next
    FROM node:16-alpine AS runner
    WORKDIR /app
    
    ENV NODE_ENV production
    
    RUN addgroup -g 1001 -S nodejs
    RUN adduser -S nextjs -u 1001
    
    # Prepare the cache folder for next/image
    RUN mkdir -p /app/.next/cache/images && chown nextjs:nodejs /app/.next/cache/images
    VOLUME /app/.next/cache/images
    
    # You only need to copy next.config.js if you are NOT using the default configuration
    COPY --from=builder /app/next.config.js ./
    COPY --from=builder /app/public ./public
    COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
    COPY --from=builder /app/package.json ./package.json
    COPY --from=builder /app/node_modules ./node_modules
    
    USER nextjs
    
    EXPOSE 3000
    
    ENV PORT 3000
    
    # Next.js collects completely anonymous telemetry data about general usage.
    # Learn more here: https://nextjs.org/telemetry
    # Uncomment the following line in case you want to disable telemetry.
    # ENV NEXT_TELEMETRY_DISABLED 1
    CMD ["node_modules/.bin/next", "start"]
    
                              
                            

    Aquí hay algunas configuraciones que se especifican para el next-short-urls solicitud. En la etapa de constructor, RUN npx prisma generate para generar los tipos a partir del esquema Prisma. En la etapa de corredor, haz una carpeta. /app/.next/cache/images y preparar el permiso de la carpeta. Esto se usa para la función de optimización automática de imágenes en Next.js.

  4. Cree la imagen de Docker

                              
                                $ docker build . -t next-short-urls
    
                              
                            
  5. Iniciar sesión en Docker Hub

                              
                                $ docker login
    
                              
                            
  6. Etiquete la imagen de Docker con su ID de Docker Hub y envíelo a Docker Hub. Reemplazar <YOUR_DOCKER_HUB_ID> con su ID de cuenta de Docker Hub.

                              
                                $ docker tag next-short-urls <YOUR_DOCKER_HUB_ID>/next-short-urls:latest
    $ docker push <YOUR_DOCKER_HUB_ID>/next-short-urls:latest
    
                              
                            
  7. Ejecute Docker local para verificar la imagen de Docker. Navegar a https://localhost:3000 para acceder a la aplicación

                              
                                $ docker run --rm -p 3000:3000 <YOUR_DOCKER_HUB_ID>/next-short-urls
    
                              
                            
  8. (Opcional) Vaya a su panel de Docker Hub y asegúrese de que su imagen sea privada.

Parte 2: implementar y escalar la aplicación Next.js con Vultr Kubernetes Engine

En esta parte, creará un secreto que contiene sus credenciales de Docker Hub y creará una implementación para implementar algunos pods que ejecutan su aplicación Next.js.

  1. Crear nombre secreto de Docker Hub regcred . Reemplace los parámetros en el comando con sus credenciales de Docker Hub

                              
                                $ kubectl create secret docker-registry regcred 
        --docker-username=YOUR_DOCKER_HUB_USERNAME  
        --docker-password=YOUR_DOCKER_HUB_PASSWORD 
        --docker-email=YOUR_DOCKER_HUB_EMAIL
    
                              
                            
  2. Crear un archivo de manifiesto secreto secrets.yaml con los datos como los creados anteriormente .env .

                              
                                apiVersion: v1
    kind: Secret
    metadata:
      name: next-short-urls-secrets
      namespace: default
    type: Opaque
    stringData:
      DATABASE_URL: "DATABASE_URL_HERE"
      SECRET_COOKIE_PASSWORD: "SOME_SECRET_PASSWORD_WITH_MIN_LENGTH_32"
      AWAIT_HISTORY_UPDATE: "0"
    
                              
                            
  3. Ejecute el comando para crear el secreto.

                              
                                $ kubectl apply -f secrets.yaml
    
                              
                            
  4. Crear un archivo de implementación deployment.yaml con el siguiente contenido. Reemplazar <YOUR_DOCKER_HUB_ID> con su ID de cuenta de Docker Hub.

                              
                                apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: next-short-urls-deploy
    spec:
      replicas: 3
      selector:
        matchLabels:
          name: next-short-urls-app
      template:
        metadata:
          labels:
            name: next-short-urls-app
        spec:
          imagePullSecrets:
            - name: regcred
          containers:
            - name: next-short-urls
              image: <YOUR_DOCKER_HUB_ID>/next-short-urls:latest
              imagePullPolicy: Always
              ports:
                - containerPort: 3000
              envFrom:
              - secretRef:
                  name: next-short-urls-secrets
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: next-short-urls-service
    spec:
      ports:
        - name: http
          port: 80
          protocol: TCP
          targetPort: 3000
      selector:
        name: next-short-urls-app
    
                              
                            
  5. Ejecute el comando para crear la implementación y el servicio.

                              
                                $ kubectl apply -f deployment.yaml
    
                              
                            
  6. Ejecute el comando kubectl get pods para ver los pods recién creados. El resultado debería ser similar a:

                              
                                NAME                                      READY   STATUS    RESTARTS   AGE
    next-short-urls-deploy-764d658d49-26b5w   1/1     Running   0          62s
    next-short-urls-deploy-764d658d49-hql7q   1/1     Running   0          62s
    next-short-urls-deploy-764d658d49-nv6tr   1/1     Running   0          62s
    
                              
                            
  7. Ejecute el comando kubectl get services para ver el servicio recién creado. El resultado debería ser similar a:

                              
                                NAME                      TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
    kubernetes                ClusterIP   10.96.0.1      <none>        443/TCP   94m
    next-short-urls-service   ClusterIP   10.99.247.34   <none>        80/TCP    39s
    
                              
                            
  8. Escale su aplicación a 10 réplicas usando el siguiente comando.

                              
                                $ kubectl scale --replicas=10 deployment/next-short-urls-deploy
    
                              
                            
  9. Ejecute el comando kubectl get pods para ver los pods recién creados. El resultado debería ser similar a:

                              
                                NAME                                      READY   STATUS    RESTARTS   AGE
    next-short-urls-deploy-764d658d49-26b5w   1/1     Running   0          3m
    next-short-urls-deploy-764d658d49-5r25t   1/1     Running   0          25s
    next-short-urls-deploy-764d658d49-hql7q   1/1     Running   0          3m
    next-short-urls-deploy-764d658d49-j6qlf   1/1     Running   0          25s
    next-short-urls-deploy-764d658d49-lvrgp   1/1     Running   0          25s
    next-short-urls-deploy-764d658d49-nv6tr   1/1     Running   0          3m
    next-short-urls-deploy-764d658d49-vkl98   1/1     Running   0          25s
    next-short-urls-deploy-764d658d49-wkclv   1/1     Running   0          25s
    next-short-urls-deploy-764d658d49-xgzs6   1/1     Running   0          25s
    next-short-urls-deploy-764d658d49-zhcdj   1/1     Running   0          25s
    
                              
                            
  10. Realice el reenvío de puertos para acceder a su aplicación a través del servicio. Navegar a https://localhost:8080 para acceder a su aplicación.

                              
                                $ kubectl port-forward services/next-short-urls-service 8080:80
    
                              
                            

Ha implementado correctamente la aplicación Next.js con la base de datos MySQL en Vultr Kubernetes Engine con 10 réplicas en su clúster.

Parte 3: exponga la aplicación Next.js con certificados SSL seguros

En esta parte, instalará NGINX Ingress Controller y expondrá su aplicación a través de un nombre de dominio con certificados SSL seguros.

  1. Instalar ingress-nginx .

                              
                                $ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.1/deploy/static/provider/cloud/deploy.yaml 
    
                              
                            
  2. Vaya a su panel de Load Balancers en https://my.vultr.com/loadbalancers/ y obtenga la dirección IP del Load Balancer recién creado. Este es el balanceador de carga creado para el ingreso de NGINX.

  3. Cree un registro A en el DNS de su dominio que apunte a la dirección IP anterior.

  4. Instalar cert-manager para gestionar certificados SSL

                              
                                $ kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.7.0/cert-manager.yaml
    
                              
                            
  5. Crear un archivo de manifiesto letsencrypt.yaml para manejar los certificados de Let’s Encrypt. Reemplace con su correo electrónico real.

                              
                                apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: letsencrypt-staging
    spec:
      acme:
        # The ACME server URL
        server: https://acme-staging-v02.api.letsencrypt.org/directory
        preferredChain: "ISRG Root X1"
        # Email address used for ACME registration
        email: <YOUR_EMAIL>
        # Name of a secret used to store the ACME account private key
        privateKeySecretRef:
          name: letsencrypt-staging
        solvers:
          - http01:
              ingress:
                class: nginx
    ---
    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: letsencrypt-prod
    spec:
      acme:
        # The ACME server URL
        server: https://acme-v02.api.letsencrypt.org/directory
        # Email address used for ACME registration
        email: <YOUR_EMAIL>
        # Name of a secret used to store the ACME account private key
        privateKeySecretRef:
          name: letsencrypt-prod
        solvers:
          - http01:
              ingress:
                class: nginx
    
                              
                            
  6. Ejecute el comando para instalar los emisores de Let’s Encrypt anteriores.

                              
                                $ kubectl apply -f letsencrypt.yaml
    
                              
                            
  7. Crear un archivo de manifiesto de ingreso ingress.yaml con el siguiente contenido. Reemplaza con el dominio que creaste en el registro A en el paso anterior.

                              
                                apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: next-short-urls-ingress
      annotations:
        kubernetes.io/ingress.class: nginx
        cert-manager.io/cluster-issuer: letsencrypt-prod
    spec:
      tls:
        - secretName: next-short-urls-tls
          hosts:
            - <YOUR_DOMAIN>
      rules:
        - host: <YOUR_DOMAIN>
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: next-short-urls-service
                    port:
                      number: 80
    
                              
                            
  8. Ejecute el comando para crear el ingreso.

                              
                                $ kubectl apply -f ingress.yaml
    
                              
                            
  9. Ejecute el comando kubectl get ingress para ver el ingreso recién creado. El resultado debería ser similar a:

                              
                                NAME                      CLASS    HOSTS               ADDRESS        PORTS     AGE
    next-short-urls-ingress   <none>   <YOUR_DOMAIN>      140.82.41.69   80, 443   37s
    
                              
                            
  10. Navegar a https://<YOUR_DOMAIN para acceder a su aplicación.

Más información

Título del artículo Nombre (opcional) Correo electrónico (opcional) Descripción

Enviar sugerencia

Related Posts