dockerenvironment-variablesdocker-entrypoint

How to dynamically set environment variables in a docker-entrypoint.sh?


I have a go binary that will pull environment variables from AWS SSM Param, when the script runs, it prints out lines like this:

export FOO="BAR"
export BAZ="QUX"

This works well and I actually see the print happening. Then, I have a docker-entrypoint.sh shell file that takes these lines and eval's them, setting triggering the export:

#!/bin/bash
set -e

ssm_available() {
  if [ -z "$SSM_BASE_PATH" ]; then
    return 1
  fi

  return 0
}

export_ssm_params_go() {
  set -x
  eval $(./ssm_get_parameter --path ${SSM_BASE_PATH})
  exec "$@"
}

main() {
  if ssm_available; then
    echo "Info: Loading SSM Parameters" >&2
    export_ssm_params_go "$@"
  fi

  echo "Info: Starting ..." >&2
  exec "$@"
}

main "$@"

I see that it works but it's not actually setting the env var when I exec into the container and run env. This is the output

Info: Loading SSM Parameters
+ ./ssm_get_parameter --path /p-stack-fs/env/production
+ eval export 'FOO="TEST"'
+ export 'FOO=TEST'
+ exec node server.js

I feel like maybe it's running in a subshell and setting that or something? Here's the end of my Dockerfile:

...
ENTRYPOINT [ "sh", "docker-entrypoint.sh" ]
CMD ["node", "server.js"]

EDIT: actually looks like it is setting it but when I try to run env in a docker exec command, it doesn't show up, even though the other ENV variables in my Dockerfiles does. Any idea why?


Solution

  • Environment variables are specific per process. You can see this without running Docker: you can just run the script you have (with correct AWS credentials), but you won't be able to see the environment variables that get set by the script later on in the same terminal window. If you could examine the process deeper (maybe looking in /proc/12345/environment) you could see the variables, but there is not a way to "go inside" a process and run an interactive shell.

    docker exec runs a second process inside an existing container. It does not run as a child of the entrypoint, and it does not run an entrypoint script if you have one. That means it will see ENV variables from the image and docker run -e environment variables globally in the container, but not things that are only set for the main container process, as in this script.

    If you docker run an alternate command that will go via the entrypoint, and if you're just trying to debug the variable settings, that can be a good starting point

    docker run --rm your-image env