Use basic auth conditionally in nginx

Solution 1:

Nginx doesn't support environment variables in server, location or http blocks, but you can replace the occurrence of a specific variable in your configuration file for the value of an environment value with envsubst before nginx loads it.

With a configuration file such us:

server {

    listen 80 default_server;

    auth_basic ${BASIC_AUTH_ENABLED};
    auth_basic_user_file /etc/nginx/.htpasswd;

    root /var/www;

    location /health-check {
        try_files /health-check.html =404;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }

}

you can replace "${BASIC_AUTH_ENABLED}" with the value of the env var BASIC_AUTH_ENABLED by running

envsubst '${BASIC_AUTH_ENABLED}' < /etc/nginx/nginx.conf > /etc/nginx/nginx.conf

The first parameter '${BASIC_AUTH_ENABLED}' tells envsubst to only replace those occurrences that match that text (make sure to use simple quotes, otherwise parameter expansion might happen before executing envsubst itself).

If the value of auth_basic has the special value off, basic authentication is deactivated (see nginx documentation on auth_basic).

As the entrypoint of your Docker container you can run a bash script such as:

if
    [ ${BASIC_AUTH_ENABLED} = "true" ] ;
then
    htpasswd -cb -B -C 10 /etc/nginx/.htpasswd ${BASIC_AUTH_USER} ${BASIC_AUTH_PASSWORD} ;
else
    export BASIC_AUTH_ENABLED=off ;
fi
envsubst '${BASIC_AUTH_ENABLED}' < /etc/nginx/nginx.conf > /etc/nginx/nginx.conf

So if you've enabled basic authentication, encrypt the password for the given user, otherwise, set the value of the env var to "off" specifically so nginx disables basic auth.