Nginx is a convenient HTTP server that makes it super easy to launch in a container and serve web services. On the other hand, there are some quirks in following best practices for container operations.
The best practices for container operations are:
--Containers do not change the image in each environment (development, production, etc.) --It is the environment variables that change, and the environment variables control the behavior inside the container.
On the other hand, Nginx is difficult to pass environment variables. You have to do some tricks like the article below.
But with modern Nginx containers, you don't have to do this!
When you start the Nginx container, docker-entrypoint.sh is executed by default.
The contents of this script are as follows (image when `` `FROM nginx: 1.18``` is done)
docker-entrypoint.sh
#!/bin/sh
# vim:sw=4:ts=4:et
set -e
if [ -z "${NGINX_ENTRYPOINT_QUIET_LOGS:-}" ]; then
exec 3>&1
else
exec 3>/dev/null
fi
if [ "$1" = "nginx" -o "$1" = "nginx-debug" ]; then
if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -maxdepth 1 -type f -print -quit 2>/dev/null | read v; then
echo >&3 "$0: /docker-entrypoint.d/ is not empty, will attempt to perform configuration"
echo >&3 "$0: Looking for shell scripts in /docker-entrypoint.d/"
find "/docker-entrypoint.d/" -follow -type f -print | sort -n | while read -r f; do
case "$f" in
*.sh)
if [ -x "$f" ]; then
echo >&3 "$0: Launching $f";
"$f"
else
# warn on shell scripts without exec bit
echo >&3 "$0: Ignoring $f, not executable";
fi
;;
*) echo >&3 "$0: Ignoring $f";;
esac
done
echo >&3 "$0: Configuration complete; ready for start up"
else
echo >&3 "$0: No files found in /docker-entrypoint.d/, skipping configuration"
fi
fi
exec "$@"
In short, it will execute .sh under /docker-entrypoint.d/ in sequence (other than .sh will be ignored).
In addition, /docker-entrypoint.d/ includes the following scripts by default.
20-envsubst-on-templates.sh
#!/bin/sh
set -e
ME=$(basename $0)
auto_envsubst() {
local template_dir="${NGINX_ENVSUBST_TEMPLATE_DIR:-/etc/nginx/templates}"
local suffix="${NGINX_ENVSUBST_TEMPLATE_SUFFIX:-.template}"
local output_dir="${NGINX_ENVSUBST_OUTPUT_DIR:-/etc/nginx/conf.d}"
local template defined_envs relative_path output_path subdir
defined_envs=$(printf '${%s} ' $(env | cut -d= -f1))
[ -d "$template_dir" ] || return 0
if [ ! -w "$output_dir" ]; then
echo >&3 "$ME: ERROR: $template_dir exists, but $output_dir is not writable"
return 0
fi
find "$template_dir" -follow -type f -name "*$suffix" -print | while read -r template; do
relative_path="${template#$template_dir/}"
output_path="$output_dir/${relative_path%$suffix}"
subdir=$(dirname "$relative_path")
# create a subdirectory where the template file exists
mkdir -p "$output_dir/$subdir"
echo >&3 "$ME: Running envsubst on $template to $output_path"
envsubst "$defined_envs" < "$template" > "$output_path"
done
}
auto_envsubst
exit 0
This means that all environment variables will replace the environment variable definitions (strings enclosed in $ {}) in the * .template file under/etc/nginx/templates.
Not solved.
As you can see by reading the script above, it replaces all the set environment variables. If the environment variable and the variable of nginx.conf are duplicated in log output etc., there is a possibility of accidental explosion.
If you want to avoid accidental explosions, you have to prepare your own script using envsubst
.
Also, if you add the above script under /docker-entrypoint.d/, it will be executed at startup, but docker-entrypoint.sh will continue processing even if the called script causes an error. Therefore, for example, "If this environment variable is not defined, it will not start" cannot be done.
After all, I had no choice but to execute the above script with CMD, and it seemed difficult to complete with docker-entrypoint.sh ...