服务器Loki教程:用Docker和Nginx搭建日志收集系统
Loki 是 Grafana 团队推出的日志聚合系统,和 Prometheus 的标签模型类似,但专门用来存日志。
相比 ELK,Loki 占用资源少、部署简单,适合个人服务器或中小团队。
这篇服务器 Loki 教程会带你用 Docker Compose 在一台 Linux 服务器上跑通 Loki 加 Grafana,再通过 Nginx 暴露访问入口,最后验证日志能不能正常写入和查询。
先确认环境和端口占用
需要一台能联网的 Linux 服务器,推荐 2 核 4G 起步,系统用 Ubuntu 22.04 或 CentOS 7 以上都行。
开始前先装好 Docker 和 Docker Compose,如果不是新机器,用下面命令确认版本。
docker --version
docker compose version
如果第二条命令报错,说明你装的是旧版 docker-compose,把后续命令里的 docker compose 换成 docker-compose 即可。
Loki 默认监听 3100 端口,Grafana 默认 3000。
先用 ss -tlnp | grep -E '3100|3000' 检查端口有没有被占用,被占用就换端口,或者停掉冲突服务。
用 Docker Compose 启动 Loki 和 Grafana
新建目录并写入配置文件。
Loki 需要一个最小配置来指定存储路径和监听地址。
mkdir -p /opt/loki && cd /opt/loki
创建 loki-config.yaml,内容如下:
auth_enabled: false
server:
http_listen_port: 3100
common:
path_prefix: /loki
storage:
filesystem:
chunks_directory: /loki/chunks
rules_directory: /loki/rules
replication_factor: 1
ring:
kvstore:
store: inmemory
schema_config:
configs:
- from: 2024-01-01
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h
limits_config:
allow_structured_metadata: false
这里的 from: 是 schema 生效日期,
2024-01-01
写一个已经过去的日期即可。allow_structured_metadata: 是为了兼容旧版查询方式,
false
如果你用的是较新的 Loki 版本,
可以保留这个设置避免启动报错。
接着创建 docker-compose.yml:
services:
loki:
image: grafana/loki:2.9.0
container_name: loki
restart: unless-stopped
ports:
- "3100:3100"
volumes:
- ./loki-config.yaml:/etc/loki/local-config.yaml
- ./loki-data:/loki
command: -config.file=/etc/loki/local-config.yaml
grafana:
image: grafana/grafana:10.2.0
container_name: grafana
restart: unless-stopped
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin123
volumes:
- ./grafana-data:/var/lib/grafana
启动服务:
docker compose up -d
用 docker compose ps 看两个容器是否都是 running 状态。
如果 Loki 反复重启,用 docker logs loki 看报错,常见原因是配置文件缩进错误或 schema 日期格式不对。
通过 Nginx 暴露访问入口
如果服务器有公网 IP,直接开 3000 端口不安全。
建议用 Nginx 反向代理,并加上基础认证。
假设你已经装好 Nginx,在 /etc/nginx/conf.d/loki.conf 写入:
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /loki/ {
proxy_pass http://127.0.0.1:3100/;
proxy_set_header Host $host;
}
}
your-domain.com 换成你自己的域名或服务器 IP。
改完后执行 nginx -t 检查语法,再 nginx -s reload 重载。
注意:Loki 的推送接口默认不加认证,生产环境建议在 Nginx 层加 auth_basic 或限制来源 IP。
在 Grafana 里添加 Loki 数据源
浏览器打开 http://your-domain.com,用 admin / admin123 登录。
进入左侧菜单的 Connections,选择 Data sources,点 Add data source,搜索 Loki。
URL 填 http://loki:3100。
因为 Grafana 和 Loki 在同一个 Docker 网络里,用服务名 loki 就能互通,不需要走公网。
保存后点 Save & test,出现绿色提示说明连接成功。
下一步可以测试推送一条日志。
在服务器上执行:
curl -X POST http://127.0.0.1:3100/loki/api/v1/push \
-H "Content-Type: application/json" \
-d '{"streams":[{"stream":{"job":"test"},"values":[["'$(date +%s)'000000000","hello loki"]]}]}'
回到 Grafana 的 Explore 页面,
数据源选 Loki,
查询框输入 {job="test"},
点 Run query,
能看到 hello loki 这条日志就算成功了。
常见报错和避坑说明
Loki 启动后立刻退出:多半是 YAML 缩进问题。
YAML 对空格敏感,不要用 Tab。
可以用 docker run --rm -v $(pwd)/loki-config.yaml:/etc/loki/local-config.yaml grafana/loki:2.9.0 -config.file=/etc/loki/local-config.yaml -verify-config 单独验证配置。
Grafana 提示 “Unable to connect with Loki”:先确认数据源 URL 写的是 http://loki:3100 而不是 http://localhost:3100。
容器内的 localhost 指向容器自己,不是宿主机。
如果不在同一 Docker 网络,需要把两个服务放到同一个 networks 下。
推送日志返回 404:检查 Loki 版本和接口路径是否匹配。
旧版本可能使用 /api/prom/push,本文示例基于 Loki 2.x 的 /loki/api/v1/push。
磁盘被日志写满:Loki 默认不会自动删除旧数据。
可以在 limits_config 里加 retention_period: 720h,再配合 compactor 配置启用清理。
具体字段随版本有差异,调整前先备份配置。
验证整套链路是否正常
完整验证分三步:第一,curl http://127.0.0.1:3100/ready 返回 ready;
第二,Grafana 数据源测试通过;
第三,Explore 里能查到 {job="test"} 的日志。
三步都通过,说明从采集到查询的链路已经通了。
如果后续要接入真实日志,可以在每台服务器上装 Promtail,把系统日志或应用日志目录配置进去,指向 Loki 的推送地址。
配置方式和本文的 Loki 配置一样,改完先 -verify-config 再重启。
这套方案适合单机或小规模场景。
日志量上到每天几十 GB 后,需要考虑对象存储后端和独立部署 compactor。
先把当前版本跑通,再根据实际数据量做扩容,比一开始就堆复杂架构更容易排查问题。