云原生运维【免费下载链接】docker-alpineAlpine Linux Docker image. Win at minimalism!项目地址https://gitcode.com/gh_mirrors/do/docker-alpine点击查看免费下载本篇技术指南围绕 docker-alpine 仓库中的 builder/README.md 展开深入讲解该构建器镜像如何通过mkimage-alpine.bash脚本从 Alpine 官方软件源生成最小化的rootfs.tar.xz根文件系统并逐一剖析-r、-m、-s、-c、-e、-d、-E、-t、-p、-b、-a全部选项的底层实现与真实用法。读完本文你将理解 docker-alpine 官方alpine镜像与gliderlabs/alpine镜像背后的构建原理掌握通过一条docker run命令为任意版本、任意架构的 Alpine 生成定制 rootfs 的完整实战方案。构建器是什么把造镜像变成一条命令docker-alpine 的目标是产出极小的 Alpine Linux Docker 基础镜像仓库 README.md 中描述的镜像仅约 5 MB。要得到这样一个镜像第一步不是手工chroot拼装文件系统而是先构建出一个Alpine Linux rootfs Builder——一个专门负责从零生成 Alpine 根文件系统的辅助镜像。builder/README.md 明确指出这个构建器镜像负责构造一个rootfs.tar.xz供后续构建基础 Alpine 镜像时使用重头戏由mkimage-alpine.sh脚本完成在配置镜像的过程中还会加入自带的apk-install便利脚本。当前仓库中该脚本的实际文件名是mkimage-alpine.bash见 builder/scripts/mkimage-alpine.bashREADME 中的.sh是历史命名习惯读者阅读源码时以.bash文件为准。构建器的 Dockerfile 结构builder/Dockerfile 完整定义了构建器镜像本身FROM alpine:latest COPY scripts/mkimage-alpine.bash scripts/apk-install / RUN apk add --no-cache bash tzdata xz ENTRYPOINT [/mkimage-alpine.bash]三个要点值得注意基础镜像直接选用alpine:latest构建器自身就是 Alpine天然具备apk包管理能力后续生成 rootfs 时直接复用宿主环境里的apk与/etc/apk/keys密钥目录依赖只有bash、tzdata、xz三个包bash用于执行脚本tzdata用于在设置时区选项-t时提供/usr/share/zoneinfo数据xz用于最终以tar -Jxz 压缩打包rootfs.tar.xzENTRYPOINT直接指向脚本也就是说docker run该构建器镜像时传入的参数会原样交给mkimage-alpine.bash解析docker run builder-image -r v3.9 -m mirror ...等价于直接执行脚本。一次构建的完整工作流结合 builder/scripts/mkimage-alpine.bash 的build()函数一次构建按以下顺序进行在${TMPDIR:-/var/tmp}下用mktemp -d创建临时目录作为 rootfs 骨架写入/etc/apk/repositories仓库列表main、community、可选的edge/testing引脚用apk --root $rootfs add --initdb把选定包安装进 rootfs--initdb初始化 apk 数据库相当于无中生有地建立包管理状态根据选项追加 baselayout、时区、root 密码禁用、apk-install脚本等定制内容清理/var/cache/apk/*包缓存用tar -J以--numeric-owner保留数字属主、避免 UID/GID 映射问题并--excludedev/*剔除设备节点设备由 Docker 运行时注入打包成rootfs.tar.xz。最终产物再被 versions/library-edge/x86_64/Dockerfile 这种极简 Dockerfile 消费FROM scratch ADD rootfs.tar.xz / CMD [/bin/sh]FROM scratchADD rootfs.tar.xz /正是把构建器产物直接铺成镜像根文件系统的标准做法构建出的镜像仅包含 rootfs 里的内容没有任何冗余层。选项全解从 README 到源码的逐项剖析builder/README.md 列出了构建器支持的全部选项下表先给出总览随后逐项结合源码展开选项参数作用默认值-rrelease使用的发布标签如edge、v3.1edge-mmirror镜像源 URL 基地址http://nl.alpinelinux.org/alpine-s无将rootfs.tar.xz输出到 stdout关闭-c无向生成的 rootfs 中加入apk-install脚本关闭-e无在 repositories 文件中追加edge/main与edge/testing引脚关闭-d无通过移除空 root 密码禁用su到 root关闭-E无不把community写入 repositories无 community 仓库的版本必需关闭-ttimezone设置时区不设置-ppackages逗号分隔的包列表alpine-base-b无将alpine-base无依赖地解包进 rootfs供-p精简后仍需要/etc/*-release与/etc/issue的场景关闭-aarchitecture下载 rootfs 时使用的架构x86_64选项解析入口main()函数所有选项最终由 builder/scripts/mkimage-alpine.bash 的main()函数用getopts hr:m:t:sEecdp:ba:解析并映射为内部环境变量-r→RELrelease-m→MIRROR注意源码里做了${OPTARG%/}处理自动去掉参数末尾多余的/-s→STDOUT-E→OMIT_COMMUNITY-e→REPO_EXTRA-t→TIMEZONE-c→ADD_APK_SCRIPT-p→PACKAGES-b→ADD_BASELAYOUT-d→DISABLE_ROOT_PASSWD-a→ARCH脚本开头还声明了两个可被外部环境覆盖的变量builder/scripts/mkimage-alpine.bashdeclare REL${REL:-edge} declare MIRROR${MIRROR:-http://nl.alpinelinux.org/alpine}即release 与 mirror 也可以通过环境变量REL/MIRROR注入命令行选项只是覆盖它们的另一种方式。此外设置TRACE环境变量可开启set -x调试输出脚本还强制要求以 root 运行id -u必须为 0否则直接报错退出。-r release决定拉取哪个发布分支REL直接拼进仓库地址$mirror/$rel/main。仓库中的真实用法既包含稳定版本号v3.9、v3.1也包含滚动分支edge。例如 versions/library-3.9/x86_64/options 中RELEASEv3.9而 versions/library-edge/x86_64/options 中RELEASEedge。需要说明的是-r只影响 apk 仓库路径与后续 fetch 行为edge分支对应持续更新的滚动版本适合尝鲜生产环境一般固定到vX.Y。-m mirror镜像源基地址MIRROR默认指向http://nl.alpinelinux.org/alpine仓库实际构建时换用了 CDN 镜像http://dl-cdn.alpinelinux.org/alpine见 versions/library-edge/x86_64/optionsgliderlabs 变体则使用http://alpine.gliderlabs.com/alpine见 versions/gliderlabs-3.9/options。仓库地址最终形态是$mirror/$rel/main、$mirror/$rel/community。如果你的网络环境里默认镜像不可达这就是第一个要改的参数。-s把产物打到 stdout设置STDOUT1后构建脚本在打包完成后执行cat rootfs.tar.xz将二进制流输出到标准输出builder/scripts/mkimage-alpine.bash。这一设计使得构建过程可以嵌入管道链例如配合docker build时把 stdout 直接喂给ADD或通过docker run ... -s rootfs.tar.xz落盘。官方两种镜像的构建选项versions/*/options中普遍带-s因为后续需要把 rootfs 传给FROM scratch的镜像构建。-c注入apk-install便利脚本当ADD_APK_SCRIPT1时脚本会把构建器镜像根目录下的/apk-install复制到 rootfs 的/usr/sbin/apk-installbuilder/scripts/mkimage-alpine.bash。该脚本内容极简builder/scripts/apk-install#!/bin/sh apk add --update-cache $ rm -rf /var/cache/apk/*即安装包并顺手清空缓存避免镜像里残留apk索引缓存。这个开关只被gliderlabs变体使用如 versions/gliderlabs-3.9/options 的BUILD_OPTIONS含-c官方alpine镜像刻意不装它。这一点被测试用例严格校验test/test_alpine-3.9.bats中断言which apk-install必须失败而test/test_gliderlabs_alpine-3.9.bats中断言必须存在见 test/test_alpine-3.9.bats 与 test/test_gliderlabs_alpine-3.9.bats。-e追加 edge 仓库引脚当REPO_EXTRA1时repositories 文件会追加edge $mirror/edge/main与testing $mirror/edge/testing两行builder/scripts/mkimage-alpine.bash。注意一个细节如果当前rel本身就是edge则只追加testing一行避免出现edge .../edge/main自引用。仓库别名edge、testing让用户可以用apk add edge 包名从指定仓库安装较新软件而不污染默认仓库的解析顺序。-d禁用 root 空密码DISABLE_ROOT_PASSWD1时脚本对 rootfs 中的/etc/shadow执行sed -ie s/^root::/root:!:/ $rootfs/etc/shadowAlpine 默认 root 密码为空su可直接提权把密码位从空改成!后su因无有效密码而失败从而禁用以非 root 用户身份提权。该行为同样被测试覆盖docker run --user nobody alpine:3.9 su必须返回失败见 test/test_alpine-3.9.bats。-E省略 community 仓库OMIT_COMMUNITY1时 repositories 文件只写$mirror/$rel/main一行。这是为没有community仓库的早期版本准备的——例如 versions/library-3.1/options 的BUILD_OPTIONS(-d -s -E -t UTC -r v3.1 -m ...)就带-E。如果你的目标版本确实没有 community 仓库却忘了加-Eapk add会在解析不存在的仓库时失败。-t timezone设置时区TIMEZONE非空时脚本分三步完成时区注入builder/scripts/mkimage-alpine.bash以虚拟包名.timezone临时安装tzdataapk add -t .timezone tzdata把/usr/share/zoneinfo/$TIMEZONE复制为/etc/localtime卸载虚拟包apk del --purge .timezone从而不把tzdata留在最终镜像里。这种用完即弃的技巧正是仓库里反复出现的虚拟包-t/--virtual思想在构建器中的一次实践。官方构建统一使用-t UTC见 versions/library-3.9/x86_64/options测试也断言容器内date %Z输出UTC见 test/test_alpine-3.9.bats。-p packages自定义安装包列表PACKAGES默认alpine-base会被拆成apk add的参数源码里${packages[*]//,/ }把逗号替换为空格。官方alpine镜像为了把体积压到最小改用更精简的包组合例如 versions/library-edge/x86_64/optionsexport PACKAGESbusybox,alpine-baselayout,apk-tools,alpine-keys,libc-utils注意组合里保留了alpine-keys提供签名密钥与apk-tools提供包管理器同时用-b补回 release 信息文件——这正是下一节-b的典型配套场景。-b无依赖解包 alpine-base当ADD_BASELAYOUT1时脚本执行builder/scripts/mkimage-alpine.bashapk --root $rootfs --keys-dir /etc/apk/keys \ fetch --stdout --arch $arch alpine-base | tar -xvz -C $rootfs etc即只下载alpine-base包、不解依赖仅把其中的etc/内容/etc/os-release、/etc/issue等版本与发行标识文件解压进 rootfs。这样-p精简过的镜像虽然没有安装完整alpine-base依然能正确报告系统版本cat /etc/os-release依旧可用——官方镜像测试里第一项就是校验VERSION_ID见 test/test_alpine-3.9.bats。-a architecture跨架构构建ARCH默认x86_64透传给apk add --arch与apk fetch --arch用于下载指定架构的包。仓库在 multi-arch 层面还有另一条路径对3.6及更早版本versions/library-3.6/*/options直接通过PULL_URL下载官方alpine-minirootfs压缩包如 versions/library-3.6/aarch64/options 中的alpine-minirootfs-3.6.3-${ARCH}.tar.gz其产物为rootfs.tar.gz且对应 Dockerfile 额外COPY UTC /etc/localtime保证 UTC 时区见 versions/library-3.6/aarch64/Dockerfile。这是以仓库源码为准的两种实现并存新版走-a参数由apk直接组装旧版走官方 minirootfs 下载。实战把选项组合成一次真实的构建方式一直接docker run构建器参照 builder/Dockerfile 的ENTRYPOINT构建器镜像本身就是可执行脚本。假设已在本仓库根目录构建好构建器镜像镜像名暂记为alpine-builder生成 v3.9 的 x86_64 rootfs 可执行$ docker run --rm alpine-builder \ -r v3.9 -m http://dl-cdn.alpinelinux.org/alpine \ -s -b -t UTC -p busybox,alpine-baselayout,apk-tools,alpine-keys,libc-utils \ rootfs.tar.xz得到的rootfs.tar.xz再用FROM scratchADD rootfs.tar.xz /的 Dockerfile 即可构建出最终基础镜像。方式二以仓库 options 文件为模板仓库内每个版本目录都存放了经过验证的构建参数是最可靠的配方。以 versions/gliderlabs-3.9/options 为例export RELEASEv3.9 export MIRRORhttp://alpine.gliderlabs.com/alpine export PACKAGESalpine-baselayout,alpine-keys,apk-tools,libc-utils export BUILD_OPTIONS(-b -s -c -t UTC -r $RELEASE -m $MIRROR -p $PACKAGES) export TAGS(gliderlabs/alpine:3.9 gliderlabs/alpine:latest)对照前文表格可以反推每个开关的设计意图-b补 release 文件、-s输出到 stdout、-c注入apk-install、-t UTC固定时区、-p精简包集合。官方库版本versions/library-edge/x86_64/options则去掉-c并改用 CDN 镜像——这正是官方与 gliderlabs 变体在构建选项层面的核心差异。参数组合速查目标效果推荐组合官方alpine风格最小镜像3.9-b -s -t UTC -r vX.Y -m mirror -p busybox,alpine-baselayout,apk-tools,alpine-keys,libc-utilsgliderlabs 风格含apk-install上面组合再加-c无 community 仓库的旧版本如 3.1加-E需要额外仓库引脚加-e需要禁用 root 空密码提权加-d跨架构产物加-a aarch64或改用旧版PULL_URL路径产物验证测试用例如何保障构建正确性仓库test/目录下的 bats 测试如 test/test_alpine-3.9.bats为构建选项的每一项效果提供了可执行断言也即构建器的输出必须满足的契约版本正确cat /etc/os-release第二行VERSION_ID与目标版本一致对应-b/-p的产物完整性包可安装apk add --no-cache libressl成功说明apk-tools、alpine-keys与仓库列表配置正确时区为 UTCdate %Z输出UTC对应-t UTCapk-install存在与否官方镜像断言缺失、gliderlabs 镜像断言存在对应-c的差异仓库列表正确逐行比对/etc/apk/repositories中main/community行对应-m、-r、-E的组合结果缓存为空/var/cache/apk下文件数为 0对应构建收尾的rm -f $rootfs/var/cache/apk/*root 密码被禁用docker run --user nobody ... su失败对应-d无设备节点docker export后 tar 列表里不存在dev/null对应打包时的--excludedev/*。这些测试把 README 中每个选项的语义固化成了可重复验证的行为读者在自定义构建选项时可以直接以它们为验收标准。小结docker-alpine 的构建器把生成 Alpine rootfs抽象成了寥寥几个开关-r/-m决定从哪里取什么版本-p/-b/-a决定装什么包、补什么文件、用什么架构-s/-c/-e/-d/-E/-t决定产物如何交付与定制。理解 builder/README.md 中这 11 个选项再对照 builder/scripts/mkimage-alpine.bash 的源码实现与 versions/ 下的真实配方你就能像仓库 CI 一样为任意 Alpine 版本和架构定制出最小化、无缓存、可验证的基础镜像。赞分享云原生运维【免费下载链接】docker-alpineAlpine Linux Docker image. Win at minimalism!项目地址https://gitcode.com/gh_mirrors/do/docker-alpine点击查看免费下载相关推荐Alpine Linux Docker镜像构建终极指南mkimage-alpine.bash脚本完全解析Alpine Linux Docker镜像构建终极指南mkimage alpine.bash脚本完全解析 Alpine Linux作为轻量级Docker镜像的云原生运维Nexe与Docker构建最小化容器镜像Nexe与Docker构建最小化容器镜像 你还在为Node.js应用的Docker镜像体积过大而烦恼吗传统Node.js容器动辄数百MB不仅浪费存储空间构建工具开发工具CLI大麦自动抢票脚本完整指南3 步部署 Web 与移动端双端抢票大麦自动抢票脚本完整指南3 步部署 Web 与移动端双端抢票 ticket purchase 是一个面向大麦网的自动化抢票工具用 Python 驱动浏览器与GUI 自动化RPA上一篇Apache Hudi Flink 分区感知的 RocksDB 记录索引缓存RFC-107 设计与实践指南下一篇如何高效下载HuggingFace模型开发者的专业工具指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考