NGINX basic authentication based on environment variable

I’m setting up a docker image with nginxlua installed. The scenario is to have a basic authentication on staging, but not in production. My idea was to have an ENV variable with the name of the stage and check the value in the nginx.conf file.

The content of the docker-compose.yml file (for staging, and for production the STAGE env will be prod of course):

  • Unsatisfiable constraints when installing packages on docker alpine
  • How to manage multiple database schema from simple docker?
  • Docker image push over SSH (distributed)
  • How to add 3rd party jar to maven container docker
  • not able to perform gcloud init inside dockerfile
  • PyCharm Docker Deployment “[Errno 2] No such file or directory”
  • docs-router:
      build: ./nginx 
      environment:
        - API_BASE_URI=staging.example.com
        - DOCS_STATIC_URI=docs-staging.example.com
        - STAGE=staging
      ports:
        - "8089:8089"
        - "8090:8090"
    

    The content of the nginx.conf file:

    ...
    
    env API_BASE_URI;
    env DOCS_STATIC_URI;
    env STAGE;
    
    ...
    
    http {
      server {
        listen 8089 default_server;
        charset utf-8;
        resolver 8.8.8.8;
        access_log off;
    
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
        location ~ ^(/.*\.(?:apib|svg))?$ {
          set_by_lua_block $api_base_uri { return os.getenv("API_BASE_URI") }
          set_by_lua_block $stage { return os.getenv("STAGE") }
          set $unprotected "prod";
    
          if ($stage = $unprotected) {
            auth_basic "Restricted Content";
            auth_basic_user_file /etc/nginx/.htpasswd;
          }
    
          proxy_pass https://$api_base_uri$1;
          proxy_set_header Host $api_base_uri;
        }
    
        ...
    
      }
    
    }
    

    But it’s not working. Any idea, how can I achieve this?

  • Docker Cannot link to a non running container
  • Docker: Is it necessary to mount a new partition
  • How to configure PHP 7 - Apache with MySQL PDO driver in Debian Docker image?
  • Can't run a command from Dockerfile or Docker Compose
  • Work with docker and IDE
  • Docker: Use sockets for communication between 2 containers
  • One Solution collect form web for “NGINX basic authentication based on environment variable”

    I just find a solution with some help from Serverfault. It’s not the best one because the URLs are in the nginx.conf file, but it solves my problem:

    I just removed the variable form the docker-compose.yml file:

    docs-router:
      build: ./nginx 
      environment:
        - API_BASE_URI=staging.example.com
        - DOCS_STATIC_URI=docs-staging.example.com
      ports:
        - "8089:8089"
        - "8090:8090"
    

    And then I mapped the URLs in the nginx.conf file:

    ...
    
    env API_BASE_URI;
    env DOCS_STATIC_URI;
    
    ...
    
    http {
    
      ##
      # URL protection
      ##
      map $http_host $auth_type {
        default "off";
        stage1.example.com "Restricted";
        stage2.example.com "Restricted";
      }
    
      server {
        listen 8089 default_server;
        charset utf-8;
        resolver 8.8.8.8;
        access_log off;
    
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
        location ~ ^(/.*\.(?:apib|svg))?$ {
          set_by_lua_block $api_base_uri { return os.getenv("API_BASE_URI") }
    
          auth_basic $auth_type;
          auth_basic_user_file /etc/nginx/.htpasswd;
    
          proxy_pass https://$api_base_uri$1;
          proxy_set_header Host $api_base_uri;
        }
    
        ...
    
      }
    
    }
    

    If there is a better / nicer solution for this, please let me know.

    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.