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.
2
Answers
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
Then
PROTOC_ARCH
will be available in thewget
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.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
:And then your
init.sh
could look like this: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: