title: NginX reverse proxy for Kibana over Docker
body: <p>I have a Docker Compose setup with NginX, ElasticSearch and Kibana like the following:</p>
  <pre><code>web:
      build:
        context: .
        dockerfile: ./system/docker/development/web.Dockerfile
      depends_on:
        - app
      volumes:
        - './system/ssl:/etc/ssl/certs'
      networks:
        - mynet
      ports:
        - 80:80
        - 443:443
  
    elasticsearch_1:
      image: docker.elastic.co/elasticsearch/elasticsearch:7.7.0
      container_name: &quot;${COMPOSE_PROJECT_NAME:-service}_elasticsearch_1&quot;
      environment:
        - node.name=elasticsearch_1
        - cluster.name=es-docker-cluster
        - discovery.seed_hosts=elasticsearch_2,elasticsearch_3
        - cluster.initial_master_nodes=elasticsearch_1,elasticsearch_2,elasticsearch_3
        - bootstrap.memory_lock=true
        - &quot;ES_JAVA_OPTS=-Xms512m -Xmx512m&quot;
      ulimits:
        memlock:
          soft: -1
          hard: -1
      volumes:
        - es_volume_1:/usr/share/elasticsearch/data
      ports:
        - 9200:9200
      networks:
        - mynet
  
    elasticsearch_2:
      image: docker.elastic.co/elasticsearch/elasticsearch:7.7.0
      container_name: &quot;${COMPOSE_PROJECT_NAME:-service}_elasticsearch_2&quot;
      environment:
        - node.name=elasticsearch_2
        - cluster.name=es-docker-cluster
        - discovery.seed_hosts=elasticsearch_1,elasticsearch_3
        - cluster.initial_master_nodes=elasticsearch_1,elasticsearch_2,elasticsearch_3
        - bootstrap.memory_lock=true
        - &quot;ES_JAVA_OPTS=-Xms512m -Xmx512m&quot;
      ulimits:
        memlock:
          soft: -1
          hard: -1
      volumes:
        - es_volume_2:/usr/share/elasticsearch/data
      ports:
        - 9201:9201
      networks:
        - mynet
  
    elasticsearch_3:
      image: docker.elastic.co/elasticsearch/elasticsearch:7.7.0
      container_name: &quot;${COMPOSE_PROJECT_NAME:-service}_elasticsearch_3&quot;
      environment:
        - node.name=elasticsearch_3
        - cluster.name=es-docker-cluster
        - discovery.seed_hosts=elasticsearch_1,elasticsearch_2
        - cluster.initial_master_nodes=elasticsearch_1,elasticsearch_2,elasticsearch_3
        - bootstrap.memory_lock=true
        - &quot;ES_JAVA_OPTS=-Xms512m -Xmx512m&quot;
      ulimits:
        memlock:
          soft: -1
          hard: -1
      volumes:
        - es_volume_3:/usr/share/elasticsearch/data
      ports:
        - 9202:9202
      networks:
        - mynet
  
    kibana:
      image: docker.elastic.co/kibana/kibana:7.7.0
      container_name: &quot;${COMPOSE_PROJECT_NAME:-service}_kibana&quot;
      ports:
        - 5601:5601
      environment:
        ELASTICSEARCH_URL: http://elasticsearch_1:9200
        ELASTICSEARCH_HOSTS: http://elasticsearch_1:9200
      networks:
        - mynet
        
  volumes:
    es_volume_1: null
    es_volume_2: null
    es_volume_3: null
  
  networks:
    mynet:
      driver: bridge
      ipam:
        config:
        - subnet: 172.18.0.0/24
          gateway: 172.18.0.1
  </code></pre>
  <p>When I (build and) run this using <code>docker-compose up</code> I'm able to access Kibana through URL  <code>http://localhost:5601/</code> but when I try to setup a reverse proxy for the same using NginX, I get a <strong>502 Bad Gateway</strong> error. Here's my NginX config file:</p>
  <pre><code>server {
     listen 80;
     listen 443 ssl http2;
  
     ssl_certificate /ssl/localhost.crt;
     ssl_certificate_key /ssl/localhost.key;
  
    ...
  
    location /app/kibana {
       proxy_pass http://localhost:5601;
       proxy_http_version 1.1;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection 'upgrade';
       proxy_set_header Host $host;
       proxy_cache_bypass $http_upgrade;
    }
  
     location ~ /\. {    
        deny all;  
     }
     
     ...
  }
  </code></pre>
  <p>What I'm trying to do here is be able to access Kibana like <code>http://localhost/app/kibana</code>. The articles I've gone through (like <a href="https://phoenixnap.com/kb/kibana-nginx-proxy" rel="nofollow noreferrer">this</a>) seem to be focused more on securing Kibana access through NginX (using Basic Auth) rather than the ability to access on a particular path on port 80.</p>
  <p><strong>Update</strong></p>
  <p>So, I changed <code>localhost</code> to <code>kibana</code> (as suggested by @mikezter) and now it seems to be able to at least find the Kibana service (so there's no more 502 error).</p>
  <p>However, then I encountered a blank page with a few errors in browser debug console. Upon searching, I came across this location directive:</p>
  <pre><code>location ~ (/app|/translations|/node_modules|/built_assets/|/bundles|/es_admin|/plugins|/api|/ui|/elasticsearch|/spaces/enter) {
           proxy_pass          http://kibana:5601;
           proxy_set_header    Host $host;
           proxy_set_header    X-Real-IP $remote_addr;
           proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header    X-Forwarded-Proto $scheme;
           proxy_set_header    X-Forwarded-Host $http_host;
           proxy_set_header    Authorization &quot;&quot;;
           proxy_hide_header   Authorization;
    }
  </code></pre>
  <p>Now the page loads and there is some UI, but there's still some issue with the scripting, so the page is not available for user interaction.</p>