首页 > 解决方案 > 如何减少多阶段构建重复步骤时间成本问题?

问题描述

我有一个 go 应用程序,它依赖于 cgo。构建时需要libsodium-dev, libzmq3-dev, libczmq-dev,运行时还需要以上三个包。

目前,我使用下一个多阶段构建:a golang build environment作为第一阶段和a debian slim第二阶段。但是您可以看到安装了两次的 3 个软件包,这浪费了时间(以后我可能会添加更多此类软件包)。

FROM golang:1.12.9-buster AS builder

WORKDIR /src/pigeon

COPY . .

RUN apt-get update && \
  apt-get install -y --no-install-recommends libsodium-dev && \
  apt-get install -y --no-install-recommends libzmq3-dev && \
  apt-get install -y --no-install-recommends libczmq-dev && \
  go build cmd/main/pgd.go


FROM debian:buster-slim

RUN apt-get update && \
  apt-get install -y --no-install-recommends libsodium-dev && \
  apt-get install -y --no-install-recommends libzmq3-dev && \
  apt-get install -y --no-install-recommends libczmq-dev && \
  apt-get install -y --no-install-recommends python3 && \
  apt-get install -y --no-install-recommends python3-pip && \
  pip3 install jinja2

WORKDIR /root/

RUN mkdir logger

COPY --from=builder /src/pigeon/pgd .
COPY --from=builder /src/pigeon/logger logger

CMD ["./pgd"]

当然,我可以放弃多阶段构建,只使用golang1.12.9-busterfor build,继续for run,但这会使最终运行的图像更大(这是多阶段构建的优势)。

我错过了什么还是我不得不在上面做出选择?

标签: docker

解决方案


这是我对你的问题的看法:

FROM debian:buster-slim as base

RUN mkdir /debs /debs_tmp \
    && chmod 777 /debs /debs_tmp

WORKDIR /debs
RUN apt-get update \
    && apt-get install -y -d \
            --no-install-recommends \
            -o dir::cache::archives="/debs_tmp/" \
        libsodium-dev \
        libzmq3-dev \
        libczmq-dev \
    && mv /debs_tmp/*.deb /debs \
    && rm -rf /debs_tmp \
    && apt-get install -y --no-install-recommends \
        python3 \
        python3-pip \
    && pip3 install jinja2 \
    && rm -rf /var/lib/apt/lists/*


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

FROM golang:1.12.9-buster AS builder

COPY --from=base /debs /debs
WORKDIR /debs

RUN dpkg -i *.deb

WORKDIR /src/pigeon
COPY . .

RUN go build cmd/main/pgd.go

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

FROM base

RUN rm -rf /debs

WORKDIR /root/
RUN mkdir logger

COPY --from=builder /src/pigeon/pgd .
COPY --from=builder /src/pigeon/logger logger

CMD ["./pgd"]

您可以在临时文件夹中下载所需的包,将 debs 移动到新位置,最后COPY将 debs 移动到下一阶段。最后,您只需使用您创建的第一个图像。

顺便说一句,容器将以 root 身份运行。这可能是一个问题,具体取决于软件的功能,您可能需要考虑使用没有“权力”的用户。

编辑:对编辑感到抱歉,但我在本地运行了几个示例并且没有准备好 go 脚本。


推荐阅读