Kodeloka
  1. Kodeloka
  2. Kelas Grafana
  3. Materi

Modul 2 · Modul 2 dari 15

Instalasi & Konfigurasi: grafana.ini, Env Var, Reverse Proxy

Memasang Grafana dengan benar, memahami hierarki konfigurasi, dan menempatkannya di belakang reverse proxy tanpa dashboard yang rusak.

Tiga Cara Memasang, Satu Cara yang Dianjurkan

CaraKapan dipakaiCatatan
Paket OS (apt/yum)VM tunggal, tradisionalConfig di /etc/grafana/grafana.ini, data di /var/lib/grafana
Docker / ComposeMayoritas kasusConfig lewat env var, volume wajib untuk /var/lib/grafana
Helm (Kubernetes)Produksi berskalaProvisioning via ConfigMap/Sidecar

Hierarki Konfigurasi — Siapa Menang

Ini sumber kebingungan yang sangat umum. Urutan prioritas, dari yang paling lemah ke paling kuat:

urutan prioritastext
1. defaults.ini            ← bawaan, JANGAN diedit
2. grafana.ini             ← file konfigurasi Anda
3. custom.ini              ← khusus paket biner
4. Environment variable    ← MENANG atas semuanya
5. Argumen baris perintah  ← untuk beberapa opsi tertentu
⚠️ Pola penamaan env var wajib dihafal

Setiap opsi [section] key = value punya padanan GF_<SECTION>_<KEY>, huruf besar, titik dan tanda hubung menjadi garis bawah.

ini
[auth.anonymous]
enabled = true
org_role = Viewer

# padanannya:
# GF_AUTH_ANONYMOUS_ENABLED=true
# GF_AUTH_ANONYMOUS_ORG_ROLE=Viewer

Bila Anda mengedit grafana.ini tetapi nilainya tidak berubah, hampir pasti ada env var yang menimpanya.

Bagian Konfigurasi yang Paling Sering Disentuh

grafana.iniini
[server]
protocol       = http
http_port      = 3000
domain         = grafana.perusahaan.id
root_url       = https://grafana.perusahaan.id/
serve_from_sub_path = false
enforce_domain = false

[database]
type     = postgres
host     = db.internal:5432
name     = grafana
user     = grafana
password = $__env{GF_DB_PASSWORD}
ssl_mode = require

[security]
admin_user            = admin
admin_password        = $__file{/run/secrets/grafana_admin}
secret_key            = $__env{GF_SECRET_KEY}
disable_gravatar      = true
cookie_secure         = true
cookie_samesite       = lax
content_security_policy = true

[users]
allow_sign_up      = false
auto_assign_org_role = Viewer
default_theme      = dark

[dashboards]
min_refresh_interval = 10s
versions_to_keep     = 20

[alerting]
enabled = false          # alerting lama, WAJIB false di Grafana modern

[unified_alerting]
enabled = true

[analytics]
reporting_enabled  = false
check_for_updates  = false

[log]
mode  = console
level = info

Menyimpan Rahasia Tanpa Menaruhnya di File

Grafana memahami dua penyedia nilai khusus di dalam grafana.ini:

  • $__env{NAMA_VAR} — ambil dari environment variable.
  • $__file{/path/ke/berkas} — ambil isi berkas (cocok untuk Docker/Kubernetes secret).
⛔ secret_key bukan hiasan

secret_key dipakai untuk mengenkripsi kredensial data source di basis data. Bila Anda memulihkan basis data ke server lain dengan secret_key berbeda, semua password data source menjadi tidak bisa didekripsi dan harus dimasukkan ulang satu per satu.

Simpan secret_key bersama backup basis data, di brankas rahasia yang sama.

Di Belakang Reverse Proxy

Dua kesalahan klasik: WebSocket untuk Live tidak diteruskan, dan root_url tidak diset sehingga tautan share/alert menunjuk ke localhost:3000.

/etc/nginx/conf.d/grafana.confnginx
server {
    listen 443 ssl http2;
    server_name grafana.perusahaan.id;

    ssl_certificate     /etc/ssl/certs/grafana.crt;
    ssl_certificate_key /etc/ssl/private/grafana.key;

    location / {
        proxy_pass         http://127.0.0.1:3000;
        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;
    }

    # WAJIB: Grafana Live memakai WebSocket
    location /api/live/ {
        proxy_pass          http://127.0.0.1:3000;
        proxy_http_version  1.1;
        proxy_set_header    Upgrade    $http_upgrade;
        proxy_set_header    Connection "upgrade";
        proxy_set_header    Host       $host;
    }
}
💡 Melayani dari sub-path

Bila Grafana harus berada di https://portal.id/grafana/, Anda perlu dua setelan sekaligus:

ini
root_url = https://portal.id/grafana/
serve_from_sub_path = true

Melewatkan salah satunya menghasilkan halaman putih karena aset statis dicari di path yang salah.

Compose Produksi Minimal

docker-compose.ymlyaml
services:
  grafana:
    image: grafana/grafana:12.0.0
    restart: unless-stopped
    user: "472"                     # UID resmi grafana
    ports: ["127.0.0.1:3000:3000"]  # hanya lokal, publik lewat nginx
    environment:
      GF_SERVER_ROOT_URL: https://grafana.perusahaan.id/
      GF_DATABASE_TYPE: postgres
      GF_DATABASE_HOST: db:5432
      GF_DATABASE_NAME: grafana
      GF_DATABASE_USER: grafana
      GF_DATABASE_PASSWORD__FILE: /run/secrets/db_pass
      GF_SECURITY_ADMIN_PASSWORD__FILE: /run/secrets/admin_pass
      GF_USERS_ALLOW_SIGN_UP: "false"
      GF_ANALYTICS_REPORTING_ENABLED: "false"
      GF_INSTALL_PLUGINS: "grafana-clock-panel,grafana-piechart-panel"
    volumes:
      - grafana-data:/var/lib/grafana
      - ./provisioning:/etc/grafana/provisioning:ro
    secrets: [db_pass, admin_pass]
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:3000/api/health || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 3

secrets:
  db_pass:    { file: ./secrets/db_pass.txt }
  admin_pass: { file: ./secrets/admin_pass.txt }

volumes:
  grafana-data:

Perhatikan akhiran __FILE pada env var — ini cara Grafana membaca Docker secret tanpa menaruh rahasia di docker inspect.