Configure the Grafana Server with grafana.ini and Environment Variables
Know where config files live, how overrides are ordered, and how to keep settings in Git.
Grafana’s server behavior is controlled by an INI file and by environment variables that override it. Knowing the rules lets you keep the whole configuration in a repository and change nothing by hand. This guide covers where the files live, how precedence works, how to inject values and secrets, and the settings you will touch most.
Where the configuration lives
defaults.iniships with Grafana and holds every default (inconf/for a tarball install). Never edit it. It’s the best reference for what options exist.grafana.iniis your configuration file. On Linux packages it is/etc/grafana/grafana.ini, and the official Docker image reads the same path. For a tarball install, useconf/custom.ini. Pass--configto point at another file.- Environment variables starting with
GF_override both.
Precedence, lowest to highest: defaults.ini, then your grafana.ini, then GF_* environment variables (and command line flags). Only put the options you want to change in your file, which keeps diffs small.
In an INI file, lines starting with ; are comments, so to enable an option you remove the leading ;:
;http_port = 3000 # ignored
http_port = 3000 # active
Restart Grafana after changing the file or the environment.
Environment variable overrides
The pattern is GF_<SECTION>_<KEY>, with the section and key in uppercase and any . or - replaced by _:
GF_SECURITY_ADMIN_USER=owner # [security] admin_user
GF_SERVER_ROOT_URL=https://grafana.example.com # [server] root_url
GF_AUTH_GOOGLE_CLIENT_SECRET=newS3cretKey # [auth.google] client_secret
GF_FEATURE_TOGGLES_newNavigation=true # [feature_toggles] newNavigation
GF_DEFAULT_INSTANCE_NAME=my-instance # top-level instance_name, no section
Environment variables are the natural fit for containers and Kubernetes, because the same file can be shared by every environment while the environment-specific values (URLs, passwords) come from the platform.
Variable expansion inside the file
Option values may reference environment variables or files with the $__env{} and $__file{} providers, or the ${NAME} shorthand:
[paths]
logs = $__env{LOGDIR}/grafana
[security]
admin_password = ${GF_ADMIN_PASSWORD}
secret_key = $__file{/run/secrets/grafana_secret_key}
[database]
password = $__file{/etc/secrets/gf_sql_password}
$__file{} reads the file and trims leading and trailing whitespace, which makes it a good match for Docker and Kubernetes secrets mounted as files. Grafana Enterprise also has a $__vault{} provider. The official Docker image additionally accepts a __FILE suffix on variable names (for example GF_SECURITY_ADMIN_PASSWORD__FILE=/run/secrets/admin_password), which is covered in the secrets guide.
A practical baseline
A short grafana.ini for a small production-like setup:
[paths]
provisioning = /etc/grafana/provisioning
[server]
protocol = http
http_port = 3000
domain = grafana.example.com
root_url = https://grafana.example.com/
; add the sub path to root_url and enable this when served from /grafana
; serve_from_sub_path = true
[database]
type = postgres
host = postgres:5432
name = grafana
user = grafana
password = $__file{/run/secrets/grafana_db_password}
[security]
admin_user = admin
admin_password = $__file{/run/secrets/grafana_admin_password}
secret_key = $__file{/run/secrets/grafana_secret_key}
cookie_secure = true
[users]
allow_sign_up = false
[analytics]
reporting_enabled = false
check_for_updates = false
[log]
mode = console
level = info
Points worth knowing:
- Database. The default is SQLite, which is fine for a single instance and testing. Use PostgreSQL or MySQL for production, and always for more than one Grafana replica.
root_urlmust match the public address, or links in alert notifications and OAuth redirects will be wrong. Behind a reverse proxy that serves Grafana under a sub-path, add the path toroot_urland setserve_from_sub_path = true.admin_passwordis only applied the first time Grafana creates its database. Changing the setting afterward doesn’t change the password of the existing admin user.secret_keyencrypts the secrets stored for data sources. If you change it, previously stored secrets can’t be read, and the data sources must be provisioned again. Set it explicitly and never rotate it casually.[paths] provisioningis where Grafana looks for provisioning folders. The default is/etc/grafana/provisioningon packages.
SMTP for email alerts
[smtp]
enabled = true
host = smtp.example.com:587
user = grafana@example.com
password = $__file{/run/secrets/smtp_password}
from_address = grafana@example.com
from_name = Grafana
startTLS_policy = OpportunisticStartTLS
Or the same with GF_SMTP_ENABLED=true, GF_SMTP_HOST=..., and so on. Verify option names against defaults.ini for your version.
Feature toggles
Experimental or opt-in features are switched on in a section of their own:
[feature_toggles]
; list the toggles you want, as documented for your version
newNavigation = true
Prefer the file or environment over the UI, so the setting survives a rebuild. Toggles come and go between releases, so review them at every upgrade.
Validate and inspect the effective configuration
After starting Grafana, you can compare what you set with what’s in effect:
curl -s -u admin:$GRAFANA_ADMIN_PASSWORD http://localhost:3000/api/admin/settings | jq '.server'
This admin endpoint returns the merged settings, and values for sensitive keys are masked. It’s the quickest way to confirm that an environment variable actually took effect. If it didn’t, check the spelling of the variable (uppercase, underscores) and that the option exists in defaults.ini.
Keep it in Git
- Commit
grafana.iniand a.env.examplewith placeholder values. - Keep real secrets out of the repository: mount them as files, inject them as environment variables, or commit them encrypted (see the secrets guide).
- Review
defaults.inichanges when you upgrade Grafana. New releases add options and sometimes deprecate old ones.
Popular Guides
-
Operate Grafana as Code: The Big Picture What can live in files, what needs an API, and how the pieces fit together. -
Provision Dashboards from JSON Files Load dashboards from disk, map folders from directories, and author them without losing changes. -
Provision Alert Rules, Contact Points, and Notification Policies Define the whole alerting pipeline in YAML so it is reviewed and versioned like code. -
Deploy Grafana on Kubernetes with Helm and Provisioning Values Run Grafana from a Helm chart where data sources, dashboards, and settings all come from values files. -
Reload, Verify, and Troubleshoot Provisioning from the Command Line Find out what Grafana loaded, reload without a restart, and fix the usual provisioning errors.