Running a bash script before startup in an NGINX docker container Running a bash script before startup in an NGINX docker container nginx nginx

Running a bash script before startup in an NGINX docker container


NGINX 1.19 has a folder /docker-entrypoint.d on the root where place startup scripts executed by thedocker-entrypoint.sh script. You can also read the execution on the log.

/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, willattempt to perform configuration

/docker-entrypoint.sh: Looking for shell scripts in/docker-entrypoint.d/

/docker-entrypoint.sh: Launching

[..........]

/docker-entrypoint.sh: Configuration complete; ready for start up


For my future self and everybody else, this is how you can set up variable substitution at startup (for nginx, may also work for other images):

I've also wrote a more in depth blog post about it: https://danielhabenicht.github.io/docker/angular/2019/02/06/angular-nginx-runtime-variables.html

Dockerfile:

FROM nginxENV TEST="Hello variable"WORKDIR /etc/nginxCOPY ./substituteEnv.sh ./substituteEnv.sh# Execute the subsitution script and pass the path of the file to replaceENTRYPOINT ["./substituteEnv.sh", "/usr/share/nginx/html/index.html"]CMD ["nginx", "-g", "daemon off;"]

subsitute.sh: (same as @Daniel West's answer)

#!/bin/bashif [[ -z $1 ]]; then    echo 'ERROR: No target file given.'    exit 1fi#Substitute all environment variables defined in the file given as argumentenvsubst '\$TEST \$UPSTREAM_CONTAINER \$UPSTREAM_PORT' < $1 > $1# Execute all other paramtersexec "${@:2}"

Now you can run docker run -e TEST="set at command line" -it <image_name>

The catch was the WORKDIR, without it the nginx command wouldn't be executed. If you want to apply this to other containers be sure to set the WORKDIR accordingly.

If you want to do the substitution recursivly in multiple files this is the bash script you are looking for:

# Substitutes all given environment variablesvariables=( TEST )if [[ -z $1 ]]; then    echo 'ERROR: No target file or directory given.'    exit 1  fifor i in "${variables[@]}"do  if [[ -z ${!i} ]]; then    echo 'ERROR: Variable "'$i'" not defined.'    exit 1  fi  echo $i ${!i} $1  # Variables to be replaced should have the format: ${TEST}  grep -rl $i $1 | xargs sed -i "s/\${$i}/${!i}/Ig"doneexec "${@:2}"


I know this is late but I found this thread while searching for a solution so thought I'd share.

I had the same issue. Your ENTRYPOINT script should also include exec "$@"

#!/bin/shset -eenvsubst '\$CORS_HOST \$UPSTREAM_CONTAINER \$UPSTREAM_PORT' < /srv/api/default.conf > /etc/nginx/conf.d/default.confexec "$@"

That will mean the startup CMD from the nginx:alpine container will run. The above script will inject the specified environment variables into a config file. By doing this in runtime yo can override the environment variables.