0

Inside my dockerfile:


ENV MY_ENCODED_VALUE="bXkgbmFtZSBpcyByYWtpYgo="

ENV MY_DECODED_VALUE=$(echo $MY_ENCODED_VALUE | base64 -d)

in the second line, i want to decode the encoded value and put the decoded value into my environment variable.


But i am getting the following error

Error response from daemon: failed to parse dockerfile: Syntax error - can't find = in "$MY_ENCODED_VALUE". Must be of the form: name=value


What does it even mean? What's supposed to be the right syntax here?

Rakib
  • 12,376
  • 16
  • 77
  • 113
  • Is your "MY_ENCODED_VALUE" static. I mean, for each time you build new image, are you willing to change this value or let it be same? – Kapil Khandelwal Apr 17 '20 at 08:06
  • it will stay same – Rakib Apr 17 '20 at 08:08
  • please refer https://stackoverflow.com/questions/30494050/how-do-i-pass-environment-variables-to-docker-containers – Andy Wong Apr 17 '20 at 08:23
  • @Rakib: Do you need it only when doing the build or later as well? – Technext Apr 17 '20 at 08:39
  • Hi @Technext @AndyWong i only need it during the build process. I will not need it in the running container. So i am not looking to set env in `docker run`. For now, i am just not able to make it work because of the syntax inside dockerfile. – Rakib Apr 17 '20 at 08:45
  • @Rakib: Check updated answer. – Technext Apr 17 '20 at 09:01
  • Given that specific base64-encoded value, you can include the decoded string in an `ENV` statement directly. In the more general case, this isn't something you can set directly in the Dockerfile; the linked question has the typical workarounds. – David Maze Apr 17 '20 at 11:16
  • This specific base64-encoded value is just for example. Consider it a very long encoded string that is coming from some other source in our setup. – Rakib Apr 17 '20 at 14:22
  • in that case, can we conclude that it's not possible to interpolate shell commands on a `ENV` step in dockerfile? That an `ENV` step can only accept simple `key=value` format for setting it in a dockerfile? – Rakib Apr 17 '20 at 14:40
  • i understand passing in docker-run is an option. Just wanna make sure we understand that interpolation is not possile in `ENV` step in a dockerfile – Rakib Apr 17 '20 at 14:41

1 Answers1

0

As you've mentioned that you need to use the variable during build time only, this should do the job:

Dockerfile:

FROM node:alpine
ENV MY_ENCODED_VALUE "bXkgbmFtZSBpcyByYWtpYgo="
RUN echo $MY_ENCODED_VALUE | base64 -d > /root/temp
RUN MY_DECODED_VALUE=$(cat /root/temp); echo "Output: $MY_DECODED_VALUE"

Output:

$ docker build -t test .
Sending build context to Docker daemon   2.56kB
Step 1/4 : FROM node:alpine
 ---> bcfeabd22749
Step 2/4 : ENV MY_ENCODED_VALUE "bXkgbmFtZSBpcyByYWtpYgo="
 ---> Using cache
 ---> 81084f4be2e4
Step 3/4 : RUN echo $MY_ENCODED_VALUE | base64 -d > /root/temp
 ---> Using cache
 ---> b8ad3a100746
Step 4/4 : RUN MY_DECODED_VALUE=$(cat /root/temp); echo "Output: $MY_DECODED_VALUE"
 ---> Running in c9c41b92dee0
Output: my name is rakib
Removing intermediate container c9c41b92dee0
 ---> acfcd422a8ed
Successfully built acfcd422a8ed
Successfully tagged testing:latest

Note:

1) The RUN instruction in the last line of my Dockerfile is for the latter part i.e., the echo command. Assigning variable [MY_DECODED_VALUE=$(cat /root/temp)] just before the echo command ensures that the variable gets set in the same layer where you want to consume it.

2) The way i have used variable assignment, it will not behave as you would expect from an ENV instruction i.e., it will not be available for use across layers. If you want to consume the variable in multiple layers, then you will have to use RUN MY_DECODED_VALUE=$(cat /root/temp); <your-command-that-uses-the-variable>, wherever applicable. Not an elegant one but that's how it works with my solution.

Technext
  • 7,887
  • 9
  • 48
  • 76
  • 1
    This won't work. It will not execute the command. It will set environment variables as raw string: `MY_DECODED_VALUE=$(echo bXkgbmFtZSBpcyByYWtpYgo= | base64 -d)` and `MY_ENCODED_VALUE=bXkgbmFtZSBpcyByYWtpYgo=` – Kapil Khandelwal Apr 17 '20 at 07:57
  • @kapilKhandelwal is right. It sets the whole raw string – Rakib Apr 17 '20 at 08:07
  • @Technext you have given the updated solution using `RUN`. But my post was using `ENV`. Is it not possible to do this using `ENV` ? My setup requires ENV. – Rakib Apr 17 '20 at 10:02
  • The `RUN` instruction in that line is actually for the latter part i.e., the `echo` command. We are just ensuring that the variable gets set in the _same_ layer where you want to consume it. – Technext Apr 17 '20 at 10:06
  • Unfortunately that wouldn't serve the purpose. We can't use that value anywhere else when a container is spun up. – Rakib Apr 17 '20 at 10:12
  • Are you using the variable in multiple places? If that's the case, then you will have to use `RUN MY_DECODED_VALUE=$(cat /root/temp); `, wherever applicable. I know it's not an elegant solution if you need to use the variable's value in _multiple_ layers but that's how it works with my solution. – Technext Apr 17 '20 at 10:40
  • in that case, can we conclude that it's not possible to interpolate shell commands on a ENV step in dockerfile? That an ENV step can only accept simple key=value format for setting it in a dockerfile? – Rakib Apr 17 '20 at 14:41
  • i understand passing in docker-run is an option. Just wanna make sure we understand that interpolation is not possile in ENV step in a dockerfile – Rakib Apr 17 '20 at 14:41