Grafana and InfluxDB with Let's Encrypt SSL on Docker

It seems extremely easy to do if you know all required Docker containers, but it's not so obvious if you are not a fluent Docker user.
Here is what it takes to create SSL secured Grafana + InfluxDB Docker setup:

The additional benefit of this setup is certificate autogeneration and auto-renewal (no more worries/downtime related to expired Let's Encrypt certificate.

Required tools:


Create docker-compose.yml file with the content similar to the example below and execute docker-compose up -d command in the directory where your yml file is saved.
Here is the example content of docker-compose.yml with some comments related to the required modifications/adjustments (don't worry about the file length, feel free to skip this section and continue reading starting from Architecture description):

version: '2'

    image: grafana/grafana:5.0.0 # or probably any other version
    container_name: grafana
    restart: always
      - VIRTUAL_HOST=YOUR.DOMAIN.TEST # adjust to match your domain name
      - VIRTUAL_PROTO=https
      - VIRTUAL_PORT=3000
      - LETSENCRYPT_HOST=YOUR.DOMAIN.TEST # adjust to match your domain name
      - LETSENCRYPT_EMAIL=YOUR.EMAIL@ADDRESS.TEST # adjust to match your email

      - GF_SERVER_CERT_FILE=/etc/letsencrypt/certs/YOUR.DOMAIN.TEST.crt # adjust to match your domain name
      - GF_SERVER_CERT_KEY=/etc/letsencrypt/certs/YOUR.DOMAIN.TEST.key # adjust to match your domain name
      - GF_SERVER_PROTOCOL=https

      - GF_SERVER_DOMAIN=YOUR.DOMAIN.TEST # adjust to match your domain name
      - GF_SECURITY_ADMIN_USER=SECURE_USERNAME # adjust to create Grafana admin account
      - GF_SECURITY_ADMIN_PASSWORD=SECURE_PASS # adjust to set Grafana admin password
      - ./letsencrypt/certs:/etc/letsencrypt/certs:ro

      - grafana-data:/var/lib/grafana

    image: influxdb:1.4.2 # or any other recent version
    container_name: influx
    restart: always
      - influx-data:/var/lib/influxdb

      - ./letsencrypt/certs:/etc/letsencrypt/certs:ro
      - "8086:8086"
      # might be used someday when issue #59 will be resolved/merged
      #- VIRTUAL_PROTO=https
      #- VIRTUAL_PORT=8086

      - INFLUXDB_HTTP_HTTPS_CERTIFICATE=/etc/letsencrypt/certs/YOUR.DOMAIN.TEST.crt # adjust to match your domain name
      - INFLUXDB_HTTP_HTTPS_PRIVATE_KEY=/etc/letsencrypt/certs/YOUR.DOMAIN.TEST.key # adjust to match your domain name

      - INFLUXDB_DB=SOME_DB_NAME # set any other to create database on initialization

      - INFLUXDB_ADMIN_USER=SECURE_USERNAME # adjust to create InfluxDB admin account
      - INFLUXDB_ADMIN_PASSWORD=SECURE_PASS # adjust to create InfluxDB admin password

  # Containers below ensures automatic cert creation and renewal
    image: jwilder/nginx-proxy:0.6.0
    container_name: nginx
    restart: always
      - com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy
      - "80:80"
      - "443:443"
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./nginx/html:/usr/share/nginx/html
      - ./nginx/vhost.d:/etc/nginx/vhost.d
      - ./letsencrypt/certs:/etc/nginx/certs:ro
    image: jrcs/letsencrypt-nginx-proxy-companion:v1.7
    container_name: letsencrypt
    restart: always
      - nginx
      - ./letsencrypt/certs:/etc/nginx/certs:rw
      - /var/run/docker.sock:/var/run/docker.sock:ro

    driver: local
    driver: local

That's all. Just replace:

  • YOUR.DOMAIN.TEST - appropriate domain name
  • YOUR.EMAIL@ADDRESS.TEST - your email address
  • SECURE_USERNAME - some username
  • SECURE_PASS - secure password for the user

After executing docker-compose up -d you SSLed Grafana + Influx stack should be available over https://YOUR.DOMAIN.TEST and https://YOUR.DOMAIN.TEST:8086. It may take a couple of minutes on the first run because of Let's Encrypt certificate generation.

As an "extra" benefit the Nginx ensures HSTS headers for SSLed service, which basically means that all requests have to be done using an encrypted connection (the browser will force https:// at the beginning of the address).


As we know by default Docker creates it's own subnetwork for running containers and communication between them. Here is how it looks in the above example.

Influx-Grafana-Let's Encrypt SSL

NOTE 1: Influx URL. Inside Grafana data sources panel you will have to define your Influx URL using a fully qualified domain name (FQDN e.g. https://YOUR.DOMAIN.TEST:8086) and not internal Docker subnetwork alias e.g. influx. This is due to the fact that SSL certificate will work with Influx only if it is accessed through the URL for which certificate was requested.

NOTE 2: Grafana port. In this setup Grafana still uses its default 3000 port, the redirection from 80 and 443 ports is handled by the Nginx proxy server.

NOTE 3: Influx without proxy. As you may notice InfluxDB connections doesn't go through Nginx. That fact is caused by the Nginx env variables configuration limitation. It doesn't allow to specify port-based routing (only subdomain routing is available). For more details please refer to the Github issue #59

Detailed description

Here is some more information about setup presented above. Some of them may be evident especially for (more or less) experienced Docker users. I think that they are worth at least skimming through.


The container name option, once specified, let's you refer to the deployed container using a custom name instead of SHA code. It is useful especially for checking container status with docker logs [container_name] or executing custom commands with docker exec -it [container_name].

restart: always

Just to ensure continuous work even after Docker/host restart. Be careful with restart: unless-stopped as this option lacks the container autostart feature.


They are used (in this setup) just to mark which container is the Nginx proxy in order to trigger its reloading on certificate update. It's a handy feature implemented by letsencrypt-nginx-proxy-companion.


That's a tricky one. The docker.sock allows the container to work with Docker Engine API. It is used by the jwilder/nginx-proxy to do its VIRTUAL_... env variables magic. The docker API works similar to any JSON based HTTP API, but it is exposed on docker.sock socket.

:ro and :rw suffixes

I think it's an obvious one but to cover "everything" I can say that those are folder/file permissions: "Read Only" and "Read and Write".


There are 3 kinds of "paths" used in this setup:

  • absolute paths like /var/run/docker.sock:... which points to the host system internal files
  • relative paths e.g. *./letsencrypt/certs:... which are a handy way of storing/sharing container files with the host system
  • volumes dirs influx-data:... these are used for ensuring data persistence ensured by the Docker

cert files

Don't worry that the cert file paths are invalid on the first run when there are no certificate files. As soon as Let's Encrypt certificate request will be fulfilled you will find appropriate certificates in the specified localizations.


That's all for now. I'd be happy to answer some questions. I hope to be able to explain everything about this or similar setup.