Другое

Полное руководство: исправление ошибки развертывания Next.js в Kubernetes

Узнайте, как устранить ошибку 'Не удалось найти файл JavaScript' при развертывании Next.js 16 в Kubernetes с помощью Jenkins pipeline.

Развертывание Next.js 16.0.1 с Node 20 на Kubernetes с использованием Jenkins-пайплайна приводит к ошибке: “Не удалось найти файл JavaScript в ‘APP_DIR’ (/data/app)”

Я пытаюсь развернуть приложение Next.js 16 с Node 20 на Kubernetes с использованием Jenkins-пайплайна без использования Dockerfile. Мой Jenkins-пайплайн включает следующие шаги:

  1. npm install
  2. npm run build
  3. Архивировать директорию .next и загрузить ее в Artrepo
  4. Собрать образ Kubernetes из zip-архива

Однако при развертывании на Kubernetes я сталкиваюсь со следующими симптомами:

Не удалось найти файл JavaScript в "APP_DIR" (/data/app)
Readiness probe failed: Get "http://<pod-ip>:3000/": dial tcp <pod-ip>:3000: connect: connection refused
Back-off restarting failed container <pod> in pod <pod_name>

Что я упускаю в процессе развертывания, особенно в отношении того, как запустить образ в Kubernetes?

Ошибка “Не удалось найти файл JavaScript в ‘APP_DIR’ (/data/app)” в Next.js 16

Ошибка “Не удалось найти файл JavaScript в ‘APP_DIR’ (/data/app)” возникает из-за того, что приложения Next.js 16 требуют специальной конфигурации для контейнерных развертываний. При сборке Next.js для Kubernetes необходимо использовать флаг --standalone в процессе сборки и настроить приложение для запуска в режиме сервера, а не как статический сайт.

Содержание

Понимание ошибки

Сообщение об ошибке указывает, что ваше приложение Next.js ищет файлы JavaScript в /data/app, но не может их найти. Это обычно происходит, когда:

  1. Приложение не было собрано с флагом --standalone, необходимым для контейнерных развертываний
  2. Конфигурация развертывания в Kubernetes не правильно монтирует собранные файлы приложения
  3. Команда запуска в вашем контейнере неверна

Как указано в документации по развертыванию Next.js, приложения Next.js, развертываемые в Kubernetes, требуют специальной конфигурации для правильной работы в контейнерных средах.

Конфигурация автономной сборки Next.js

Основная проблема заключается в том, что Next.js 16 нужно собирать с флагом --standalone, чтобы создать самодостаточное приложение, которое может работать в контейнере. Этот флаг создает файл server.js и необходимые зависимости.

Требуемая команда сборки:

bash
npm run build -- --standalone

Эта команда:

  • Создаст файл server.js в вашем каталоге .next
  • Включит все зависимости Node.js в сборку
  • Сгенерирует автономное приложение, которое не требует полной среды Node.js

Из результатов исследования мы видим, что контейнерные развертывания Next.js требуют этого конкретного подхода к сборке для правильной работы в средах Kubernetes.

Модификации Jenkins Pipeline

Ваш текущий Jenkins Pipeline требует модификации для включения автономной сборки и правильной подготовки к развертыванию:

Обновленные этапы Pipeline:

groovy
pipeline {
    agent any
    
    stages {
        stage('Установка зависимостей') {
            steps {
                sh 'npm install'
            }
        }
        
        stage('Сборка для продакшена') {
            steps {
                // Используем флаг --standalone для контейнерного развертывания
                sh 'npm run build -- --standalone'
            }
        }
        
        stage('Подготовка к развертыванию') {
            steps {
                // Создаем архив с автономной сборкой
                sh 'zip -r next-app.zip .next'
                // Загружаем в Artrepo
                sh 'curl -X POST -F "file=@next-app.zip" http://ваш-url-artrepo/upload'
            }
        }
    }
}

Ключевое изменение - добавление флага --standalone в команду сборки, который создает необходимый файл server.js, который потребуется вашему развертыванию в Kubernetes для запуска приложения.

Конфигурация развертывания в Kubernetes

При развертывании в Kubernetes необходимо убедиться, что:

  1. Правильное монтирование томов: Каталог .next с автономной сборкой должен быть смонтирован правильно
  2. Правильная команда запуска: Контейнер должен запускаться с командой node server.js
  3. Переменные окружения: Установите NODE_ENV=production и PORT=3000

