18

I've setup and started default grafana and it works as expected on http://localhost:3000. I'm trying to proxy it with nginx where I have ssl installed. I'm trying to have it respond to https://localhost/grafana but it just serves the following:

{{alert.title}}

I have this in my nginx server block:

location /grafana {
     proxy_pass         http://localhost:3000;
     proxy_set_header   Host $host;
}

6 Answers 6

32

It seems nginx supports rewriting the requests to the proxied server so updating the config to this made it work:

location /grafana {
     proxy_pass         http://localhost:3000;
     rewrite  ^/grafana/(.*)  /$1 break;
     proxy_set_header   Host $host;
}

My grafana.ini also has an updated root:

[server]
root_url = %(protocol)s://%(domain)s:%(http_port)s/grafana
4
  • I can confirm that this works. Note that due to the static assets both the nginx rewrite and the root_url config are needed, but otherwise it does the trick with Grafana 2.2.
    – Mahn
    Commented Aug 14, 2015 at 20:44
  • 3
    Also, if you have basic http auth in front of nginx before it hits grafana, make sure you override the Authorization header by including proxy_set_header Authorization ""; in your proxy location block, otherwise Grafana will insist in reusing these credentials for data source connections.
    – Mahn
    Commented Aug 14, 2015 at 21:05
  • The rewrite rule is essential to make it work. This should really be added to the Grafana documentation at docs.grafana.org/installation/behind_proxy
    – dasup
    Commented Jan 5, 2018 at 9:46
  • 1
    @dasup No, the rewrite rule is not required (at least not in grafana 4.6). You need to set proxy_pass to include a URI such as /, otherwise the request is passed through as is (see also nginx.com/resources/admin-guide/reverse-proxy for the explanation). So the config should be proxy_pass http://localhost:3000/; which is exactly what the grafana docs state.
    – ChrisWue
    Commented Jan 25, 2018 at 23:36
12

Adding on to @AXE-Labs answer, you don't need to rewrite the URL.

nginx.conf

location /grafana/ {
     proxy_pass         http://localhost:3000/;
     proxy_set_header   Host $host;
}

grafana.ini update root:

[server]
root_url = %(protocol)s://%(domain)s:%(http_port)s/grafana/

Notice the additional / in the location block, that makes all the difference.

If you want to see the entire file, please visit https://gist.github.com/mvadu/5fbb7f5676ce31f2b1e6 where I have rever proxy setup for Infludb as well as grafana.

3
  • 1
    Yes, the difference is explained here: nginx.com/resources/admin-guide/reverse-proxy
    – ChrisWue
    Commented Jan 25, 2018 at 23:39
  • 3
    Note that trailing slash in http://localhost:3000/; also important.
    – bitnik
    Commented Apr 5, 2018 at 13:06
  • 1
    And in %(protocol)s://%(domain)s:%(http_port)s/grafana/ - all locations should have trailing slash. Commented Aug 29, 2019 at 3:05
4

I got the same problem when using nginx and grafana on docker, in two different containers. Passed the following options to docker-compose on grafana service, following http://docs.grafana.org/installation/behind_proxy/#nginx-configuration-with-sub-path:

- GF_SERVER_DOMAIN=foo.bar.com
- GF_SERVER_ROOT_URL=%(protocol)s://%(domain)s:/grafana

But it didn't work, and my browser's console shows: net::ERR_CONTENT_LENGTH_MISMATCH.

So, to fix it, I added the following line to my nginx config:

location /grafana/ {
  proxy_pass http://monitoring_grafana:3000/;
  proxy_max_temp_file_size 0; # THIS MADE THE TRICK!
}
1

I struggled a bit with all the answers here. For completeness and documentation for myself a full example which worked in my case.

/etc/grafana/grafana.ini:

... DEFAULT CONFIGURATION

#################################### Server ################################

... DEFAULT CONFIGURATION

root_url = %(protocol)s://%(domain)s:%(http_port)s/grafana/

... DEFAULT CONFIGURATION

nginx.conf looks like this:

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;

        server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # SSL Settings
        #

        ##
        # Logging Settings
        ##
        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        ... DEFAULT SETTINGS ...

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;

        # note that I am not using sites-enabled:
        # include /etc/nginx/sites-enabled/*;
}

I put the NGINX configuration for grafana into a separate grafana.conf located in /etc/nginx/conf.d/:

server {

  listen 80;
  listen [::]:80;

  listen 443 ssl;
  listen [::]:443 ssl;

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
  ssl_prefer_server_ciphers on;

  ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
  ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

  root /var/www/<my.hostname.xy>/html;
  index index.html index.htm;

  server_name <my.hostname.xy>;

  location /grafana/ {
    proxy_pass http://localhost:3000/;
    proxy_set_header Host $host;
  }
}
0

FYI:

root_url = %(protocol)s://%(domain)s:%(http_port)s/grafana

causes proxy errors for some API calls. I find:

root_url = %(protocol)s://%(domain)s:/grafana
0

For Nginx default-ssl.conf

 location /login {
   proxy_set_header Host $http_host;
   proxy_set_header X-Forwarded-Proto $scheme;
   proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
   proxy_set_header X-Real-IP $remote_addr;
   proxy_pass http://localhost:3000;
 }

and also you have to change grafana.ini configuration.

[server]
domain = serverdomain.com
root_url = %(protocol)s://%(domain)s:%(http_port)s/
serve_from_sub_path = true

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .