Expand ARG value in CMD [Dockerfile]

cch*_*ney 3 docker dockerfile

I'm passing a build argument into: docker build --build-arg RUNTIME=test

In my Dockerfile I want to use the argument's value in the CMD:

CMD ["npm", "run", "start:${RUNTIME}"]

Doing so results in this error: npm ERR! missing script: start:${RUNTIME} - it's not expanding the variable

I read through this post: Use environment variables in CMD

So I tried doing: CMD ["sh", "-c", "npm run start:${RUNTIME}"] - I end up with this error: /bin/sh: [sh,: not found

Both errors occur when I run the built container.

I'm using the node alpine image as a base. Anyone have ideas how to get the argument value to expand within CMD? Thanks in advance!

full Dockerfile:

FROM node:10.15.0-alpine as builder

ARG RUNTIME_ENV=test
RUN mkdir -p /usr/app
WORKDIR /usr/app

COPY . .

RUN npm ci
RUN npm run build

FROM node:10.15.0-alpine

COPY --from=builder /usr/app/.npmrc /usr/app/package*.json /usr/app/server.js ./
COPY --from=builder  /usr/app/config ./config
COPY --from=builder  /usr/app/build ./build

RUN npm ci --only=production

EXPOSE 3000

CMD ["npm", "run", "start:${RUNTIME_ENV}"]
Run Code Online (Sandbox Code Playgroud)

Update: Just for clarity there were two problems I was running into. 1. The problem as described by Samuel P. 2. ENV values are not carried between containers (multi-stage)

Here's the working Dockerfile where I'm able to expand environment variables in CMD:

# Here we set the build-arg as an environment variable.
# Setting this in the base image allows each build stage to access it
FROM node:10.15.0-alpine as base
ARG ENV
ENV RUNTIME_ENV=${ENV}

FROM base as builder
RUN mkdir -p /usr/app
WORKDIR /usr/app
COPY . .
RUN npm ci && npm run build

FROM base
COPY --from=builder /usr/app/.npmrc /usr/app/package*.json /usr/app/server.js ./
COPY --from=builder  /usr/app/config ./config
COPY --from=builder  /usr/app/build ./build

RUN npm ci --only=production

EXPOSE 3000

CMD npm run start:${RUNTIME_ENV}
Run Code Online (Sandbox Code Playgroud)

Sam*_*ipp 5

这里的问题是ARG参数仅在图像构建期间可用。

ARG 指令定义了一个变量,用户可以在构建时docker build通过使用--build-arg <varname>=<value>标志的命令将其传递给构建器。

https://docs.docker.com/engine/reference/builder/#arg

CMD在容器启动时执行,其中ARG变量不再可用。

ENV 变量在构建期间和容器中都可用:

当容器从生成的映像运行时,使用 ENV 设置的环境变量将持续存在。

https://docs.docker.com/engine/reference/builder/#env

要解决您的问题,您应该将ARG变量转换为ENV变量。

在您的之前添加以下行CMD

ENV RUNTIME_ENV ${RUNTIME_ENV}
Run Code Online (Sandbox Code Playgroud)

如果要提供默认值,可以使用以下命令:

ENV RUNTIME_ENV ${RUNTIME_ENV:default_value}
Run Code Online (Sandbox Code Playgroud)

以下是有关docker docs的使用ARGENV来自 docker docs 的更多详细信息。