Docker Shell形式ENTRYPOINT未加载默认环境变量,未传参时报错
问题
我参考过一篇Stack Overflow的答案来解决问题,但它似乎不适用于我的场景。我在Dockerfile里设置了以下环境变量:
ENV API="list,create,delete" ENV ID="1-1" ENV VERBO=5
ENTRYPOINT采用Shell形式编写:
ENTRYPOINT /myapp --id=$ID --api=$API --origin="*" --trace --metrics --verbosity=$VERBO --allow-insecure
但当我不通过docker run命令传入VERBO参数时(即执行docker run -p 80:8080 $DOCKER_IMAGE),总会报错invalid value "" for flag -verbosity:;而通过docker run -p 80:8080 -e VERBO=4 $DOCKER_IMAGE指定参数时,应用似乎能正常运行。我想确认这种用法是否正确,因为VERBO设计为可选参数,无需每次docker run都设置。以下是完整的Dockerfile:
FROM golang:1.19-alpine as builder RUN apk add --no-cache make gcc musl-dev linux-headers git WORKDIR /go/myapp COPY . . ARG GOPROXY RUN go mod download RUN make myapp ENV API="list,create,delete" ENV ID="1-1" ENV VERBO=5 FROM alpine:latest RUN apk add --no-cache ca-certificates COPY --from=builder /go/myapp/build/myapp / ENTRYPOINT /myapp --id=$ID --api=$API --origin="*" --trace --metrics --verbosity=$VERBO --allow-insecure
解决方法
问题核心是环境变量设置阶段错误:你把ENV指令写在了builder构建阶段,而非最终运行的alpine:latest阶段。Docker多阶段构建中,各阶段的环境变量相互独立,最终镜像只会保留最后一个阶段的环境变量,所以你的VERBO=5并没有被带入到运行镜像里。当不通过docker run传入VERBO时,$VERBO会被解析为空字符串,导致应用的--verbosity参数无有效取值,触发报错。
修正后的Dockerfile需将ENV指令移至FROM alpine:latest阶段之后:
FROM golang:1.19-alpine as builder RUN apk add --no-cache make gcc musl-dev linux-headers git WORKDIR /go/myapp COPY . . ARG GOPROXY RUN go mod download RUN make myapp FROM alpine:latest RUN apk add --no-cache ca-certificates # 将环境变量移至当前运行阶段 ENV API="list,create,delete" ENV ID="1-1" ENV VERBO=5 COPY --from=builder /go/myapp/build/myapp / ENTRYPOINT /myapp --id=$ID --api=$API --origin="*" --trace --metrics --verbosity=$VERBO --allow-insecure
修改后,最终镜像会默认携带VERBO=5的环境变量,不传入自定义值时,应用会使用默认的5作为verbosity参数,不会再出现空值报错。
内容的提问来源于stack exchange,提问作者unsafe_where_true
相关产品推荐
相关产品推荐

