Home > Net >  How to export parsed json variables in docker entrypoint.sh?
How to export parsed json variables in docker entrypoint.sh?

Time:03-26

In AWS ECS, when SECRET is defined in the ECS task definition, the $SECRET variable ends up in the container as a json string.

SECRET={"secret1":"value1","secret2":"value2"}

I'm able to parse out and export the json string to individual environment variables when I run this command directly in the container using this command:

eval export $(echo "$SECRET" | jq -r 'to_entries|map("\"\(.key)=\(.value|tostring)\"")|.[]' )

But, the variables don't get set properly when I run the same command from the 'entrypoint.sh' script, on container run, when the container starts. ["entrypoint.sh"]

["entrypoint.sh"]

#!/usr/bin/env bash

if [ $# -gt 0 ];then
    ## If we passed a command in docker run, run it
    exec "$@"
else
    eval export $(echo "$SECRET" | jq -r 'to_entries|map("\"\(.key)=\(.value|tostring)\"")|.[]' ) 
 
    "${BUILD_DIR}"/run.sh
fi

Is it possible to parse the json string and export environment variables in an entrypoint script so that the show up in printenv?

Any guidance would be appreciated.

CodePudding user response:

I tried to reproduce this problem but your code appears to work just fine. With the following Dockerfile:

FROM ubuntu:20.04

RUN apt-get update; apt-get -y install jq; apt-get clean all
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

And a slightly modified entrypoint.sh:

#!/usr/bin/env bash

if [ $# -gt 0 ];then
    ## If we passed a command in docker run, run it
    exec "$@"
elif [ -n "$SECRET" ]; then
    eval export $(echo "$SECRET" | jq -r 'to_entries|map("\"\(.key)=\(.value|tostring)\"")|.[]' ) 
fi

echo "Extracted environment variables:"
env | grep '^secret'

If I run it like this:

docker build -t myimage .
docker run --rm -e 'SECRET={"secret1":"value1","secret2":"value2"}'
myimage

I get this output:

Extracted environment variables:
secret2=value3
secret1=value1

Your code seems to correctly extract and export to the environment the variables encoded in the SECRET variable.

CodePudding user response:

The sort of complex variable manipulation you're describing is hard to do in a shell script, but much more straightforward in other languages. There's really only two requirements around an entrypoint wrapper script: it must be executable given the language runtime and libraries in the image, and it must execute the command passed to it as parameters.

So you could imagine writing a Python entrypoint wrapper script, for example. Modifying os.environ modifies the environment in the same way as the shell export built-in; os.execvp() replaces the current process with a new one, like the shell exec built-in. If you're doing this already then you can use the standard json library for JSON parsing.

This leads to a script like:

#!/usr/bin/env python3
# entrypoint.py

import json
import os

# Set arbitrary environment variables from a JSON-encoded
# $SECRET environment variable
if 'SECRET' in os.environ:
  for k, v in json.loads(os.environ['SECRET']).items():
    os.environ[k] = v

# Get the command to run from command-line arguments
cmd = sys.argv[1:]
if len(cmd) == 0:
  cmd = [os.path.join(os.environ['BUILD_DIR']), "run.sh"]

# Replace this script with that command.
os.execvp(cmd[0], cmd)

So long as your image already has a Python interpreter and you mark this script as executable, you can use it as an ENTRYPOINT ["./entrypoint.py"] the same way you do your existing shell script.

  • Related