敬启者,
我这样做:
我在 github 存储库中有我的简单 C#/NET Core 6.0 应用程序的源代码(我的)。
我正在编写一个 Dockerfile,它应该采用此代码并构建应用程序。
据我了解,这是一种相当普遍的做法 - 一个收集应用程序的单独容器。
这是这个dockerfile,里面没有什么特别原创的(我没有故意优化它):
FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -y wget
RUN wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
RUN dpkg -i packages-microsoft-prod.deb
RUN rm packages-microsoft-prod.deb
RUN apt-get update
RUN apt-get install -y apt-transport-https
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
RUN apt-get install -y dotnet-sdk-6.0
# dotnet sdk is installed!
RUN apt-get install -y git
ARG ssh_prv_key
ARG ssh_pub_key
# Authorize SSH Host
RUN mkdir -p /root/.ssh
RUN chmod 0700 /root/.ssh
RUN ssh-keyscan github.com > /root/.ssh/known_hosts
# Add the keys and set permissions
RUN echo "$ssh_prv_key" > /root/.ssh/id_rsa
RUN echo "$ssh_pub_key" > /root/.ssh/id_rsa.pub
RUN chmod 600 /root/.ssh/id_rsa
RUN chmod 600 /root/.ssh/id_rsa.pub
WORKDIR /App
RUN git clone git@github.com:junecat/InternalProject.git
WORKDIR /App/InternalProject
RUN dotnet publish -c release
CMD mkdir /App/publish-output/
WORKDIR /App/publish-output
CMD cp -r /App/InternalProject/bin/Release/net6.0/* /App/publish-output
从这个 dockerfile,我构建了我需要使用命令构建扩展的容器映像
docker build -t internal_project_build-image --build-arg ssh_prv_key="$(cat ~/.ssh/ro1_key)" --build-arg ssh_pub_key="$(cat ~/.ssh/ro1_key.pub)" -f Dockerfile .
如您所见,在这个阶段,我的readonly-keys 用于访问github从主机到容器。
然后我用命令启动容器
docker run -it --name internal_project_build-cont -v /home/konst/BuildingContainer/publish-output:/App/publish-output -d internal_project_build-image
我的 Dockerfile 已经为我工作了,所以我感觉自己就像世界的统治者。一切都很棒。
直到我对源代码做了一些小的改动,然后我尝试重新构建应用程序。
该应用程序是从旧的源代码构建的。我通过它给出的错误看到了它。我的“小改动”旨在纠正这些错误。
然后我注意到在构建容器映像以响应命令时
RUN git clone git@github.com:junecat/InternalProject.git
我在命令控制台中看到一条docker build消息
Step 22/24 : RUN git clone git@github.com:junecat/InternalProject.git
---> Using cache
---> 3c5778dd3426
“呃!——彼得·伊万诺维奇和我说”
似乎出于某种我不知道的原因,一个聪明的 docker 没有去 github 寻找新的资源,而是决定“它会做!”
我怎样才能让他摆脱困境?
顺便说一句,通过表面的搜索,我发现我并不是唯一一个受苦的人。但是该问题中没有给出任何方法-在我看来,答案很合适...
另外,谢谢你给我关于如何优化我正在做的过程的建议(在容器中构建应用程序)
非常感谢您的建议!
小加法
首先,非常感谢 tym32167 在 git clone 之后使用 git pull 的建议。它有所帮助,但正如评论中所预测的那样,只有一次。然后,显然,“一切都被缓存了”。当然,我会再次尝试检查,也许是我不注意,但似乎这仍然不能解决问题。
到目前为止,对我来说,问题是通过使用命令“解决”的docker builder prune。但是我把“决定”这个词放在引号中是有原因的:这个命令会重置构建器的整个缓存。也就是说,下一次是一切,一切都将再次下载。实际上,这类似于您不喜欢草叶上的特定瓢虫 - 您需要用凝固汽油弹烧掉整个草地并再次生长。
感谢对我的问题的评论,我意识到我在“深入挖掘,但在错误的地方”
对于我的“像 Rails 一样简单”的项目来说,参与从容器内的存储库中获取源代码并构建其中一些是没有意义的。
也就是说,它当然很酷 - 当容器可以完成所有这些时,为此我们将密钥从外部等转移给它。- 但是,显然,这种技术应该用于更复杂的目的,例如,在项目的某些部分必须从源代码构建的情况下......
如果我们有“只是一个项目”——那么构建它的最佳方式是这样的:
码头工人克隆
结果,我们得到了一个包含项目源代码的目录。从它我们启动容器的组装,然后启动容器。
此外 - 只有一个“装饰”修复:在这个目录的顶层只有两件事:Dockerfile 和一个目录,它已经包含源中的项目。
它解决了什么问题?
如果我们突然有另一个项目,那么这只会导致 dockerfile 旁边会有 2 个目录。
这可能会发生,因为我们决定只有几个项目进入一个存储库(对于小型项目来说这是一种非常常见的做法),或者因为测试、设置等通常出现在项目旁边。相关项目。
总的来说,我——就像一个模范男孩——甚至做了一个演示项目来解释我的想法。
该项目分别称为BuildDemo,后
你会有一个爸爸
~/BuildDemo(我会假设一切都发生在主目录中。如果没有,请更正那些重要的地方的路径)然后我们进入这个文件夹并做
从理论上讲,您可以将最后一行“粘贴”到 dockerfile 中
STOPSIGNAL SIGQUIT,然后在容器使用命令完成运行后可以进入它看看它是如何存在的。
然而 - 项目中有第二个 dockerfile (我,不用多说,称之为
Dockerfile2)。它从第一个容器的工作结果中收集 - 第二个容器,已经“工作”:
并使用命令运行它
(另外,这些命令在 )
然后 - 您可以在将在 中创建的 Logs 文件夹中
~/BuildDemo,并确保容器已工作并将其“hello world”写入日志。非常感谢所有帮助我解决问题的人!