这个问题已经问过了,在过去的两天里,我已经尝试了大量的例子来尝试和配置,没有运气,所以我张贴我的环境,以寻求任何帮助。
问题
在使用Terraform部署到kubernetes之后,Nextjs环境变量都是未定义的。
预期结果
staging: NEXT_PUBLIC_APIROOT=https://apis-staging.mywebsite.com
production: NEXT_PUBLIC_APIROOT=https://apis.mywebsite.com
秘密存储在github行动中。我有一个terraform设置,它将我的应用程序部署到我的暂存和生产库中,下面是一个片段:
env:
ENV: staging
PROJECT_ID: ${{ secrets.GKE_PROJECT_STAG }}
GOOGLE_CREDENTIALS: ${{ secrets.GOOGLE_CREDENTIALS_STAG }}
GKE_SA_KEY: ${{ secrets.GKE_SA_KEY_STAG }}
NEXT_PUBLIC_APIROOT: ${{ secrets.NEXT_PUBLIC_APIROOT_STAGING }}
我还有一个额外的步骤要手动创建一个.env文件
- name: env-file
run: |
touch .env.local
echo NEXT_PUBLIC_APIROOT: ${{ secrets.NEXT_PUBLIC_APIROOT_STAGING }} >> .env.local
Dockerfile
FROM node:16-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json package-lock.json .npmrc ./
RUN npm ci
FROM node:16-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM node:16-alpine AS runner
WORKDIR /app
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
# 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 /app/package.json ./package.json
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
CMD ["node", "server.js"]
next.config.js
module.exports = withBundleAnalyzer({
publicRuntimeConfig: {
NEXT_PUBLIC_APIROOT: process.env.NEXT_PUBLIC_APIROOT,
},
output: 'standalone',
webpack: (config, { dev, isServer }) => {
if (dev && isServer) {
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')
config.plugins.push(
new ForkTsCheckerWebpackPlugin({
eslint: {
files: './src/**/*.{ts,tsx,js,jsx}',
},
})
)
}
return config
},
})
有人在这个问题上有经验吗?
发布于 2022-08-18 11:36:06
首先,我想说,我绝不是NextJS的专家。因此,我尝试在以下假设下处理您的问题:
next.config.js
机制自动从.env.local
加载环境变量us-central1-c
)我的第一步是使用一个API端点创建一个虚拟的NextJS应用程序,该端点只打印我在将工作负载部署到Kubernetes时试图设置的一个环境变量。当涉及到Dockerfile时,我使用了您提供的完全相同的图像。请在下面找到我的虚拟应用程序的相关文件:
pages/api/test.js
export default function handler(req, res) {
res.status(200).json(process.env.NEXT_PUBLIC_APIROOT)
}
next.config.js
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: true,
});
module.exports = withBundleAnalyzer({
publicRuntimeConfig: {
NEXT_PUBLIC_APIROOT: process.env.NEXT_PUBLIC_APIROOT,
},
output: 'standalone'
})
Dockerfile
FROM node:16-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
FROM node:16-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM node:16-alpine AS runner
WORKDIR /app
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
# 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 /app/package.json ./package.json
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
CMD ["npm", "start"]
我在Dockerfile中做了一个更改,就是更新CMD条目,以便应用程序通过npm start
命令启动。
根据官方的文档,NextJS将尝试在应用程序根文件夹中查找.env.local
,并在process.env
中加载这些环境变量。
因此,我使用Kubernetes资源创建了一个YAML文件,用于创建部署设置。
nextjs-app-setup.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nextjs-app-config
data:
.env.local: |-
NEXT_PUBLIC_APIROOT=hello_i_am_an_env_variable
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nextjs-app
labels:
app: nextjs-app
spec:
replicas: 1
selector:
matchLabels:
app: nextjs-app
template:
metadata:
labels:
app: nextjs-app
spec:
containers:
- name: nextjs-app
image: public.ecr.aws/u4x8r8g3/nextjs-app:latest
ports:
- containerPort: 3000
volumeMounts:
- name: nextjs-app-config
mountPath: "/app/.env.local"
subPath: ".env.local"
readOnly: true
volumes:
- name: nextjs-app-config
configMap:
name: nextjs-app-config
---
apiVersion: v1
kind: Service
metadata:
name: nextjs-service
spec:
selector:
app: nextjs-app
ports:
- protocol: TCP
port: 3000
targetPort: 3000
在上面的配置中发生了多种情况:
.env.local
的条目,它将保存所有的环境变量,并将作为一个文件挂载在应用程序pod中。volumes
和volumeMounts
块。在这里,我从定义在.env.local
路径上的ConfigMap中挂载/app/.env.local
条目通过kubectl连接到GKE集群之后,我通过kubectl apply -f nextjs-app-setup.yaml
应用了配置。
为了从本地工作站连接到服务,我执行了kubectl port-forward service/nextjs-service 3000:3000
。然后,我在浏览器中导航到localhost:3000/api/test
,可以看到我在ConfigMap中设置的值作为输出。
免责声明:我知道您的设置可能涉及一些额外的组件,特别是在涉及CI/CD和基础设施作为代码时,但是我在这里的回答至少应该为您提供一种在容器化NextJS工作负载中访问环境变量的方法。如果您仍然得到undefined
值,我的假设是它很可能与您在CI/CD管道中配置它们的方式有关,但这将是一个与NextJS或Kubernetes无关的不同问题。
https://stackoverflow.com/questions/73310405
复制相似问题