我正在学习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” ] 

我不能忽略WORKDIR和Copy,只是有我的Dockerfile在我的项目的根?使用这种方法的缺点是什么?


当前回答

在应用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"]

因此,它就像一张cd,为接下来的语句设定基调。

其他回答

要注意在哪里设置WORKDIR,因为它会影响持续集成流程。例如,将其设置为/home/circleci/project将导致错误,例如.ssh或远程circleci在安装时正在执行的任何操作。

@juanlumn的回答很棒,但我想再补充一件(重要的)事情。

在常规命令行中,如果您在某个地方执行cd操作,它将一直停留在那里,直到您更改它。然而,在Dockerfile中,每个RUN命令都是从根目录开始的!这是码头工人新手的一个难题,需要注意。

因此,WORKDIR不仅为阅读代码的人提供了更明显的视觉提示,而且还为多个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” ] 

在应用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"]

因此,它就像一张cd,为接下来的语句设定基调。

小心使用vars作为WORKDIR的目标目录名——这样做似乎会导致“不能标准化任何东西”的致命错误。在我看来,还值得指出的是,WORKDIR的行为与mkdir -p <path>相同,即路径的所有元素都是创建的,如果它们还不存在的话。

更新: 我在运行多阶段构建时遇到了变量相关的问题(上面提到过)-现在看来使用变量是可以的-如果它(变量)是“在范围内”,例如在下面,第2个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(可能在文档里,我错过了)