原文作者:atsigncompany.medium.com/
发布时间:2021年5月10日 - 4分钟阅读
作者:Chris Swan,The @ Company的工程师
上周,我写了一篇关于使用GitHub Actions构建多架构Docker镜像的自动化操作。这让我想到了另一个问题--如何创建二进制文件以用于这些构建?如果我正在制作一个Arm镜像,那么我需要一个Arm二进制文件来放入该镜像。
目前,dart compile只为它所运行的架构编译独立的可执行文件。这是一个耻辱,因为底层工具完全能够进行交叉编译,正如J-P Nurmi在交叉编译Dart应用程序中所解释的那样。
如果没有交叉编译,唯一的选择就是在每个目标平台上运行Dart SDK的dart compile。谷歌将SDK打包成一个Docker镜像google/dart,但不幸的是,这只适用于x86_64(又称amd64)。该镜像的Docker文件也使用了SDK apt包,但它也只适用于x86_64。
所以为了在多个架构上运行dart编译,我首先需要一个多架构的构建镜像。
FROM debian:stable
ARG DART_VERSION="2.12.4"
WORKDIR /tmp/
RUN \
apt-get -q update && apt-get install --no-install-recommends -y -q \
gnupg2 curl git ca-certificates unzip openssh-client && \
case "$(uname -m)" in armv7l | armv7) ARCH="arm";; aarch64) ARCH="arm64";; *) ARCH="x64";; esac && \
curl -O https://storage.googleapis.com/dart-archive/channels/stable/release/$DART_VERSION/sdk/dartsdk-linux-$ARCH-release.zip && \
unzip dartsdk-linux-$ARCH-release.zip -d /usr/lib/ && \
rm dartsdk-linux-$ARCH-release.zip && \
mv /usr/lib/dart-sdk /usr/lib/dart
ENV DART_SDK /usr/lib/dart
ENV PATH $DART_SDK/bin:/root/.pub-cache/bin:$PATH
这就是安装一些关键的依赖项(与google/dart相同),然后根据uname -m的输出下载并安装Dart SDK,以建立底层架构。 有了构建镜像,就可以在谷歌工程师Tony Pujals的subfuzion/dart-docker-slim的工作基础上创建一个轻量级的运行镜像。
# Originally based on subfuzion/dart-docker-slim
# Using our buildimage as it supports x64|arm|arm64
FROM atsigncompany/buildimage AS dart
# Do all the copying to an output dir here first
# as the buildimage has a shell that can be used
# for multi-arch conditionals
RUN \
mkdir -p /output/lib && mkdir -p /output/etc && \
mkdir -p /output/etc/ssl/certs && \
mkdir -p /output/usr/share/ca-certificates && \
case "$(uname -m)" in \
armv7l | armv7) ARCH="arm-linux-gnueabihf" ; \
mkdir -p /output/lib/$ARCH ; \
cp /lib/ld-linux-armhf.so.3 /output/lib/ld-linux-armhf.so.3 ; \
cp /lib/arm-linux-gnueabihf/ld-linux-armhf.so.3 \
/output/lib/arm-linux-gnueabihf/ld-linux-armhf.so.3 ;; \
aarch64) ARCH="aarch64-linux-gnu" ; \
mkdir -p /output/lib/$ARCH ; \
cp /lib/ld-linux-aarch64.so.1 /output/lib/ld-linux-aarch64.so.1 ; \
cp /lib/aarch64-linux-gnu/ld-linux-aarch64.so.1 \
/output/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1 ;; \
*) ARCH="x86_64-linux-gnu" ; \
mkdir -p /output/lib/$ARCH ; mkdir -p /output/lib64/ ; \
cp /lib64/ld-linux-x86-64.so.2 /output/lib64/ld-linux-x86-64.so.2 ;; \
esac && \
cp /lib/$ARCH/libdl.so.2 /output/lib/$ARCH/libdl.so.2 && \
cp /lib/$ARCH/libc.so.6 /output/lib/$ARCH/libc.so.6 && \
cp /lib/$ARCH/libm.so.6 /output/lib/$ARCH/libm.so.6 && \
cp /lib/$ARCH/librt.so.1 /output/lib/$ARCH/librt.so.1 && \
cp /lib/$ARCH/libpthread.so.0 /output/lib/$ARCH/libpthread.so.0 && \
cp /lib/$ARCH/libnss_dns.so.2 /output/lib/$ARCH/libnss_dns.so.2 && \
cp /lib/$ARCH/libresolv.so.2 /output/lib/$ARCH/libresolv.so.2 && \
cp /etc/nsswitch.conf /output/etc/nsswitch.conf && \
cp /etc/resolv.conf /output/etc/resolv.conf && \
cp -R /usr/share/ca-certificates /output/usr/share/ca-certificates && \
cp -R /etc/ssl/certs /output/etc/ssl/certs
FROM scratch
COPY --from=dart /output /
# Is this even really needed, as Docker uses host hosts?
COPY ./at-runimage/etc-hosts /etc/hosts
这也是使用uname -m的输出来确定从构建镜像中复制进来的正确依赖关系。
然后,构建镜像和运行镜像可以与Dart应用程序结合起来。我做了一个微不足道的dartshowplatform,打印出版本和平台信息。
$ sudo docker run -it atsigncompany/dartshowplatform
2.12.4 (stable) (Thu Apr 15 12:26:53 2021 +0200) on "linux_arm64"
这里是Docker文件。
FROM atsigncompany/buildimage
WORKDIR /app
COPY ./dartshowplatform/showplatform.dart .
RUN dart compile exe /app/showplatform.dart -o /app/dartshowplatform
FROM atsigncompany/runimage
COPY --from=0 /app/dartshowplatform /app/dartshowplatform
ENTRYPOINT ["/app/dartshowplatform"]
构建镜像用于运行dart编译,然后将其创建的二进制文件复制到运行镜像中。
上述内容的完整源代码等可在GitHub atsign-company/at_dockerfiles上找到。
如果你想知道我们为什么要这样做,那是因为人们要求我们支持Arm和Arm64,因为如上所述,Arm的足迹有巨大的增长。我们可以预计,不久之后,我们也将不得不增加对RISC-V的支持,因为该指令集架构(ISA)获得了牵引力和更广泛的采用。WinTel霸权的日子已经过去了,这意味着要处理更多的异质性,这需要更多的自动化来避免被这一切的复杂性所淹没。
The @ Company是一家科技创业公司,致力于改变现代互联网对待人们数据的方式。要了解更多关于The @ Company和他们的使命,请查看他们的网站。
在Twitter上关注Flutter社区:www.twitter.com/FlutterComm
通过www.DeepL.com/Translator(免费版)翻译