<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>docker on </title>
    <link>/tags/docker/</link>
    <description>Recent content in docker on </description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Tue, 15 Sep 2026 20:30:00 +0800</lastBuildDate><atom:link href="/tags/docker/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>用 buildpack 构建 Spring Boot 镜像</title>
      <link>/posts/spring-boot-buildpacks-image/</link>
      <pubDate>Tue, 15 Sep 2026 20:30:00 +0800</pubDate>
      
      <guid>/posts/spring-boot-buildpacks-image/</guid>
      <description>Spring Boot 的 Maven 插件带了一个 spring-boot:build-image，项目里不用放 Dockerfile，一条命令就能出一个能跑的镜像。拿 start.spring.io 生成的 Spring Boot 4.1.1 空 web 项目，在一台 Apple Silicon 机器上试了一遍：48 秒出镜像，347MB，里面装的是 BellSoft Liberica JRE 25.0.4。而 pom 里写的是 &amp;lt;java.version&amp;gt;21&amp;lt;/java.version&amp;gt;。
镜像能跑，该有的也都有，代价是里面几乎每一样东西都由 buildpack 替你挑，包括那个 JRE 25。Spring I/O 2026 上 Anthony Dahanne 那场 Paketo Buildpacks 的分享讲的就是这套东西。下面是照着它在本机跑一遍的结果。
buildpack、builder、run image 各管什么 Dockerfile 的模型是每一步都由你写出来：从哪个基础镜像起、把什么复制进去、装什么、用什么命令启动。镜像里有什么、缺什么，都算在写的人头上。
buildpack 换了个分法。一个 buildpack 是一对脚本，detect 判断这个项目用不用得上它，build 在用得上的时候往镜像里加东西。每个只管一件小事：一个装 JRE，一个装 CA 证书，一个把 Spring Boot 的 jar 切成几层。谁该出场不用人指定，由 detect 自己判断。
调度这套流程的程序叫 lifecycle，构建日志里那几行大写的 ===&amp;gt; DETECTING 就是它的阶段名。它要用到两个镜像：
builder：构建时用的镜像，里面装着一整组 buildpack、lifecycle 本身，以及编译要用的 JDK 之类的工具。 run image：最终镜像的底座，应用的那几层叠在它上面。 构建工具链不进最终镜像，就是靠这两个分开：JDK 待在 builder 里，最终镜像里只剩 JRE。</description>
    </item>
    
  </channel>
</rss>
