Dockerfile上的WORKDIR有什么意义?

ryoqjall  于 2022-11-02  发布在  Docker
关注(0)|答案(7)|浏览(279)

我在学Docker,多次看到DockerfileWORKDIR命令:

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放在项目的根目录下吗?使用这种方法有什么缺点?

9avjhtql

9avjhtql1#

根据文件:
WORKDIR指令为Dockerfile中跟在它后面的任何RUN、CMD、ENTRYPOINT、COPY和ADD指令设置工作目录。如果WORKDIR不存在,即使它没有在任何后续的Dockerfile指令中使用,也会创建它。
此外,在Docker最佳实践中,它建议您使用它:
...您应该使用WORKDIR,而不是像RUN cd...&& do-something这样的大量指令,这些指令很难阅读、排除故障和维护。
我建议保留它。
我认为您可以将您的Dockerfile重构为如下形式:

FROM node:latest
WORKDIR /usr/src/app
COPY package.json .
RUN npm install
COPY . ./
EXPOSE 3000
CMD [ "npm", "start" ]
oknrviil

oknrviil2#

你不必
WORKDIR
当您指定WORKDIR时,会自动建立此档案

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

e1xvtsh33#

您可以将WORKDIR视为容器内的cd(它会影响Docker文件中后面的命令,如RUN命令)。如果您在上面的示例中删除了WORKDIR,则RUN npm install将无法工作,因为您将不在容器内的/usr/src/app目录中。
我看不出这和你把Dockerfile放在哪里有什么关系(因为你的Dockerfile在主机上的位置和容器中的pwd没有关系)。你可以把Dockerfile放在你项目中你想放的任何地方。但是,COPY的第一个参数是一个相对路径,所以如果你移动你的Dockerfile,你可能需要更新那些COPY命令。

ny6fqffe

ny6fqffe4#

在应用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,并为即将到来的声明定下基调。

anauzrmj

anauzrmj5#

注意使用vars作为WORKDIR的目标目录名a-这样做似乎会导致“cannot normalize nothing”的致命错误。IMO,值得指出的是,WORKDIR的行为方式与mkdir -p <path>相同,即如果路径的所有元素都不存在,则会创建它们。
UPDATE:我在运行多阶段构建时遇到了变量相关的问题(上面提到的)-现在看来,使用变量是很好的-如果它(变量)是“在范围内”,例如在下面的代码中,第二个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

. ooO(* 可能在文档中有,但我错过了 *)

8zzbczxx

8zzbczxx6#

注意设置WORKDIR的位置,因为它可能会影响连续积分流。例如,将其设置为/home/circleci/project将导致类似.ssh的错误,或者远程circleci在设置时正在执行的任何操作。

fbcarpbf

fbcarpbf7#

@juanlumn的回答很棒,但我想再补充一件(重要的)事情。
在常规的命令行中,如果你在某个地方执行cd,它会一直保持在那里,直到你改变它。然而,在Docker文件中,每个RUN命令都从根目录开始!这是一个gotcha,适合Docker新手,需要注意。
因此,WORKDIR不仅为阅读代码的人提供了更明显的视觉提示,而且它还为多个RUN命令保留了工作目录。

相关问题