Docker 构建后符号链接变成自引用,而非指向期望的可执行文件?

新手上路,请多包涵

问题描述

在构建 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 . 吗?
在错误的情况下,打包过程究竟发生了什么?

阅读 1.1k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题