You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker多阶段构建中FROM scratch无法复制二进制文件求助

问题描述

Docker多阶段构建时,builder阶段已成功生成/bin/tracking二进制文件,但使用FROM scratch作为第二阶段基础镜像时,执行容器提示exec /bin/tracking: no such file or directory;替换为FROM golang:alpine则可正常运行。尝试过相对路径、绝对路径、设置WORKDIR等方法均未解决,需保留FROM scratch配置。

相关Dockerfile代码:

# golang:1.24.0-alpine3.21 using manifest digest (linux/amd64)
FROM --platform=linux/amd64 golang:1.24.0-alpine3.21@sha256:2d40d4fc278dad38be0777d5e2a88a2c6dee51b0b29c97a764fc6c6a11ca893c AS builder

WORKDIR /app

ARG GITHUB_TOKEN
ARG REVISION
ARG TAG
ARG BUILDINFO=github.com/private-digital/foe-tracking/internal/version

# Create appuser.
ENV USER=appuser
ENV UID=1000

RUN adduser \
    --disabled-password \
    --gecos "" \
    --home "/nonexistent" \
    --shell "/sbin/nologin" \
    --no-create-home \
    --uid "${UID}" \
    "${USER}"

ENV PATH=$PATH:/usr/local/go/bin
RUN go env -w GOPRIVATE="github.com/private-digital/*"

RUN pwd && ls -al

USER root
# Install git and certificates
# Git is required for fetching the dependencies.
RUN apk update && apk add --no-cache gcc musl-dev git ca-certificates wget gcompat openssl

# Prepare access to private repos
RUN git config --global url."https://${GITHUB_TOKEN}@github.com/private-digital/".insteadOf "https://github.com/private-digital/"

# Copy files

COPY . .

RUN go mod download
RUN go mod verify


RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -x -v -ldflags="-w -s -X '${BUILDINFO}.Version=${TAG}' -X '${BUILDINFO}.Commit=${REVISION}'" -o /bin/tracking ./cmd/tracking/main.go

RUN pwd && ls -al /bin

RUN ls -al /app && [ -f /bin/tracking ] && echo "Binary exists" || echo "Binary does not exist"

# Binary exists

FROM scratch

USER appuser:appuser
# Define arguments
ARG CREATED
ARG REVISION
ARG TAG

# Add Maintainer Info
LABEL org.opencontainers.image.authors="FOE-Tracking"
LABEL org.opencontainers.image.created="${CREATED}"
LABEL org.opencontainers.image.revision="${REVISION}"
LABEL org.opencontainers.image.tag="${TAG}"

# Import the user, group and certificate files from the builder.
COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=0 /etc/passwd /etc/passwd
COPY --from=0 /etc/group /etc/group
# copy executable
COPY --from=0 /bin/tracking /bin/tracking

# Run the binary - exec /bin/tracking: no such file or directory
ENTRYPOINT ["/bin/tracking"]
解决方案

核心问题是启用了CGO(CGO_ENABLED=1)编译,生成的是动态链接二进制文件,而scratch镜像不含任何系统依赖库(如musl libc),导致系统无法找到二进制依赖的运行时组件,最终误报“文件不存在”。

修复步骤:

  • 修改编译命令为静态编译:
    将builder阶段的go build命令中CGO_ENABLED=1改为CGO_ENABLED=0,同时添加-tags netgo确保网络相关依赖也静态编译:

    RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -x -v -tags netgo -ldflags="-w -s -X '${BUILDINFO}.Version=${TAG}' -X '${BUILDINFO}.Commit=${REVISION}'" -o /bin/tracking ./cmd/tracking/main.go
    

    (若代码必须依赖CGO无法禁用,需手动将依赖的系统库从builder镜像复制到scratch镜像中,但静态编译是适配scratch的最优方案)

  • 验证静态编译结果:
    在builder阶段添加以下命令,确认二进制为静态链接:

    RUN ldd /bin/tracking || echo "Static binary"
    

    输出Static binary即表示编译正确,无动态依赖。

  • 确保执行权限:
    可在builder阶段编译后显式添加执行权限(默认已有,但显式设置更稳妥):

    RUN chmod +x /bin/tracking
    

内容的提问来源于stack exchange,提问作者Ravi Parekh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 07:16:15