Пример развертывания в Kubernetes:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nextjs-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nextjs-app
  template:
    metadata:
      labels:
        app: nextjs-app
    spec:
      containers:
      - name: nextjs
        image: ваш-image:latest
        ports:
        - containerPort: 3000
        env:
        - name: NODE_ENV
          value: "production"
        - name: PORT
          value: "3000"
        command: ["node", "server.js"]
        workingDir: /app
        volumeMounts:
        - name: app-data
          mountPath: /app
      volumes:
      - name: app-data
        persistentVolumeClaim:
          claimName: nextjs-pvc

Команда command: ["node", "server.js"] здесь критически важна - она указывает Kubernetes, как запустить ваше приложение Next.js после сборки с автономным флагом.

Альтернативные подходы

1. Использование Dockerfile (Рекомендуется)

Хотя вы хотите избежать использования Dockerfile, исследования постоянно показывают, что контейнеризация Next.js с Docker является наиболее надежным подходом. Вот минимальный Dockerfile:

dockerfile
FROM node:20-alpine AS base
WORKDIR /app

FROM base AS builder
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build -- --standalone

FROM base AS runner
ENV NODE_ENV=production
ENV PORT=3000
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
EXPOSE 3000
CMD ["node", "server.js"]

2. Использование конфигурации вывода Next.js

Добавьте это в ваш next.config.js:

javascript
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'standalone',
  experimental: {
    // Включите при необходимости для вашего случая использования
    serverComponentsExternalPackages: []
  }
}

module.exports = nextConfig

Эта конфигурация указывает Next.js всегда собирать с автономным выводом, что устраняет необходимость в флаге --standalone.

Пример полного решения

Вот полное решение, объединяющее лучшие подходы:

1. Обновите next.config.js:

javascript
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'standalone',
  experimental: {
    serverComponentsExternalPackages: []
  }
}

module.exports = nextConfig

2. Упрощенный Jenkins Pipeline:

groovy
pipeline {
    agent any
    
    stages {
        stage('Сборка и развертывание') {
            steps {
                sh 'npm install'
                sh 'npm run build'  // --standalone теперь автоматический
                sh 'docker build -t ваш-репозиторий/nextjs:latest .'
                sh 'docker push ваш-репозиторий/nextjs:latest'
                sh 'kubectl apply -f k8s-deployment.yaml'
            }
        }
    }
}

3. Развертывание в Kubernetes с проверками работоспособности:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nextjs-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nextjs-app
  template:
    metadata:
      labels:
        app: nextjs-app
    spec:
      containers:
      - name: nextjs
        image: ваш-репозиторий/nextjs:latest
        ports:
        - containerPort: 3000
        env:
        - name: NODE_ENV
          value: "production"
        - name: PORT
          value: "3000"
        command: ["node", "server.js"]
        workingDir: /app
        livenessProbe:
          httpGet:
            path: /
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5

Ключевое изыскание из исследований заключается в том, что приложения Next.js в Kubernetes должны быть специально собраны для контейнерных сред с использованием автономной конфигурации вывода, и они должны запускаться с командой node server.js, а не с сервера запуска по умолчанию Next.js.

Источники

  1. Документация по развертыванию Next.js - Контейнерное развертывание
  2. Быстрое развертывание любого приложения Next.js в Kubernetes
  3. Начало работы с Next.js и Kubernetes
  4. Развертывание NextJS приложения в Kubernetes
  5. Развертывание полнофункционального блога на Next.js в Kubernetes & AWS

Заключение

Основные проблемы в процессе вашего развертывания:

  1. Отсутствие автономной сборки: Next.js 16 нужно собирать с флагом --standalone или настроить в next.config.js для работы в контейнерах
  2. Неверная команда запуска: Kubernetes нужно запускать приложение с помощью node server.js, а не сервера по умолчанию Next.js
  3. Конфигурация тома: Убедитесь, что собранные файлы приложения правильно смонтированы в контейнере

Рекомендуемый подход:

  • Использовать output: 'standalone' в вашем next.config.js
  • Собирать с помощью npm run build (флаг standalone применяется автоматически)
  • Развертывать с Dockerfile, который запускает приложение с помощью node server.js
  • Настроить правильные проверки работоспособности в вашем развертывании в Kubernetes

Это решит ошибку “Не удалось найти файл JavaScript” и обеспечит правильный запуск вашего приложения Next.js в Kubernetes.

Авторы
Проверено модерацией
Модерация