在多阶段镜像构建中,我需要复制文件到哪里?

huangapple go评论75阅读模式
英文:

Where do I need to copy files in a multistage image build?

问题

I'm learning multistage build to get a small image size.
我正在学习多阶段构建以获得较小的镜像大小。

However, I'm struggling with "where do I copy files?"
但是,我遇到了“我应该复制文件到哪里?”的问题。

Indeed, considering the Dockerfile below:
实际上,考虑到下面的Dockerfile

FROM --platform=linux/arm64/v8 debian:11.6-slim as builder
从--platform=linux/arm64/v8 debian:11.6-slim作为构建器

WORKDIR /app

RUN apt update
RUN apt install curl unzip -y
RUN apt-get -y install sqlite3
RUN apt-get -y install imagemagick
RUN curl https://bun.sh/install | bash

COPY package.json .
COPY bun.lockb .

RUN /root/.bun/bin/bun install --production

##############################

FROM --platform=linux/arm64/v8 gcr.io/distroless/base

WORKDIR /app

COPY --from=builder /root/.bun/bin/bun bun
COPY --from=builder /app/node_modules node_modules

COPY --from=builder <===== SQLITE

COPY --from=builder <===== CURL

COPY --from=builder <===== IMAGEMAGICK

CMD ["./bun", "index.ts"]

EXPOSE 3000

What and where do I need to copy to get SQLite3, curl, and imagemagick to work in my distroless image? And whatever the application is, how do I know where to save it?

我需要复制什么和到哪里才能使SQLite3curlimagemagick在我的distroless镜像中工作?而无论应用程序是什么,我怎么知道要保存在哪里?

BTW, if there is another way to shrink my image size, let me know. Thanks.

顺便说一句,如果有其他方法来缩小我的镜像大小,请告诉我。谢谢。

英文:

I'm learning multistage build to get a small image size.
However, I'm struggling with "where do I copy files?"

Indeed, considering the Dockerfile below:

FROM --platform=linux/arm64/v8 debian:11.6-slim as builder

WORKDIR /app

RUN apt update
RUN apt install curl unzip -y
RUN apt-get -y install sqlite3
RUN apt-get -y install imagemagick
RUN curl https://bun.sh/install | bash

COPY package.json .
COPY bun.lockb .

RUN /root/.bun/bin/bun install --production

##############################

FROM --platform=linux/arm64/v8 gcr.io/distroless/base

WORKDIR /app

COPY --from=builder /root/.bun/bin/bun bun
COPY --from=builder /app/node_modules node_modules
# COPY --from=builder     &lt;===== SQLITE
# COPY --from=builder     &lt;===== CURL
# COPY --from=builder     &lt;===== IMAGEMAGICK

CMD [&quot;./bun&quot;, &quot;index.ts&quot;]

EXPOSE 3000

What and where do I need to copy to get SQLite3, curl and imagemagick work in my distroless image? And whatever the application is, how do I know where to save it?

BTW, if there is another way to shrink my image size, let me know. Thanks.

答案1

得分: 0

你实际上无法做到这一点。

特别是ImageMagick包含多个二进制文件并具有多个共享库依赖项。您需要确定所有这些内容,并将它们全部复制到最终镜像中。查看Debian软件包页面可以给您一些想法;跟随所有“dep:”依赖项链接,并点击每个软件包页面底部的“文件列表”链接。最终将包括libc6libgcc-s1低级共享库软件包,如果其中任何程序以shell脚本实现,您还需要一个shell;此时,您基本上会拥有一个完整的Linux环境。

SQLite是另一个有趣的情况,因为您可能不需要sqlite3命令行工具,但您的node_modules目录中可能需要相应的libsqlite.so.3共享库及其依赖项。因此,您还必须识别应用程序依赖项中具有本机扩展的这些情况。

您没有说明镜像中的空间实际用途,而且您的镜像似乎缺少实际的应用程序代码。我一般的建议是将构建分为两个阶段,第一阶段构建应用程序,第二阶段运行它。我不会担心使用Alpine或distroless镜像 - 基础分发可能不是占用空间的地方,而且您可能会遇到兼容性问题。请尽量仅在最终阶段安装所需的共享库,而不是...-dev软件包,也不是命令行工具。

英文:

You can't really do this.

ImageMagick in particular includes multiple binaries and has several shared-library dependencies. You'd need to identify what all of these things are an COPY all of them into the final image. Looking at the Debian package page can give you some idea; follow all of the "dep:" dependency links, and click through to the "list of files" links at the bottom of each package's page. This will eventually include the libc6 and libgcc-s1 low-level shared-library packages, and if any of these programs are implemented as shell scripts you'll need a shell too; at which point you'll essentially have a complete functioning Linux environment.

SQLite is another interesting case in that you probably don't need the sqlite3 command-line tool, but something in your node_modules directory will need the corresponding libsqlite.so.3 shared library and its dependencies. So you'd also have to identify these cases in your application's dependencies with native extensions.

You don't say where the space in your image is actually going, and your image seems to be missing the actual application code. My generic advice would be to split the build into two stages, where the first stage builds the application and the second runs it. I wouldn't worry about using an Alpine or distroless image – the base distribution probably isn't where your space is going and you'll hit compatibility problems like this. Do try to only install the shared libraries you need in the final stage, not ...-dev pacakges and not the command-line tools.

huangapple
  • 本文由 发表于 2023年8月4日 20:39:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76835995.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定