问题描述
在构建 Docker 镜像时,项目源代码中存在一个与 ln -sf patrol /app/service 同名的空目录 service 。其被复制到 /app 目录下,并执行了创建链接的命令(不知道执行是否成功)。
但在最终的 Runtime 阶段镜像中,本应在 /app 目录下的 service 却变成了一个指向自身的符号链接 controller ,而不是预期的可执行文件 service 。
也就是说,错误的最终镜像里出现了一个自引用的软链接现象。
关键 Dockerfile 片段
# Build stage
FROM debian:bullseye-slim AS builder
# 配置 Go 编译环境,如安装 wget、tar、git、go 等工具(省略)
WORKDIR /app
# 复制项目代码
COPY . .
# 下载依赖模块
RUN go mod download
# 编译并创建软链接
RUN go build -ldflags "-s -w" -o controller ./cmd/controller && \
ln -sf controller /app/service
# Runtime stage
FROM debian:bullseye-slim
WORKDIR /app
# 环境配置等(省略)
# 复制构建结果
COPY --from=builder /app/service .构建命令
docker build -t app-controller .
错误镜像(存在service同名空文件夹打包)
$ docker run -it --entrypoint /bin/sh cb4edd601f68
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
# pwd
/app
# ls
controller entrypoint.sh service_name
# ls -la
total 16
drwxr-xr-x 2 root root 4096 Oct 21 09:03 .
dr-xr-xr-x 22 root root 4096 Oct 21 11:21 ..
lrwxrwxrwx 1 root root 15 Oct 21 09:03 controller -> /app/controller
-rwxrwxr-x 1 root root 519 Oct 20 06:54 entrypoint.sh
-rw-r--r-- 1 root root 11 Oct 20 09:29 service_name
# ./controller
/bin/sh: 4: ./controller: Too many levels of symbolic links
# exit正确镜像(删除了service同名空文件夹打包)
$ docker run -it --entrypoint /bin/sh d8a43f83bd8a
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
# ls
entrypoint.sh service service_name
# ls -la
total 17996
drwxr-xr-x 2 root root 4096 Oct 21 11:26 .
dr-xr-xr-x 22 root root 4096 Oct 21 11:27 ..
-rwxrwxr-x 1 root root 519 Oct 20 06:54 entrypoint.sh
-rwxr-xr-x 1 root root 18407608 Oct 21 11:26 service
-rw-r--r-- 1 root root 11 Oct 20 09:29 service_name
# ./service
2025-10-21T11:28:22.847Z INFO /app/cmd/controller/main.go:35 NOTraceID env config path: .env
...期待解答
我想问的就是,为什么在错误镜像中,会有指向自身的符号链接 controller ,复制的时候不是执行的 COPY --from=builder /app/service . 吗?
在错误的情况下,打包过程究竟发生了什么?