【问题标题】:Next.js Environment variables work locally but not when hosted on KubernetesNext.js 环境变量在本地工作,但在 Kubernetes 上托管时不工作
【发布时间】:2020-03-21 22:20:05
【问题描述】:

有一个 Next.js 项目。

这是我在本指南中使用的 next.config.js 文件:https://dev.to/tesh254/environment-variables-from-env-file-in-nextjs-570b

module.exports = withCSS(withSass({
    webpack: (config) => {
        config.plugins = config.plugins || []
        config.module.rules.push({
          test: /\.svg$/,
          use: ['@svgr/webpack',  {
            loader: 'url-loader',
            options: {
                limit: 100000,
                name: '[name].[ext]'
            }}],
        });

        config.plugins = [
          ...config.plugins,

          // Read the .env file
          new Dotenv({
            path: path.join(__dirname, '.env'),
            systemvars: true
          })
        ]

        const env = Object.keys(process.env).reduce((acc, curr) => {
          acc[`process.env.${curr}`] = JSON.stringify(process.env[curr]);
          return acc;
        }, {});
        // Fixes npm packages that depend on `fs` module
        config.node = {
          fs: 'empty'
        }

         /** Allows you to create global constants which can be configured
        * at compile time, which in our case is our environment variables
        */
        config.plugins.push(new webpack.DefinePlugin(env));

        return config
      }
    }),

    );

我有一个 .env 文件,其中包含我需要的值。它在本地主机上运行时有效。

在我的 Kubernetes 环境中,在我可以修改的部署文件中,我设置了相同的环境变量。但是当我尝试识别它们时,它们会显示为未定义,因此我的应用程序无法运行。

我这样称呼它:

process.env.SOME_VARIABLE

在本地工作。

有没有人在部署时有在 Next.js 上创建环境变量功能的经验?不像后端服务那么简单。 :(

编辑: 这就是环境变量部分的样子。

编辑 2: 完整的部署文件,编辑删除了一些细节

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "38"
  creationTimestamp: xx
  generation: 40
  labels:
    app: appname
  name: appname
  namespace: development
  resourceVersion: xx
  selfLink: /apis/extensions/v1beta1/namespaces/development/deployments/appname
  uid: xxx
spec:
  progressDeadlineSeconds: xx
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: appname
      tier: sometier
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: appname
        tier: sometier
    spec:
      containers:
      - env:
        - name: NODE_ENV
          value: development
        - name: PORT
          value: "3000"
        - name: SOME_VAR
          value: xxx
        - name: SOME_VAR
          value: xxxx
        image: someimage
        imagePullPolicy: Always
        name: appname
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /healthz
            port: 3000
            scheme: HTTP
          initialDelaySeconds: 5
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 1
  conditions:
  - lastTransitionTime: xxx
    lastUpdateTime: xxxx
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  observedGeneration: 40
  readyReplicas: 1
  replicas: 1
  updatedReplicas: 1

【问题讨论】:

  • 您的项目中的 .env 文件在哪里?此外,可能值得查看该文件的权限。
  • .env 与 package.json 等一起存在于根目录中(在 /src 目录之外)
  • 对于 Kubernetes,我执行“kubectl edit deploy project_name”,它允许我修改已部署产品的配置,还可以像我一样添加环境变量。此方法适用于后端服务,但浏览器内容不同。
  • 你能分享你的部署文件吗?
  • 我已将环境变量部分的示例添加到 OP

标签: kubernetes environment-variables next.js


【解决方案1】:

.env 在 docker 或 docker-compose 中工作,它们在 Kubernetes 中不起作用,如果你想添加它们,你可以通过 configmaps 对象或直接向每个部署添加一个示例(来自文档):

apiVersion: v1
kind: Pod
metadata:
  name: envar-demo
  labels:
    purpose: demonstrate-envars
spec:
  containers:
  - name: envar-demo-container
    image: gcr.io/google-samples/node-hello:1.0
    env:
    - name: DEMO_GREETING
      value: "Hello from the environment"
    - name: DEMO_FAREWELL
      value: "Such a sweet sorrow

另外,最好和标准的方法是使用配置映射,例如:

  containers:
    - env:
        - name: DB_DEFAULT_DATABASE
          valueFrom:
            configMapKeyRef:
              key: DB_DEFAULT_DATABASE
              name: darwined-env

还有配置图:

apiVersion: v1
data:
  DB_DEFAULT_DATABASE: darwined_darwin_dev_1
 kind: ConfigMap
metadata:
  creationTimestamp: null
  labels:
    io.kompose.service: darwin-env
  name: darwined-env

希望这会有所帮助。

【讨论】:

  • 我在编辑 pod 的部署时有这种设置。我需要将它们添加到 deploy.yaml 中,还是当前通过“kubectl edit deploy service-name”编辑它的方式是一样的?
  • 两者都可以,但最好使用配置映射,如后面的示例所示
  • 我的问题是我有你建议的设置,但实际部署时它不起作用。在本地它工作正常,但是当部署到 pod 时 process.env.SOME_VAR 返回一个未定义的。
  • 这就是我在这里试图帮助你的,事情是检查如何在 next.js 的 docker 容器中运行命令来检查变量是否在里面传递,否则你有问题在部署的 YAML 描述符中
  • 哦,现在我看到了问题,我的错,所以您正在阅读代码中的 .env 文件!现在您的容器中没有 env 文件。因此,要么确保 .env 文件进入容器,要么将代码更改为从环境变量而不是 .env 文件中读取
猜你喜欢
  • 2020-11-09
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-16
  • 2018-03-23
  • 2021-12-08
相关资源
最近更新 更多