dockerdocker-entrypoint

Docker entrypoint script not sourcing file


I have an entrypoint script with docker which is getting executed. However, it just doesn't run the source command to source a file full of env values.

Here's the relevant section from tehe dockerfile

ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["-production"]

I have tried 2 version of entrypoint script. Neither of them are working.

VERSION 1

#!/bin/bash

cat >> /etc/bash.bashrc <<EOF
if [[ -f "/usr/local/etc/${SERVICE_NAME}/${SERVICE_NAME}.env" ]]
then
  echo "${SERVICE_NAME}.env found ..."
  set -a
  source "/usr/local/etc/${SERVICE_NAME}/${SERVICE_NAME}.env"
  set +a
fi
EOF

echo "INFO: Starting ${SERVICE_NAME} application, environment:"

exec -a $SERVICE_NAME node .

VERSION 2

ENV_FILE=/usr/local/etc/${SERVICE_NAME}/${SERVICE_NAME}.env
if [[] -f "$ENV_FILE" ]; then
  echo "INFO: Loading environment variables from file: ${ENV_FILE}"
  set -a
  source $ENV_FILE
  set +a
fi

echo "INFO: Starting ${SERVICE_NAME} application..."

exec -a $SERVICE_NAME node .

Version 2 of above prints to the log that it has found the file however, source command simply isn't loading the contents of file into memory. I check if contents have been loaded by running the env command.

I've been trying few things for 3 days now with no progress. Please can someone help me? Please note I am new to docker which is making things quite difficult.


Solution

  • I think your second version is almost there.

    Normally Docker doesn't read or use shell dotfiles at all. This isn't anything particular to Docker, just that you're not running an "interactive" or "login" shell at any point in the sequence. In your first form you write out a .bashrc file but then exec node, and nothing there ever re-reads the dotfile.

    You mention in the question that you use the env command to check the environment. If this is via docker exec, that launches a new process inside the container, but it's not a child of the entrypoint script, so any setup that happens there won't be visible to docker exec. This usually isn't a problem.

    I can suggest a couple of cleanups that might make it a little easier to see the effects of this. The biggest is to split out the node invocation from the entrypoint script. If you have both an ENTRYPOINT and a CMD then Docker passes the CMD as arguments to the ENTRYPOINT; if you change the entrypoint script to end with exec "$@" then it will run whatever it got passed.

    #!/bin/sh
    # (trying to avoid bash-specific constructs)
    
    # Read the environment file
    ENV_FILE="/usr/local/etc/${SERVICE_NAME}/${SERVICE_NAME}.env"
    if [ -f "$ENV_FILE" ]; then
      . $ENV_FILE
    fi
    
    # Run the main container command
    exec "$@"
    

    And then in the Dockerfile, put the node invocation as the main command

    ENTRYPOINT ["./entrypoint.sh"] # must be JSON-array syntax
    CMD ["node", "."]              # could be shell-command syntax
    

    The important thing with this is that it's easy to override the command but leave the entrypoint intact. So if you run

    docker run --rm your-image env
    

    that will launch a temporary container, but passing env as the command instead of node .. That will go through the steps in the entrypoint script, including setting up the environment, but then print out the environment and exit immediately. That will let you observe the changes.