Container-based image renderer not fully working with Grafana behing Apache proxy

Hi,

  • What Grafana version and what operating system are you using?

    • Stand-alone 11.6.10, Debian 12
  • What are you trying to achieve?

    • Have Grafana image rendering working
  • How are you trying to achieve it?

    • I have stand-alone Grafana running and then deployed container version of grafana-image-renderer (in the same host)
    • Grafana is running behind Apache proxy
    • There is a SSL certificate configured in Apache
    • There is a service account in Grafana with token generated
  • What happened?

    • The workflow partially works:
      • Grafana seems to be able to send request to renderer and it seems to be accessible from the server:
        • $ curl -v http://localhost:8081/render/version
          *   Trying 127.0.0.1:8081...
          * Connected to localhost (127.0.0.1) port 8081 (#0)
          > GET /render/version HTTP/1.1
          > Host: localhost:8081
          > User-Agent: curl/7.88.1
          > Accept: */*
          > 
          < HTTP/1.1 200 OK
          < Content-Type: application/json
          < Date: Fri, 15 May 2026 10:22:27 GMT
          < Content-Length: 20
          < 
          * Connection #0 to host localhost left intact
          {"version": "5.0.0"}
          
        • $ curl -v -H "Authorization: Bearer ***" "https://foo.bar/grafana/render/d-solo/feizqmmy116gwe/?orgId=1&from=2026-04-12T09:22:17.007Z&to=2026-05-12T10:22:17.007Z&panelId=1" -o chart.png
            % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                           Dload  Upload   Total   Spent    Left  Speed
            0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying my_ip:443...
          * Connected to foo.bar.pl (my_ip) port 443 (#0)
          * ALPN: offers h2,http/1.1
          } [5 bytes data]
          * TLSv1.3 (OUT), TLS handshake, Client hello (1):
          } [512 bytes data]
          *  CAfile: /etc/ssl/certs/ca-certificates.crt
          *  CApath: /etc/ssl/certs
          { [5 bytes data]
          * TLSv1.3 (IN), TLS handshake, Server hello (2):
          { [122 bytes data]
          * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
          { [25 bytes data]
          * TLSv1.3 (IN), TLS handshake, Certificate (11):
          { [5097 bytes data]
          * TLSv1.3 (IN), TLS handshake, CERT verify (15):
          { [264 bytes data]
          * TLSv1.3 (IN), TLS handshake, Finished (20):
          { [52 bytes data]
          * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
          } [1 bytes data]
          * TLSv1.3 (OUT), TLS handshake, Finished (20):
          } [52 bytes data]
          * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
          * ALPN: server accepted http/1.1
          * Server certificate:
          * <cert-details-cut-off>
          *  SSL certificate verify ok.
          * using HTTP/1.1
          } [5 bytes data]
          > GET /grafana/render/d-solo/feizqmmy116gwe/?orgId=1&from=2026-04-12T09:22:17.007Z&to=2026-05-12T10:22:17.007Z&panelId=1 HTTP/1.1
          > Host: foo.bar
          > User-Agent: curl/7.88.1
          > Accept: */*
          > Authorization: Bearer ***
          > 
          { [5 bytes data]
          * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
          { [57 bytes data]
          * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
          { [57 bytes data]
          * old SSL session ID is stale, removing
            0     0    0     0    0     0      0      0 --:--:--  0:00:04 --:--:--     0{ [5 bytes data]
          < HTTP/1.1 200 OK
          < Date: Fri, 15 May 2026 10:53:23 GMT
          < Server: Apache/2.4.67 (Debian)
          < Accept-Ranges: bytes
          < Cache-Control: private
          < Content-Length: 44155
          < Content-Type: image/png
          < Last-Modified: Fri, 15 May 2026 10:53:23 GMT
          < X-Content-Type-Options: nosniff
          < X-Frame-Options: deny
          < X-Xss-Protection: 1; mode=block
          < 
          { [7875 bytes data]
          100 44155  100 44155    0     0   9106      0  0:00:04  0:00:04 --:--:--  9107
          * Connection #0 to host foo.bar left intact
          
      • from within the container also Grafana seems to be accessible (test done from container)
        • $ curl -I https://foo.bar/grafana/
          HTTP/1.1 200 OK
          Date: Fri, 15 May 2026 10:32:41 GMT
          Server: Apache/2.4.67 (Debian)
          Cache-Control: no-store
          Content-Type: text/html; charset=UTF-8
          X-Content-Type-Options: nosniff
          X-Frame-Options: deny
          X-Xss-Protection: 1; mode=block
          
        • curl -v -H "Authorization: Bearer ***" "https://foo.bar/grafana/d-solo/feizqmmy116gwe/?orgId=1&from=2026-04-12T09:22:17.007Z&to=2026-05-12T10:22:17.007Z&panelId=1" | more
            % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                           Dload  Upload   Total   Spent    Left  Speed
            0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Host foo.bar:443 was resolved.
          * IPv6: (none)
          * IPv4: my_ip
          *   Trying my_ip:443...
          * ALPN: curl offers h2,http/1.1
          } [5 bytes data]
          * TLSv1.3 (OUT), TLS handshake, Client hello (1):
          } [1584 bytes data]
          *  CAfile: /etc/ssl/certs/ca-certificates.crt
          *  CApath: /etc/ssl/certs
          { [5 bytes data]
          * TLSv1.3 (IN), TLS handshake, Server hello (2):
          { [122 bytes data]
          * TLSv1.3 (IN), TLS change cipher, Change cipher spec (1):
          { [1 bytes data]
          * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
          { [25 bytes data]
          * TLSv1.3 (IN), TLS handshake, Certificate (11):
          { [5097 bytes data]
          * TLSv1.3 (IN), TLS handshake, CERT verify (15):
          { [264 bytes data]
          * TLSv1.3 (IN), TLS handshake, Finished (20):
          { [52 bytes data]
          * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
          } [1 bytes data]
          * TLSv1.3 (OUT), TLS handshake, Finished (20):
          } [52 bytes data]
          * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / x25519 / RSASSA-PSS
          * ALPN: server accepted http/1.1
          * Server certificate:
          * <cert-details-cut-off>
          *  SSL certificate verify ok.
          *   Certificate level 0: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
          *   Certificate level 1: Public key type RSA (3072/128 Bits/secBits), signed using sha256WithRSAEncryption
          *   Certificate level 2: Public key type RSA (4096/152 Bits/secBits), signed using sha256WithRSAEncryption
          * Connected to foo.bar (my_ip) port 443
          * using HTTP/1.x
          } [5 bytes data]
          > GET /grafana/d-solo/feizqmmy116gwe/?orgId=1&from=2026-04-12T09:22:17.007Z&to=2026-05-12T10:22:17.007Z&panelId=1 HTTP/1.1
          > Host: foo.bar
          > User-Agent: curl/8.14.1
          > Accept: */*
          > Authorization: Bearer ***
          > 
          * Request completely sent off
          { [5 bytes data]
          * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
          { [57 bytes data]
          * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
          { [57 bytes data]
          < HTTP/1.1 200 OK
          < Date: Fri, 15 May 2026 10:48:52 GMT
          < Server: Apache/2.4.67 (Debian)
          < Cache-Control: no-store
          < Content-Type: text/html; charset=UTF-8
          < X-Content-Type-Options: nosniff
          < X-Frame-Options: deny
          < X-Xss-Protection: 1; mode=block
          < Vary: Accept-Encoding
          < Transfer-Encoding: chunked
          < 
          { [3860 bytes data]
          <!DOCTYPE html>
          <html lang="en-US">
            <head>
              
              <meta charset="utf-8" />
              <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
              <meta name="viewport" content="width=device-width" />
              <meta name="theme-color" content="#000" />
          
              <title>Grafana</title>
          ...
          
      • but when trying to rung rendering via panel Share link option image renderer seems to have issue with accessing Grafana and in fact generates PNG but with such content:
  • What did you expect to happen?

    • Generate PNG with panel
  • Can you copy/paste the configuration(s) that you are having problems with?

    • here is my grafana.ini
      • [server]
        domain = foo.bar
        protocol = http
        root_url = https://foo.bar/grafana
        [rendering]
        rendering_mode = remote
        server_url = http://localhost:8081/render
        callback_url = https://foo.bar/grafana/
        renderer_token = test-token
        rendering_dumpio = true
        
    • here is my Apache config from /etc/apache2/conf-available/apache-grafana.conf
      • <IfModule proxy_module>
            ProxyRequests Off
            <Proxy *>
                <IfVersion >= 2.4>
                    Require all granted
                </IfVersion>
                <IfVersion < 2.4>
                    Order deny,allow
                    Allow from all
                </IfVersion>
            </Proxy>
        
            ProxyPass /grafana http://localhost:3000 status=+I
            ProxyPassReverse /grafana http://localhost:3000 status=+I
            ProxyPass /api http://localhost:3000/api status=+I
            ProxyPassReverse /api http://localhost:3000/api status=+I
            ProxyPreserveHost On
        
            SSLProxyMachineCertificateFile /etc/ssl/certs/foo-bar-proxy.pem
        </IfModule>
        
    • here is my docker config from docker-compose.yml
      • services:
          renderer:
            image: grafana/grafana-image-renderer:latest
            container_name: grafana-image-renderer
            restart: unless-stopped
            network_mode: host
            environment:
              LOG_LEVEL: debug
              RENDERING_VERBOSE_LOGGING: 'true'
              AUTH_TOKEN: test-token
              HTTP_HEADERS: '{"Authorization":"Bearer ***"}'
        
  • Did you receive any errors in the Grafana UI or in related logs? If so, please tell us exactly what they were.

    • Nothing particular
  • Did you follow any online instructions? If so, what is the URL?

    • Yes, the one to setup image rendered

Thank you in advance for any hints!

Szymon

Hi,

I think, as I wrote above, I followed that document carefully. Is there a particular thing I’m missing form it?

Sz.

please check
serve_from_sub_path = true in grafana.ini file
then
restart
sudo systemctl restart grafana-server
docker restart grafana-image-renderer
sudo systemctl restart apache2

Please note this option should only be set when proxy is not used (see documentation page). In my case setting it results in a browser error too many redirects.

@infofcc3 It is good to carefully read what people are asking and maybe try to reproduce the issue locally like the OP setup as @szymontrocha very nicely laid out.