英文:
Docker: How to set env variable in one RUN command and use it in next RUN command?
问题
I'm trying to set a variable in a RUN
command and use it in the next RUN
command.
Depending on the TARGETARCH
arg, I'm trying to set PROTOC_ARCH
variable and use it in the next RUN
command to download an architecture-specific file. But the variable isn't passing through. If I print the variable, it's always empty.
FROM ubuntu
ARG TARGETARCH="arm64"
ENV PROTOC_ARCH=""
RUN if [ "$TARGETARCH" = "arm64" ]; then \
PROTOC_ARCH="aarch_64"; \
else \
PROTOC_ARCH="x86_64"; \
fi
RUN apt-get update && apt-get install -y wget
RUN echo "PROTOC_ARCH=$PROTOC_ARCH"
RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v22.2/protoc-22.2-linux-$PROTOC_ARCH.zip
Can anyone please tell me what I'm doing wrong here?
Thanks in advance.
英文:
I'm trying to set a variable in a RUN
command and use it in the next RUN
command.
Depending on the TARGETARCH
arg, I'm trying to set PROTOC_ARCH
variable and use it in the next RUN
command to download a architecture specific file. But the variable isn't passing through. If I print the variable, it's always empty.
FROM ubuntu
ARG TARGETARCH="arm64"
ENV PROTOC_ARCH=""
RUN if [ "$TARGETARCH" = "arm64" ]; then \
PROTOC_ARCH="aarch_64"; \
else \
PROTOC_ARCH="x86_64"; \
fi
RUN apt-get update && apt-get install -y wget
RUN echo "PROTOC_ARCH=$PROTOC_ARCH"
RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v22.2/protoc-22.2-linux-$PROTOC_ARCH.zip
Can anyone please tell me what I'm doing wrong here ?
Thanks in advance.
答案1
得分: 3
以下是您要的中文翻译部分:
不应将您的 Dockerfile 看作与带有状态的 shell 脚本相同。但是,您可以将繁重的工作移到一个 shell 脚本中,以访问所需的功能。示例 Dockerfile
:
FROM ubuntu
ARG TARGETARCH="arm64"
ENV TARGETARCH=$TARGETARCH
COPY init.sh /
RUN chmod +x /init.sh
CMD /init.sh
然后您的 init.sh
可以如下所示:
#!/bin/bash
if [ "$TARGETARCH" = "arm64" ]; then
PROTOC_ARCH="aarch_64"
else
PROTOC_ARCH="x86_64"
fi
echo PROTOC_ARCH is $PROTOC_ARCH and TARGETARCH is $TARGETARCH
现在您可以访问所期望的环境变量并进行条件性下载等操作。
这种模式很常见。您会发现很多 Docker 镜像使用:
ENTRYPOINT ["docker-entrypoint.sh"]
希望这对您有所帮助。
英文:
You should not think of your Dockerfile in the same way we think about shell scripts, with state. However, you can move your heavy lifting into a shell script to access desired functionality. Example Dockerfile
:
FROM ubuntu
ARG TARGETARCH="arm64"
ENV TARGETARCH=$TARGETARCH
COPY init.sh /
RUN chmod +x /init.sh
CMD /init.sh
And then your init.sh
could look like this:
#!/bin/bash
if [ "$TARGETARCH" = "arm64" ]; then
PROTOC_ARCH="aarch_64"
else
PROTOC_ARCH="x86_64"
fi
echo PROTOC_ARCH is $PROTOC_ARCH and TARGETARCH is $TARGETARCH
Now you can access the env vars you expect and do conditional downloads, etc.
This pattern is quite common. You will find a lot of docker images using:
ENTRYPOINT ["docker-entrypoint.sh"]
答案2
得分: 1
每个RUN语句都在单独的shell中运行。这意味着在RUN语句完成时,设置的任何环境变量都会丢失。
你可以在单个RUN语句中运行所有命令,就像这样:
FROM ubuntu
ARG TARGETARCH="arm64"
ENV PROTOC_ARCH=""
RUN if [ "$TARGETARCH" = "arm64" ]; then \
PROTOC_ARCH="aarch_64"; \
else \
PROTOC_ARCH="x86_64"; \
fi && \
apt-get update && apt-get install -y wget && \
echo "PROTOC_ARCH=$PROTOC_ARCH" && \
wget https://github.com/protocolbuffers/protobuf/releases/download/v22.2/protoc-22.2-linux-$PROTOC_ARCH.zip
然后,PROTOC_ARCH
将在wget
命令中可用,因为它直到完整的RUN语句完成之前都不会丢失。
需要注意的一点是,在运行时,PROTOC_ARCH
将为空,因为它是在放入镜像的ENV语句中设置的值。据我所知,在ENV语句中没有一种条件设置变量的方式。
英文:
Each RUN statement is run in a separate shell. That means that any environment variables you set are lost when the RUN statement finishes.
What you can do is run all your commands in a single RUN statement, like this
FROM ubuntu
ARG TARGETARCH="arm64"
ENV PROTOC_ARCH=""
RUN if [ "$TARGETARCH" = "arm64" ]; then \
PROTOC_ARCH="aarch_64"; \
else \
PROTOC_ARCH="x86_64"; \
fi && \
apt-get update && apt-get install -y wget && \
echo "PROTOC_ARCH=$PROTOC_ARCH" && \
wget https://github.com/protocolbuffers/protobuf/releases/download/v22.2/protoc-22.2-linux-$PROTOC_ARCH.zip
Then PROTOC_ARCH
will be available in the wget
command, since it's not lost until the complete RUN statement is finished.
One thing to note is that at run-time, PROTOC_ARCH
will be blank, since it's the value set in the ENV statement that is put in the image. AFAIK, there's no way to conditionally set a variable in an ENV statement.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论