【问题标题】:Passing NODE_ENV to docker to run package.json scripts将 NODE_ENV 传递给 docker 以运行 package.json 脚本
【发布时间】:2018-08-22 12:08:45
【问题描述】:

这是我的 dockerfile:

FROM node:6-onbuild

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY package.json /usr/src/app/
RUN npm install
COPY . /usr/src/app

ENV PORT 80
EXPOSE ${PORT}

CMD [ "npm","run", "start" ]

在 package.json 我确实有这个:

"scripts": {
  "start": "node start.js",
  "stagestart": "NODE_ENV=content-staging node start.js"
}

start 脚本用于生产,现在我想要一种在 dockerfile 中运行暂存脚本的方法。有没有办法在 dockerfile 中读取 NODE_ENV,所以我可以拥有一个 dockerfile 来处理暂存和生产。

【问题讨论】:

  • 似乎有点像 Docker 的蚂蚁模式。如果您想运行不同的脚本或只是不同的环境变量,也不是很清楚,这两者都可以在创建 container 时执行。
  • @ldg 我实际上需要运行不同的脚本,但不知道应该如何分别运行它们。
  • 创建两个 dockerfile
  • 每个节点应用程序只能有一个 package.json 文件,因此如果您需要不同的应用程序启动,则需要从脚本启动应用程序。顺便说一句,如果不是您想要的,请检查我的详细答案。
  • 您不应通过npm 运行命令。这会大大减慢处理速度。最好在生产时直接使用node start.js

标签: node.js amazon-web-services docker dockerfile


【解决方案1】:

这里有两种可能的实现方式。

仅供参考:如果您不需要在 package.json 中提及 NODE_ENV 已经在系统级别设置了 NODE_ENV,或者在构建时或运行时在 docker 中设置了 NODE_ENV。

这里Dockerfilealpine 一样,但我以前是alpine 基本图像

FROM node:alpine

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY package.json /usr/src/app/
RUN npm install
COPY . /usr/src/app
ENV PORT 3000
ARG DOCKER_ENV
ENV NODE_ENV=${DOCKER_ENV}
RUN if [ "$DOCKER_ENV" = "stag" ] ; then  echo   your NODE_ENV for stage is $NODE_ENV;  \
else  echo your NODE_ENV for dev is $NODE_ENV; \
fi 


EXPOSE ${PORT}

CMD [ "npm","run", "start" ]

当您使用此命令构建此 Dockerfile 时

docker build --build-arg DOCKER_ENV=stag -t test-node .

你会在层看到

 ---> Running in a6231eca4d0b your NODE_ENV for stage is stag

当你运行这个 docker 容器并运行这个命令时,你的输出将是

/usr/src/app # echo $NODE_ENV

stag

最简单的方法相同的图像,但在运行时设置环境变量

你的 Dockerfile

FROM node:alpine
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/
RUN npm install
COPY . /usr/src/app
ENV PORT 3000
EXPOSE ${PORT}
CMD [ "npm","run", "start" ]

用这个命令运行这个 docker 镜像

docker build -t  test-node .

 docker run  --name test -e NODE_ENV=content-staging  -p 3000:3000 --rm -it test-node ash

所以当你在容器中运行这个命令时你会看到

/usr/src/app # echo $NODE_ENV
content-staging

这就是您可以使用 NODE_ENV 启动节点应用程序的方法,而无需在 package.json 中设置环境变量。因此,如果您的 nodejs 配置基于 NODE_ENV,则应根据 NODE_ENV 选择配置。

【讨论】:

  • 欢迎您,但您想以@Emad 的方式分享他们
  • 好吧,我找到了另一种方法,我使用了 Buildkite,因为我使用了 ECS,所以在我的 ecs-task 中我定义了我的 ENV 变量,那么无论我们运行哪个脚本,“start”或“stagestart” " 它会将所有 ENV 变量发送到 buildkite。基本上我没有改变我的 docker 上的任何东西。
  • 哦,您使用的是 AWS ECS 吗?您可以在任务定义中定义 ENV,这与我提到的 docker start 命令相同。但如果你在 docker 文件中定义 env,ECS 容器也会从 docker 文件中获取。但是我的解决方案如何在本地系统上实现。
  • 我试过这个解决方案,但它对我不起作用。当我console.log(process.env) 它回显{ ... NODE_ENV: 'production' ... },但console.log(proces.env.NODE_ENV) 下方1 行回显development。有人可以解释发生了什么吗?我什至在运行命令之前尝试了cross-envNODE_ENV=production,但它也不起作用。
  • @Reijo 你在哪里设置环境变量?
【解决方案2】:

您可以使用 ENV 指令获取环境变量作为容器内的环境变量。有一个入口点脚本来注入可用的环境变量(可能像 sed 一样简单)来代替 package.json 文件中的占位符变量名称。然后启动您的节点应用程序。显然,这将需要您对 Dockerfile 的入口点脚本等进行一些更改。

这就是我过去取得这些成就的方式。

【讨论】:

    猜你喜欢
    • 2021-07-11
    • 2019-12-26
    • 1970-01-01
    • 2018-10-08
    • 1970-01-01
    • 2014-01-31
    • 2020-05-09
    相关资源
    最近更新 更多