我在学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
放在项目的根目录下吗?使用这种方法有什么缺点?
7条答案
按热度按时间9avjhtql1#
根据文件:
WORKDIR指令为Dockerfile中跟在它后面的任何RUN、CMD、ENTRYPOINT、COPY和ADD指令设置工作目录。如果WORKDIR不存在,即使它没有在任何后续的Dockerfile指令中使用,也会创建它。
此外,在Docker最佳实践中,它建议您使用它:
...您应该使用WORKDIR,而不是像RUN cd...&& do-something这样的大量指令,这些指令很难阅读、排除故障和维护。
我建议保留它。
我认为您可以将您的Dockerfile重构为如下形式:
oknrviil2#
你不必
WORKDIR
当您指定
WORKDIR
时,会自动建立此档案e1xvtsh33#
您可以将
WORKDIR
视为容器内的cd
(它会影响Docker文件中后面的命令,如RUN
命令)。如果您在上面的示例中删除了WORKDIR
,则RUN npm install
将无法工作,因为您将不在容器内的/usr/src/app
目录中。我看不出这和你把Dockerfile放在哪里有什么关系(因为你的Dockerfile在主机上的位置和容器中的pwd没有关系)。你可以把Dockerfile放在你项目中你想放的任何地方。但是,
COPY
的第一个参数是一个相对路径,所以如果你移动你的Dockerfile,你可能需要更新那些COPY
命令。ny6fqffe4#
在应用WORKDIR之前。这里WORKDIR在错误的位置,没有被明智地使用。
我们更正了上面的代码,将WORKDIR放在正确的位置,并通过删除
/Publish
优化了以下语句因此,它的作用就像一个
cd
,并为即将到来的声明定下基调。anauzrmj5#
注意使用vars作为
WORKDIR
的目标目录名a-这样做似乎会导致“cannot normalize nothing”的致命错误。IMO,值得指出的是,WORKDIR
的行为方式与mkdir -p <path>
相同,即如果路径的所有元素都不存在,则会创建它们。UPDATE:我在运行多阶段构建时遇到了变量相关的问题(上面提到的)-现在看来,使用变量是很好的-如果它(变量)是“在范围内”,例如在下面的代码中,第二个
WORKDIR
引用失败...然而,它成功地在这个...
. ooO(* 可能在文档中有,但我错过了 *)
8zzbczxx6#
注意设置
WORKDIR
的位置,因为它可能会影响连续积分流。例如,将其设置为/home/circleci/project
将导致类似.ssh
的错误,或者远程circleci在设置时正在执行的任何操作。fbcarpbf7#
@juanlumn的回答很棒,但我想再补充一件(重要的)事情。
在常规的命令行中,如果你在某个地方执行
cd
,它会一直保持在那里,直到你改变它。然而,在Docker文件中,每个RUN
命令都从根目录开始!这是一个gotcha,适合Docker新手,需要注意。因此,
WORKDIR
不仅为阅读代码的人提供了更明显的视觉提示,而且它还为多个RUN命令保留了工作目录。