使用 Docker 部署 Nuxt,环境变量未注册和意外的 API 调用?

Sum*_*ron 5 node.js docker docker-compose axios nuxt.js

我正在重新阅读有关环境变量的文档,但有点困惑。

MWE 仓库:https : //gitlab.com/SumNeuron/docker-nf

我做了一个插件 /plugins/axios.js 来创建一个自定义的 axios 实例:

import axios from 'axios'

const apiVersion = 'v0'
const api = axios.create({
  baseURL: `${process.env.PUBLIC_API_URL}/api/${apiVersion}/`
})

export default api
Run Code Online (Sandbox Code Playgroud)

并相应地将其添加到 nuxt.config.js

import colors from 'vuetify/es5/util/colors'

import bodyParser from 'body-parser'
import session from 'express-session'
console.log(process.env.PUBLIC_API_URL)
export default {
  mode: 'spa',
  env: {
    PUBLIC_API_URL: process.env.PUBLIC_API_URL || 'http://localhost:6091'
  },
  //  ...
   plugins: [
   //...
   '@/plugins/axios.js'
  ]
}
Run Code Online (Sandbox Code Playgroud)

我在文件中设置PUBLIC_API_URL为。奇怪的是,日志语句是正确的(端口),但是当尝试访问该站点时,有一个对端口的 api 调用(后备)http://localhost:9061.env90616091

系统设置

project/
|-- backend (flask api)
|-- frontend (npx create-nuxt-app frontend)
    |-- assets/
    |-- ...
    |-- plugins/
        |-- axios.js
    |-- restriced_pages
        |-- index.js (see other notes 3)
    |-- ...
    |-- nuxt.config.js
    |-- Dockerfile

|-- .env
|-- docker-compose.yml
Run Code Online (Sandbox Code Playgroud)

码头工人

docker-compose.yml

version: '3'

services:
  nuxt: # frontend
    image: frontend
    container_name: my_nuxt
    build:
      context: .
      dockerfile: ./frontend/Dockerfile
    restart: always
    ports:
      - "3000:3000"
    command: "npm run start"
    environment:
      - HOST
      - PUBLIC_API_URL

  flask: # backend
    image: backend
    container_name: my_flask
    build:
      context: .
      dockerfile: ./backend/Dockerfile
    command: bash deploy.sh

    environment:
      - REDIS_URL
      - PYTHONPATH
    ports:
      - "9061:9061"
    expose:
      - '9061'
    depends_on:
      - redis

  worker:
    image: backend
    container_name: my_worker
    command: python3 manage.py runworker
    depends_on:
      - redis
    environment:
      - REDIS_URL
      - PYTHONPATH

  redis: # for workers
    container_name: my_redis
    image: redis:5.0.3-alpine
    expose:
        - '6379'

Run Code Online (Sandbox Code Playgroud)

文件

FROM node:10.15

ENV APP_ROOT /src

RUN mkdir ${APP_ROOT}
WORKDIR ${APP_ROOT}


COPY ./frontend ${APP_ROOT}

RUN npm install

RUN npm run build

Run Code Online (Sandbox Code Playgroud)

其他注意事项:

  1. 网站无法加载的原因是新的 axios 插件 ( @/plugins/axios.js) 在页面加载时进行了一个奇怪的调用 xhr 调用,由commons.app.js第 464 行触发。我不知道为什么,这个调用在我的代码中没有明确显示。

  2. 我看到这个警告:

    WARN 警告:connect.session() MemoryStore 不是为生产环境设计的,因为它会泄漏内存,并且不会扩展到单个进程。

我不知道是什么原因造成的或如何纠正它

  1. 我有一个“受限”页面:
project/
|-- backend (flask api)
|-- frontend (npx create-nuxt-app frontend)
    |-- assets/
    |-- ...
    |-- plugins/
        |-- axios.js
    |-- restriced_pages
        |-- index.js (see other notes 3)
    |-- ...
    |-- nuxt.config.js
    |-- Dockerfile

|-- .env
|-- docker-compose.yml
Run Code Online (Sandbox Code Playgroud)

配置nuxt.config.js

version: '3'

services:
  nuxt: # frontend
    image: frontend
    container_name: my_nuxt
    build:
      context: .
      dockerfile: ./frontend/Dockerfile
    restart: always
    ports:
      - "3000:3000"
    command: "npm run start"
    environment:
      - HOST
      - PUBLIC_API_URL

  flask: # backend
    image: backend
    container_name: my_flask
    build:
      context: .
      dockerfile: ./backend/Dockerfile
    command: bash deploy.sh

    environment:
      - REDIS_URL
      - PYTHONPATH
    ports:
      - "9061:9061"
    expose:
      - '9061'
    depends_on:
      - redis

  worker:
    image: backend
    container_name: my_worker
    command: python3 manage.py runworker
    depends_on:
      - redis
    environment:
      - REDIS_URL
      - PYTHONPATH

  redis: # for workers
    container_name: my_redis
    image: redis:5.0.3-alpine
    expose:
        - '6379'

Run Code Online (Sandbox Code Playgroud)

它使用默认axios模块:

FROM node:10.15

ENV APP_ROOT /src

RUN mkdir ${APP_ROOT}
WORKDIR ${APP_ROOT}


COPY ./frontend ${APP_ROOT}

RUN npm install

RUN npm run build

Run Code Online (Sandbox Code Playgroud)

小智 7

当您在 SPA 模式下工作时,您需要环境变量在构建期间可用。

$ docker run因此,该命令定义这些变量已经太晚了,这就是您使用 docker-compose 的“环境”键所做的。

因此,要在构建时使这些变量可用,您需要做的是在 Dockerfile 中使用ENV PUBLIC_API_URL http://localhost:9061. 但是,如果您希望它们由 docker-compose 定义,则需要将它们作为构建参数传递。即在您的 docker-compose 中:

nuxt:
  build:
    # ...
    args:
      PUBLIC_API_URL: http://localhost:9061
Run Code Online (Sandbox Code Playgroud)

在您的 Dockerfile 中,您可以捕获该 arg 并将其传递给您的构建环境,如下所示:

ARG PUBLIC_API_URL
ENV PUBLIC_API_URL ${PUBLIC_API_URL}
Run Code Online (Sandbox Code Playgroud)

如果您不想直接在 docker-compose 中定义变量的值,而是在本地(即在您启动 docker-compose 命令的机器上)定义的环境变量(例如使用 shell $ export PUBLIC_API_URL=http://localhost:9061),您可以参考它就像您在随后的 shell 命令中一样,因此您的 docker-compose 最终如下所示:

nuxt:
  build:
    # ...
    args:
      PUBLIC_API_URL: ${PUBLIC_API_URL}
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案是在构建时,而不是在运行时,它应该有一个运行时的解决方案,因为当我们拉取docker镜像来使用时,它应该能够在当时配置环境,而不是在构建时修复它。 (2认同)
  • 我遇到了同样的问题 - 只有当我在构建过程中提供 .env 文件时,事情才有效。但这显然是将其中的数据嵌入到图像中......这是无稽之谈 - 谁想要将秘密嵌入到图像中...... (2认同)