Dockerfile上的WORKDIR有什么意义?

时间:2018-06-27 15:07:30

标签: docker dockerfile

我正在学习Docker。很多次我看到Dockerfile拥有WORKDIR命令:

FROM node:latest
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/
RUN npm install
COPY . /usr/src/app
EXPOSE 3000
CMD [ “npm”, “start” ] 

我不能只省略WORKDIRCopy,而只是将Dockerfile放在项目的根目录吗?使用这种方法的缺点是什么?

7 个答案:

答案 0 :(得分:38)

根据documentation

  

WORKDIR指令为任何RUN,CMD,   紧随其后的ENTRYPOINT,COPY和ADD指令   Dockerfile。

此外,在Docker best practices中,建议您使用它:

  

...您应该使用WORKDIR而不是大量的说明   运行cd…&&做某事,这些文件很难阅读,排除故障并   维持。

我建议保留它。

我认为您可以将Dockerfile重构为类似的内容:

FROM node:latest
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json .
RUN npm install
COPY . ./
EXPOSE 3000
CMD [ “npm”, “start” ] 

答案 1 :(得分:21)

您不必

RUN mkdir -p /usr/src/app

当您指定WORKDIR

时会自动创建
FROM node:latest
WORKDIR /usr/src/app
COPY package.json .
RUN npm install
COPY . ./
EXPOSE 3000
CMD [ “npm”, “start” ] 

答案 2 :(得分:15)

您可以将WORKDIR视为容器内的cd(它会影响Dockerfile中稍后出现的命令,例如RUN命令)。如果您在上面的示例中删除了WORKDIR,则RUN npm install将不起作用,因为您将不在容器的/usr/src/app目录中。

我不知道这与放置Dockerfile的位置有什么关系(因为您在主机上的Dockerfile位置与容器内的pwd无关)。您可以将Dockerfile放置在项目中的任何位置。但是,COPY的第一个参数是相对路径,因此,如果您移动Dockerfile,则可能需要更新这些COPY命令。

答案 3 :(得分:0)

在应用WORKDIR之前。这里的WORKDIR放置在错误的位置,不明智地使用。

FROM microsoft/aspnetcore:2
COPY --from=build-env /publish /publish
WORKDIR /publish
ENTRYPOINT ["dotnet", "/publish/api.dll"]

我们更正了以上代码,以将WORKDIR放置在正确的位置,并通过删除/Publish

优化了以下语句
FROM microsoft/aspnetcore:2
WORKDIR /publish
COPY --from=build-env /publish .
ENTRYPOINT ["dotnet", "/api.dll"]

答案 4 :(得分:0)

当心使用vars作为WORKDIR的目标目录名-这样做似乎会导致“无法规范化所有内容”致命错误。 IMO,还值得指出的是WORKDIR的行为与mkdir -p <path>相同,即,如果路径中的所有元素都不存在,则会创建它们。

更新: 我在运行多阶段构建时遇到了与变量相关的问题(如上所述)-现在看来,使用变量就可以了-如果它(变量)在“范围内”,例如在以下情况下,第二个WORKDIR引用失败...

FROM <some image>
ENV varname varval
WORKDIR $varname

FROM <some other image>
WORKDIR $varname

而它成功了...

FROM <some image>
ENV varname varval
WORKDIR $varname

FROM <some other image>
ENV varname varval
WORKDIR $varname

.oO(也许在文档中,但我错过了它

答案 5 :(得分:0)

请小心设置WORKDIR的位置,因为它会影响连续的集成流程。例如,将其设置为/home/circleci/project会导致类似.ssh之类的错误,或者在设置时远程circleci正在执行的操作。

答案 6 :(得分:-2)

可以,这很好。有时您希望在容器上安装一个终端以进行调试。

docker exec -it [container-id] bash

Source

如果这样做,某些人会发现在/ usr / src / app中找到他们的应用程序很愉快。或在/ mkasberg /中。或任何其他专用工作目录。

另一种可能性是您的应用程序依赖于某个绝对路径。

除此之外,这取决于您。