如果你第一次接触 Grafana想改个端口、换掉默认数据库或者调整权限策略大概率会和我当初一样直接跑到安装目录里找到 defaults.ini改完重启然后发现配置纹丝不动甚至服务直接起不来。这不是手误而是 Grafana 的配置体系跟普通软件不太一样它把默认配置和用户自定义配置分成了两层外层还可以用环境变量和命令行参数继续覆盖。这篇文章就把 Grafana 的配置文件从头到尾捋一遍包括 defaults.ini、custom.ini、环境变量的分工常用配置段的作用以及 provisioning 自动配置目录的用法。适合刚搭好 Grafana、想按自己需求调整面板的开发者参考读完你至少不会再改错文件、也不会因为一个 secret_key 丢了导致数据源全部失效。1. 先说清楚配置文件的边界defaults.ini、custom.ini 与环境变量1.1 defaults.ini 是出厂默认配置不是给你直接改的Grafana 安装好之后安装目录下会有一个 defaults.ini里面几乎涵盖了所有配置项的默认值。注意这个文件的作用是“给程序提供一个找不到任何自定义配置时也能启动的兜底”而不是让你直接修改的入口。为什么不建议直接改它两个原因。第一Grafana 升级时安装包会整体替换或更新 defaults.ini你写在里面的自定义项会随着升级直接丢失甚至因为新旧格式不兼容导致配置解析异常。第二defaults.ini 的变更会影响你整个环境里所有实例的基线行为排查问题时很难分清到底是你改的还是默认文件被带偏了。你正确的方式是新建一个 custom.ini然后在里面只写需要覆盖的配置项。很多新手问“我没找到 custom.ini 怎么办”很正常安装包里通常只有 defaults.inicustom.ini 需要你自己创建或者从安装文档提供的样例复制一份。Debian/Ubuntu 的安装包会生成/etc/grafana/grafana.ini这个文件本质上就是 custom.ini 的角色只是名字不叫 custom.ini 而已。1.2 custom.ini用户自定义配置的真正入口Grafana 的配置查找顺序是先读取程序内置的默认值然后读取 defaults.ini再去读取位于指定位置的 custom.ini最终以更靠后的配置为准。如果你没有显式指定 custom.ini 的路径Grafana 会按编译时的默认路径去找常见的包括Linux 二进制包/etc/grafana/custom.ini或/etc/grafana/grafana.iniDocker 镜像/etc/grafana/grafana.iniMac 开发环境/usr/local/etc/grafana/grafana.ini实际部署时很多团队习惯把 custom.ini 放到/etc/grafana/目录下再用启动参数--config/etc/grafana/custom.ini显式指定。这种做法有一个额外好处当你同时维护多套 Grafana 实例测试环境、预发环境、生产环境时可以用同一份安装包通过指向不同的配置文件来区分环境互不干扰。custom.ini 的格式是标准的 INI 格式用[section]分段每个段下面放key value。注释可以用;或者#开头。比如[server] ; 对外开放的端口 http_port 8080 [database] type postgres host 127.0.0.1:5432注意custom.ini 不需要把 defaults.ini 里的所有内容都复制过来只写你要覆盖的项即可没写到的全部走默认值。1.3 环境变量是第三层覆盖容器部署时最容易踩坑除了文件配置Grafana 还支持环境变量覆盖。规则很简单环境变量名按照GF_ 配置段名 配置项名的格式组合全部转大写中间用下划线分隔。例如GF_SERVER_HTTP_PORT对应[server] http_portGF_DATABASE_TYPE对应[database] typeGF_SECURITY_ADMIN_PASSWORD对应[security] admin_passwordGF_AUTH_ANONYMOUS_ENABLED对应[auth.anonymous] enabled完整优先级从低到高是程序内置默认值 defaults.ini custom.ini 环境变量 命令行参数。也就是说如果你在 custom.ini 里把端口改成了 8080但环境中还设了GF_SERVER_HTTP_PORT9090最终生效的会是 9090。这个机制在 Docker 和 Kubernetes 环境里非常常见但也非常容易出问题。最典型的坑是自定义配置写在 YAML 或编排文件的环境变量里看起来和 custom.ini 是两套完全不同的值对不上号。我还遇到过有人把GF_SERVER_HTTP_PORT拼成了GF_SERVER_PORT程序没有任何报错只是静默忽略了结果排查了半天才发现环境变量名字根本没对上。所以建议养成一个习惯凡是容器部署优先看环境变量凡是传统二进制包部署优先看 custom.ini。两边都有配置时以环境变量为准不要再纠结文件里写了什么。2. 逐段拆解最常改的后端配置2.1 server 段端口、域名和对外访问地址server 段是所有配置里改动频率最高的地方。最关键的几个参数参数默认值说明http_port3000Grafana 的 HTTP 监听端口domainlocalhost对外访问域名用于生成票据、回调地址root_url%(protocol)s://%(domain)s:%(http_port)s/完整对外访问地址enforce_domain_redirectfalse访问 IP 时是否强制跳转到 domainstatic_root_pathpublic静态资源目录root_url值得单独说。它不只是给浏览器跳转用的Grafana 内部生成告警图片链接、嵌入面板地址、邮件通知链接时都会基于它。如果你把 Grafana 放在 Nginx 后面用/grafana/这样的子路径对外提供服务而不是独立的子域名那 root_url 必须改成https://你的域名/grafana/否则告警邮件里的链接点进去全是 404。实际配置示例[server] http_port 8080 domain grafana.example.com root_url https://grafana.example.com注意改了 http_port 不代表原来的 3000 端口就自动失效如果你忘了把别的服务的反向代理规则一起改老的端口可能仍然在监听只是没有日志排查时很误导人。2.2 database 段默认 SQLite 和外部数据库怎么选Grafana 默认使用内嵌 SQLite 存储用户、面板、数据源元数据。这个设计对个人使用和小团队非常友好装完就能跑不用额外装数据库。但生产环境下我一般不建议长期用 SQLite原因有三个并发写入能力有限多人同时保存面板时容易碰到数据库锁。备份策略不灵活直接拷贝文件虽然可行但要非常小心写权限和 WAL 文件。Grafana 后期如果开了某些高流量功能SQLite 会成为瓶颈。system 我的建议是监控规模超过几十台机器或者团队超过几个人同时用 Grafana就直接上 PostgreSQL。配置方式[database] type postgres host 127.0.0.1:5432 name grafana user grafana password 你的密码 ssl_mode requireMySQL 也可以用type 改成 mysql 即可。这里要注意一个转换成本问题从 SQLite 迁到 PostgreSQL不是说改完配置重启就完事你需要把旧数据迁移过去。官方提供了相关工具但仍然建议在迁移前先完整备份尤其是面板 JSON 和用户权限记录。我见过有人直接删掉 grafana.db重启后发现所有面板和用户全没了才想起来没导出那是很痛的教训。2.3 security 段管理员密码、secret_key 和各种安全开关security 段大概是用户最关心、也最容易一知半解的一段。先说 admin 账号[security] admin_user admin admin_password 首次登录密码这两个配置只在 Grafana 启动时读取用于初始化内置管理员账号。重点来了如果 Grafana 数据库里已经存在 admin 用户你在 custom.ini 里改 admin_password 是不会生效的因为数据库里的记录优先级更高。也就是说线上修改管理员密码正确的做法是登录后在 UI 里改而不是改配置文件再重启。再说 secret_key。这个东西非常非常重要它用于加密数据源密码、告警通知、面板快照图片等敏感信息。默认值写在 defaults.ini 里生产环境一定要换成自己的随机字符串。为什么强调这个我见过一个真实案例某开发者在迁移 Grafana 时只拷贝了数据库文件到新机器启动后用户能正常登录但所有第三方数据源全部报错提示密码解密失败。原因就是新机器上没有把旧环境的 secret_key 一起带过去Grafana 用新密钥去解密旧的加密数据自然全部失败。最后只能逐个数据源重新输入密码。如果你的数据源很多这个工作量会让你怀疑人生。配置方式[security] secret_key 一串足够复杂的随机字符串2.4 auth 段匿名访问、登录表单和其他认证方式认证相关配置在 auth 开头或者 auth 单独段。要搞懂 Grafana 认证你需要知道登录本身和认证方式是两件事。如果你只想做一个对内展示的监控大屏不想每个人都要登录才能看到面板可以开启匿名访问[auth.anonymous] enabled true org_name Main Org. org_role Viewer开启后未登录用户会以 Viewer 身份访问只能看不能改。如果你连登录表单都不想显示可以再加[auth.basic] disable_login_form true注意disable_login_form true只是把登录界面表单隐藏并不是取消认证。你仍然可以通过 API 或外部认证登录。如果设置了之后发现“既能匿名访问又能登录”不用慌这是符合预期的行为。如果你在 UI 上明明看到匿名访问已经开启但实际访问还是要登录最可能是配置被环境变量覆盖了。检查一下有没有GF_AUTH_ANONYMOUS_ENABLEDfalse之类的设置因为这个变量的优先级高于 custom.ini。每次改认证配置我都会先看一圈环境变量再下结论免得白折腾。2.5 session、日志和数据保留的隐藏配置除了上面这些还有两个容易被忽略的配置段。第一个是[sessions]默认 session 存在内存里重启后所有登录态失效用户会被强制踢下线。如果你不想频繁重启导致全员重新登录可以改成存数据库[sessions] provider database第二个是[log]段。默认日志级别是 Info排错时经常觉得日志不够细可以先临时调到 Debug复现问题后再改回来[log] level DebugDebug 日志的信息量很大包含每个请求的耗时和配置加载细节新手排查配置问题很实用但不建议生产长期开着日志量会让磁盘吃不消。3. provisioning 目录让数据源和面板配置随代码走3.1 为什么推荐用 provisioning 而不是 UI 手动配置很多人装完 Grafana习惯在界面上点“Add data source”加数据源往里填 URL、账号密码然后手动 Import 一个面板 JSON 文件。这种方式对单机使用没问题但它有一个致命缺点不可审计、不可回滚、不可版本化。什么时候会难受当你维护的不止一套 Grafana测试环境一套、生产环境一套每次改一个数据源都要在两个界面上重复操作改完了也不知道谁改的、什么时候改的。如果你用 Docker 或 Kubernetes 部署那更麻烦——容器一销毁重建所有手动配置全部丢失除非你卷外挂的整个数据目录都在。Grafana 提供了一条更干净的路provisioning。它在配置目录下启动时自动加载 YAML 文件帮你创建数据源、面板、告警规则甚至可以定义通知渠道。好处是文件可以直接放进 Git和环境一起部署可重复执行。3.2 数据源自动配置一个 datasources.yaml 就够Grafana 默认会读取/etc/grafana/provisioning/datasources/下的 YAML 文件。一个最基本的 Prometheus 数据源配置长这样apiVersion: 1 datasources: - name: Prometheus type: prometheus access: proxy url: http://prometheus:9090 isDefault: true editable: false里面access: proxy表示浏览器请求先到 Grafana由 Grafana 转发到 Prometheus这样可以避免跨域问题和数据源地址暴露。如果access: direct浏览器会直接访问数据源一般用于网络能直连的场景。还要注意editable: false。这个字段的意思是在 UI 里这个数据源不能编辑和删除。新手会觉得“那我以后想改怎么办”你的改法就是改 YAML 文件再 reload而不是在页面上改。这其实是一种保护防止有人手滑把生产数据源改坏。多个数据源就并列写多个datasources: - name: Prometheus-Prod type: prometheus url: http://prometheus-prod:9090 - name: MySQL type: mysql url: 127.0.0.1:3306 database: myapp user: grafana secureJsonData: password: 你的密码secureJsonData是专门用来放密码的地方Grafana 会把它加密存储不会明文暴露在 UI 配置接口里。这是我强烈推荐的结构。3.3 面板自动配置dashboards.yaml 与目录结构面板自动配置比数据源稍复杂一点核心是定义一个 provider。官方推荐在/etc/grafana/provisioning/dashboards/下放一个 YAMLapiVersion: 1 providers: - name: default orgId: 1 folder: type: file disableDeletion: false updateIntervalSeconds: 30 allowUiUpdates: false options: path: /etc/grafana/provisioning/dashboards foldersFromFilesStructure: true这段配置的意思很简单把/etc/grafana/provisioning/dashboards目录下的 JSON 面板文件全部加载进来每隔 30 秒扫描一次。面板文件需要在 Grafana 上手动导出 JSON或者从社区下载然后放进这个目录。有几个细节要提醒allowUiUpdates: false表示面板改动只能通过改 JSON 文件来更新UI 上做的修改保存后会提示“源由 provisioning 托管”不会真正写入数据库。如果你希望后续还能在 UI 上临时微调就把这个值改成 true。updateIntervalSeconds不设也可以默认扫描间隔比较长。改成 30 秒便于快速验证生产环境可以调大。如果两个 provider 指向同一个 folder 或同样的面板文件会出现“面板配置来源冲突”的警告启动日志里会明确写出来。3.4 改了 provisioning 文件后怎么让配置生效文件改完不会自动立刻加载数据源和面板配置都有各自的重载机制。最省事的方法是重启 Grafana 服务。不想重启的话可以用官方提供的管理 APIcurl -X POST http://localhost:3000/api/admin/provisioning/datasources/reload curl -X POST http://localhost:3000/api/admin/provisioning/dashboards/reload注意这两个接口都需要管理员权限HTTP 请求要带登录 cookie 或 Bearer Token。如果只是修改面板目录下的 JSON 文件不一定需要 reload因为 provider 的更新间隔会自动扫描。数据源文件改动就必须 reload 或重启。我个人的实践是把 provisioning 目录挂进容器后平时只改 YAML 和 JSON全部靠 API reload 生效几乎不用重启 Grafana。这样既快又不中断告警。4. 改完配置如何确认它真的生效了4.1 用设置页核对实际激活值而不是凭印象这是排查配置问题最高效的一招登录 Grafana 后在左侧菜单进入“Server Admin”下的“Settings”页面上会列出当前进程实际生效的所有配置项包括哪些值来自配置文件、哪些来自环境变量、哪些是内置默认值。比对着 custom.ini 猜要靠谱得多。比如你怀疑端口没生效去设置页搜索http_port看到的值才是程序真正在用的值。如果你在 custom.ini 里明明写了 8080设置页却显示 3000说明配置文件压根没被读取或者启动命令指定了别的文件。设置页还有一个价值是排查环境变量覆盖。页面上某个配置的值和你预期不一致时你看它的来源提示基本就能判断是哪一层把它改了。4.2 从启动日志和进程参数反向确认设置页需要能登录才能看。如果服务都起不来或者你想在启动阶段就确认配置文件路径有两条路第一看启动日志。Grafana 启动时会在日志里输出配置相关信息和路径比如loggerconfig msgLoaded configuration from /etc/grafana/custom.ini如果你设置了多个配置来源它也会在日志里列出最终合并结果。第二看进程启动参数。Linux 环境下执行ps aux | grep grafana有--config参数就直接告诉你用的是哪个配置文件。如果你用的是 systemd可以通过systemctl cat grafana-server查看到启动命令。有些系统默认就带了--config参数你只看/etc/grafana/grafana.ini可能看得不是同一个文件这就是很多人“改了不生效”的终极原因。4.3 一个典型的“改了没生效”场景我之前在一个模拟项目 X 的部署现场排查过一个问题运维在 custom.ini 里开启了匿名访问重启后访问 Grafana 仍然要求登录。排查链路是这样的先看设置页发现auth.anonymous段下enabled的值仍然为 false。再看 custom.ini文件里确实写着enabled true。查看进程启动参数发现 systemd 服务启动命令里带了--config指向另一个路径下的 grafana.ini。打开那个文件发现里面根本没有[auth.anonymous]段只有旧的 server 配置。问题到这里就清楚了系统执行的是两个配置文件默认的/etc/grafana/grafana.ini是空的而他们改的是另一个/opt/grafana/custom.ini服务根本没读取这个文件。把设置合并到正确路径并重启后问题解决。这个案例很基础但特别有代表性。遇到“改了不生效”第一反应不要是“Grafana 是不是有问题”而是先回答三个问题改的是哪个文件服务读的是哪个文件当前生效的值是什么这三个问题能节省大量时间。5. 场景化配置清单开发测试和生产环境该各改什么5.1 开发测试环境怎么配置最省心开发测试环境下配置目标就是“少打扰、快速验证、不怕折腾”。我一般建议开匿名访问、隐藏登录表单、允许嵌入、日志开到 Debug这样拉个临时面板就能直接丢到 iframe 里给同事看不用反复登录。[server] http_port 3000 root_url http://localhost:3000 [auth.anonymous] enabled true org_role Viewer [auth.basic] disable_login_form true [security] allow_embedding true [log] level Debug数据库默认用 SQLite 就行不折腾。如果你用 Docker 跑测试环境记得把/var/lib/grafana和/etc/grafana/provisioning用卷挂出来否则每次重建容器配置全没了。我见过同事因为忘了挂载数据目录三天内重复配置了三次数据源后来一眼看出就是卷少了。5.2 生产环境哪些项必须优先调整生产环境跟开发测试的取舍完全不同重点是稳定、安全、可审计。我整理了一个自己每次上线都会过一遍的检查项配置项生产建议原因database.typePostgreSQL 或 MySQL避免 SQLite 并发瓶颈security.secret_key更改为独立随机字符串避免加密数据不可恢复security.admin_password首次登录后强制改掉默认密码是攻击入口server.domain / root_url与反向代理域名一致保证告警链接和嵌入正常auth.anonymous默认关闭避免监控数据对外泄露log.levelInfo 或 Warn减少日志量sessions.providerdatabase重启不踢用户provisioning 目录开启并纳入 Git可复现、可审计还有一个容易被忽视的项如果你通过 Nginx 或负载均衡提供 HTTPSGrafana 自己没开 TLS但也需要把相关请求协议标识配置好否则 Grafana 生成的回调链接可能是http导致登录跳转出问题。在 Nginx 中设置X-Forwarded-Proto后Grafana 侧会相应处理。[server] root_url https://grafana.example.com router_logging truesmtp段我也建议在生产环境尽早配置否则面板告警发出去了通知邮件却发不出来[smtp] enabled true host smtp.example.com:587 user grafanaexample.com password 发件密码 from_address grafanaexample.com配置完别忘了测试一下在 Grafana 的 Notification channels 里选一个测试邮件接收人发一条 Test 通知能收到再继续。5.3 升级和回滚配置文件的“后悔药”怎么留最后聊一下运维里最容易出事的环节版本升级。Grafana 每次升级都会更新自带的 defaults.ini新增配置项、修改参数名是常有的事。如果你的 custom.ini 还写着老版本的配置项Grafana 不会报错它会静默忽略不认识的键值结果就是某个功能行为悄悄变了但你不一定能立刻发现。所以升级前我必有三个动作备份整个配置目录通常是/etc/grafana你可以用tar -czvf grafana-backup.tar.gz /etc/grafana。如果用的是 SQLite备份对应的数据文件并确保 Grafana 已经停止否则拷出来的数据库可能处于不一致状态。在设置页把关键配置截图或导出作为升级前后对比的基线。万一升级后发现某个配置项不再生效回滚的方法也很直接停止服务恢复之前的配置目录换回旧版本二进制再启动。不过要注意Grafana 的数据库版本也在升级如果数据文件已经被新版本改过了直接用旧版本去读有可能报版本不兼容。所以数据库类的回滚最好在升级前完成或者用导出面板 JSON 的方式恢复而不是指望数据库能无损退版。我自己做这类操作时还会把面板 JSON 全部导出一份放到备份 tar 包里。因为面板是最难重建的资产丢了比配置丢了更心疼。配置文件错了可以改回来面板没了真要重新画半天。这个内容后续还有一个很自然的扩展方向当你的 Grafana 实例变多之后配置文件本身会发展成“模板 变量替换”的管理方式provisioning 配合版本管理工具就会变成基础设施的一部分。不过那是另一个话题了先把这份配置文件手册吃透至少你已经不会再在 defaults.ini 和 custom.ini 之间反复横跳了。