【问题标题】:Injecting variables to my NextJS app using Kubernetes使用 Kubernetes 将变量注入我的 NextJS 应用程序
【发布时间】:2022-12-01 06:07:19
【问题描述】:

当我使用 Kubernets 部署我的代码时,我试图生成一些环境变量。我想做的是生成一个 ConfigMap 来获取我的变量,但它不起作用。 我正在使用 azure pipelines 来执行我的构建和发布步骤。

文件:

FROM node:14-alpine

WORKDIR /usr/src/app

COPY package.json .

COPY . .

RUN npm cache clean --force
RUN npm install
RUN npm run build

EXPOSE 80

CMD ["npm", "start"]

我的 azure-pipelines.yml:

stages:
#Build Dev
- stage: BuildDev
  displayName: Build and Push Dev
  jobs:
  - job: Development
    displayName: Build and Push Dev
    timeoutInMinutes: 0
    pool:
      vmImage: ubuntu-18.04
    steps:
    - checkout: self
    - task: Docker@1
      displayName: Build Image
      inputs:
        azureSubscriptionEndpoint: my-subscription
        azureContainerRegistry: my-container-registry
        command: build
        imageName: tenant/front/dev:$(Build.BuildId)
        includeLatestTag: true
        buildContext: '**'
    - task: Docker@1
      displayName: Push Image
      inputs:
        azureSubscriptionEndpoint: my-subscription
        azureContainerRegistry: my-container-registry
        command: push
        imageName: tenant/front/dev:$(Build.BuildId)
        buildContext: '**'


#Deploy Dev
- stage: DeployDev
  displayName: Deploy Dev
  jobs:
    - deployment: Deploy
      displayName: Deploy Dev
      timeoutInMinutes: 0
      pool:
        vmImage: ubuntu-18.04
      environment: Development-Front
      strategy:
        runOnce:
          deploy:
            steps:
            - task: Kubernetes@1
              displayName: 'kubectl apply'
              inputs:
                kubernetesServiceEndpoint: 'AKS (standard subscription)'
                command: apply
                useConfigurationFile: true
                configurationType: inline
                inline: |
                  apiVersion: apps/v1beta1
                  kind: Deployment
                  metadata:
                      name: $(appNameDev)
                      labels:
                          app: $(appNameDev)
                  spec:
                      replicas: 1
                      selector:
                          matchLabels:
                              app: $(appNameDev)
                      template:
                          metadata:
                              labels:
                                  app: $(appNameDev)
                          spec:
                              containers:
                                  - name: $(appNameDev)
                                    image: tenant/front/dev:$(Build.BuildId)
                                    imagePullPolicy:
                                    env:
                                      - name: NEXT_PUBLIC_APP_API
                                        value: development
                                    ports:
                                      - name: http
                                        containerPort: 80
                                        protocol: TCP
                                    volumeMounts:
                                      - name: environment-variables
                                        mountPath: /usr/src/app/.env
                                        readOnly: true
                              volumes:
                                - name: environment-variables
                                  configMap:
                                    name: environment-variables
                                    items:
                                    - key: .env
                                      path: .env
              ---
              apiVersion: v1
              kind: Service
              metadata:
                  name: $(appNameDev)
                  labels:
                      app: $(appNameDev)
              spec:
                  type: LoadBalancer
                  ports:
                      - port: 80
                        targetPort: 80
                        protocol: TCP
                        name: http
                  selector:
                      app: $(appNameDev)
              ---
              apiVersion: v1
              kind: ConfigMap
              metadata:
                name: environment-variables
              data:
                .env: |
                  NEXT_PUBLIC_APP_API=development
                  API=http://another.endpoint.com/serverSide

当我尝试访问此 NEXT_PUBLIC_APP_API 变量时,我收到未定义的消息。在我的 next.config.js 中,我将变量导出为 publicRuntimeConfig。

【问题讨论】:

  • 你想出来了吗?我也有同样的问题
  • 不幸的是我没有解决它。我仍在为不同的环境制作 3 个版本。
  • 我解决了在使用 GitHub 操作构建 docker 映像时注入环境变量的问题。
  • @LeandroHoffmann 你能详细说明一下吗?我坚持同样的事情
  • @LeandroHoffmann 我也对您的解决方案感兴趣

标签: kubernetes azure-devops next.js


【解决方案1】:

如果您使用 GitHub 操作,首先是在图像构建过程中添加一个步骤以包含动态变量

  - name: Create variables
    id: vars
    run: |
      branch=${GITHUB_REF##*/}
      echo "API_URL=API_${branch^^}" >> $GITHUB_ENV
      echo "APP_ENV=APP_${branch^^}" >> $GITHUB_ENV
      echo "BASE_URL=BASE_${branch^^}" >> $GITHUB_ENV
      sed -i "s/GIT_VERSION/${{ github.sha }}/g" k8s/${branch}/api-deployment.yaml

第二步是用额外的参数构建 docker 镜像,如果你使用另一个 CI,只需在构建参数中直接添加变量,如下所示:

--build-arg PROD_ENV=NEXT_PUBLIC_API_URL=${{ secrets[env.API_URL] }}
NEXT_PUBLIC_BASE_URL=${{ secrets[env.BASE_URL]}}
NEXT_PUBLIC_APP_ENV=${{ secrets[env.APP_ENV] }}

注意 以跳过行和 docker 以便能够理解您正在向构建过程发送多个变量。

最后一件事是在 Dockerfile 中添加额外的参数

# Install dependencies only when needed
FROM node:16.13.0-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

# Rebuild the source code only when needed
FROM node:16.13.0-alpine AS builder
ARG PROD_ENV=""
WORKDIR /app
COPY . .
COPY --from=deps /app/node_modules ./node_modules
RUN printf "$PROD_ENV" >> .env.production
RUN yarn build

# Production image, copy all the files and run next
FROM node:16.13.0-alpine AS runner
WORKDIR /app

ENV NODE_ENV production

# 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/.env* ./
COPY --from=builder /app/next-i18next.config.js ./
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json

RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
RUN chown -R nextjs:nodejs /app/.next
USER nextjs

# 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.
RUN npx next telemetry disable

CMD ["yarn", "start"]

我作为额外的 args PROD_ENV 发送,然后使用所需的值即时构建一个 .env.production 文件。

如果对您有帮助,请标记为答案

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-24
    • 2019-02-22
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 2018-09-07
    • 2016-07-25
    相关资源
    最近更新 更多